diff options
author | Bertrand Marc <beberking@gmail.com> | 2012-06-06 20:47:48 +0200 |
---|---|---|
committer | Bertrand Marc <beberking@gmail.com> | 2012-06-06 20:47:48 +0200 |
commit | 740b30688bd745a527f96f9116c19acb3480971a (patch) | |
tree | 2709a3f4dba11c174aa9e1ba3612e30c578e76a9 /src/ats | |
parent | 2b81464a43485fcc8ce079fafdee7b7a171835f4 (diff) |
Imported Upstream version 0.9.3upstream/0.9.3
Diffstat (limited to 'src/ats')
-rw-r--r-- | src/ats/Makefile.am | 13 | ||||
-rw-r--r-- | src/ats/Makefile.in | 35 | ||||
-rw-r--r-- | src/ats/ats.conf.in | 18 | ||||
-rw-r--r-- | src/ats/ats.h | 9 | ||||
-rw-r--r-- | src/ats/ats_api_performance.c | 4 | ||||
-rw-r--r-- | src/ats/ats_api_scheduling.c | 112 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats.c | 9 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_addresses.c | 282 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_addresses.h | 15 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_addresses_mlp.c | 225 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_addresses_mlp.h | 16 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_performance.c | 2 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_scheduling.c | 51 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_scheduling.h | 13 | ||||
-rw-r--r-- | src/ats/perf_ats_mlp.c | 372 | ||||
-rw-r--r-- | src/ats/test_ats_api.conf | 30 | ||||
-rw-r--r-- | src/ats/test_ats_api_reset_backoff.c | 308 | ||||
-rw-r--r-- | src/ats/test_ats_api_scheduling.c | 13 | ||||
-rw-r--r-- | src/ats/test_ats_mlp.c | 14 | ||||
-rw-r--r-- | src/ats/test_ats_mlp_averaging.c | 14 |
20 files changed, 1236 insertions, 319 deletions
diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am index f4056fa..2e85848 100644 --- a/src/ats/Makefile.am +++ b/src/ats/Makefile.am @@ -32,7 +32,7 @@ libgnunetats_la_LIBADD = \ libgnunetats_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ - -version-info 1:0:1 + -version-info 2:0:2 bin_PROGRAMS = \ @@ -54,6 +54,7 @@ gnunet_service_ats_LDADD = \ check_PROGRAMS = \ test_ats_api_scheduling \ + test_ats_api_reset_backoff \ $(GN_MLP_TEST) \ $(GN_MLP_TEST_AVG) \ $(GN_MLP_PERF) @@ -87,7 +88,7 @@ perf_ats_mlp_SOURCES = \ perf_ats_mlp_LDADD = \ $(GN_LIBGLPK) \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/statistics/libgnunetstatistics.la + $(top_builddir)/src/statistics/libgnunetstatistics.la endif test_ats_api_scheduling_SOURCES = \ @@ -96,6 +97,12 @@ test_ats_api_scheduling_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/ats/libgnunetats.la +test_ats_api_reset_backoff_SOURCES = \ + test_ats_api_reset_backoff.c +test_ats_api_reset_backoff_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 #test_ats_api_scheduling_get_type_LDADD = \ @@ -117,5 +124,5 @@ test_ats_api_scheduling_LDADD = \ EXTRA_DIST = \ ats.h \ - test_ats_api.conf + test_ats_api.conf diff --git a/src/ats/Makefile.in b/src/ats/Makefile.in index 26610e1..7f74064 100644 --- a/src/ats/Makefile.in +++ b/src/ats/Makefile.in @@ -38,7 +38,8 @@ build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ bin_PROGRAMS = gnunet-service-ats$(EXEEXT) -check_PROGRAMS = test_ats_api_scheduling$(EXEEXT) $(am__EXEEXT_1) \ +check_PROGRAMS = test_ats_api_scheduling$(EXEEXT) \ + test_ats_api_reset_backoff$(EXEEXT) $(am__EXEEXT_1) \ $(am__EXEEXT_2) $(am__EXEEXT_3) subdir = src/ats DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ @@ -134,6 +135,13 @@ perf_ats_mlp_OBJECTS = $(am_perf_ats_mlp_OBJECTS) @HAVE_LIBGLPK_TRUE@perf_ats_mlp_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/util/libgnunetutil.la \ @HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/statistics/libgnunetstatistics.la +am_test_ats_api_reset_backoff_OBJECTS = \ + test_ats_api_reset_backoff.$(OBJEXT) +test_ats_api_reset_backoff_OBJECTS = \ + $(am_test_ats_api_reset_backoff_OBJECTS) +test_ats_api_reset_backoff_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/ats/libgnunetats.la am_test_ats_api_scheduling_OBJECTS = \ test_ats_api_scheduling.$(OBJEXT) test_ats_api_scheduling_OBJECTS = \ @@ -187,11 +195,13 @@ AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libgnunetats_la_SOURCES) $(gnunet_service_ats_SOURCES) \ - $(perf_ats_mlp_SOURCES) $(test_ats_api_scheduling_SOURCES) \ - $(test_ats_mlp_SOURCES) $(test_ats_mlp_averaging_SOURCES) + $(perf_ats_mlp_SOURCES) $(test_ats_api_reset_backoff_SOURCES) \ + $(test_ats_api_scheduling_SOURCES) $(test_ats_mlp_SOURCES) \ + $(test_ats_mlp_averaging_SOURCES) DIST_SOURCES = $(libgnunetats_la_SOURCES) \ $(am__gnunet_service_ats_SOURCES_DIST) \ $(am__perf_ats_mlp_SOURCES_DIST) \ + $(test_ats_api_reset_backoff_SOURCES) \ $(test_ats_api_scheduling_SOURCES) \ $(am__test_ats_mlp_SOURCES_DIST) \ $(am__test_ats_mlp_averaging_SOURCES_DIST) @@ -256,6 +266,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVAPORT = @JAVAPORT@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ @@ -289,6 +300,7 @@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ @@ -427,7 +439,7 @@ libgnunetats_la_LIBADD = \ libgnunetats_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ - -version-info 1:0:1 + -version-info 2:0:2 gnunet_service_ats_SOURCES = \ gnunet-service-ats.c gnunet-service-ats.h\ @@ -471,7 +483,7 @@ gnunet_service_ats_LDADD = \ @HAVE_LIBGLPK_TRUE@perf_ats_mlp_LDADD = \ @HAVE_LIBGLPK_TRUE@ $(GN_LIBGLPK) \ @HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/util/libgnunetutil.la \ -@HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/statistics/libgnunetstatistics.la +@HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/statistics/libgnunetstatistics.la test_ats_api_scheduling_SOURCES = \ test_ats_api_scheduling.c @@ -480,6 +492,13 @@ test_ats_api_scheduling_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/ats/libgnunetats.la +test_ats_api_reset_backoff_SOURCES = \ + test_ats_api_reset_backoff.c + +test_ats_api_reset_backoff_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 @@ -500,7 +519,7 @@ test_ats_api_scheduling_LDADD = \ # $(top_builddir)/src/ats/libgnunetats.la EXTRA_DIST = \ ats.h \ - test_ats_api.conf + test_ats_api.conf all: all-am @@ -629,6 +648,9 @@ gnunet-service-ats$(EXEEXT): $(gnunet_service_ats_OBJECTS) $(gnunet_service_ats_ perf_ats_mlp$(EXEEXT): $(perf_ats_mlp_OBJECTS) $(perf_ats_mlp_DEPENDENCIES) @rm -f perf_ats_mlp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(perf_ats_mlp_OBJECTS) $(perf_ats_mlp_LDADD) $(LIBS) +test_ats_api_reset_backoff$(EXEEXT): $(test_ats_api_reset_backoff_OBJECTS) $(test_ats_api_reset_backoff_DEPENDENCIES) + @rm -f test_ats_api_reset_backoff$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_ats_api_reset_backoff_OBJECTS) $(test_ats_api_reset_backoff_LDADD) $(LIBS) test_ats_api_scheduling$(EXEEXT): $(test_ats_api_scheduling_OBJECTS) $(test_ats_api_scheduling_DEPENDENCIES) @rm -f test_ats_api_scheduling$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_ats_api_scheduling_OBJECTS) $(test_ats_api_scheduling_LDADD) $(LIBS) @@ -654,6 +676,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-ats_reservations.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-ats_scheduling.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/perf_ats_mlp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_reset_backoff.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_scheduling.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_mlp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_mlp_averaging.Po@am__quote@ diff --git a/src/ats/ats.conf.in b/src/ats/ats.conf.in index 6ea0d41..f81016e 100644 --- a/src/ats/ats.conf.in +++ b/src/ats/ats.conf.in @@ -10,10 +10,24 @@ ACCEPT_FROM6 = ::1; UNIXPATH = /tmp/gnunet-service-ats.sock UNIX_MATCH_UID = YES UNIX_MATCH_GID = YES + +# Enable MLP mode (default: NO) MLP = NO -WAN_QUOTA_IN = 65536 -WAN_QUOTA_OUT = 65536 +# Network specific inbound/outbound quotas +# LOOPBACK +LOOPBACK_QUOTA_IN = unlimited +LOOPBACK_QUOTA_OUT = unlimited +# LAN +LAN_QUOTA_IN = unlimited +LAN_QUOTA_OUT = unlimited +# WAN +WAN_QUOTA_IN = 64 KiB +WAN_QUOTA_OUT = 64 KiB +# WLAN +WLAN_QUOTA_IN = 1 MiB +WLAN_QUOTA_OUT = 1 MiB # ATS options + DUMP_MLP = NO DUMP_SOLUTION = NO DUMP_OVERWRITE = NO diff --git a/src/ats/ats.h b/src/ats/ats.h index 30ca295..f4c3d9f 100644 --- a/src/ats/ats.h +++ b/src/ats/ats.h @@ -61,6 +61,15 @@ struct RequestAddressMessage struct GNUNET_PeerIdentity peer; }; +struct ResetBackoffMessage +{ + struct GNUNET_MessageHeader header; + + uint32_t reserved GNUNET_PACKED; + + struct GNUNET_PeerIdentity peer; +}; + struct AddressUpdateMessage { diff --git a/src/ats/ats_api_performance.c b/src/ats/ats_api_performance.c index 848c7ec..c98e1c2 100644 --- a/src/ats/ats_api_performance.c +++ b/src/ats/ats_api_performance.c @@ -395,7 +395,7 @@ process_ats_message (void *cls, const struct GNUNET_MessageHeader *msg) GNUNET_TIME_UNIT_FOREVER_REL); return; reconnect: - GNUNET_CLIENT_disconnect (ph->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (ph->client); ph->client = NULL; ph->task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &reconnect_task, @@ -493,7 +493,7 @@ GNUNET_ATS_performance_done (struct GNUNET_ATS_PerformanceHandle *ph) } if (NULL != ph->client) { - GNUNET_CLIENT_disconnect (ph->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (ph->client); ph->client = NULL; } GNUNET_free (ph); diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c index 78e8d61..5a4e883 100644 --- a/src/ats/ats_api_scheduling.c +++ b/src/ats/ats_api_scheduling.c @@ -27,7 +27,6 @@ #include "gnunet_ats_service.h" #include "ats.h" -#define DEBUG_ATS GNUNET_EXTRA_LOGGING #define INTERFACE_PROCESSING_INTERVALL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) @@ -146,7 +145,6 @@ struct GNUNET_ATS_SchedulingHandle */ struct ATS_Network * net_tail; - /** * Array of session objects (we need to translate them to numbers and back * for the protocol; the offset in the array is the session number on the @@ -163,7 +161,6 @@ struct GNUNET_ATS_SchedulingHandle /** * Task retrieving interfaces from the system */ - GNUNET_SCHEDULER_TaskIdentifier interface_task; @@ -213,7 +210,7 @@ static void force_reconnect (struct GNUNET_ATS_SchedulingHandle *sh) { sh->reconnect = GNUNET_NO; - GNUNET_CLIENT_disconnect (sh->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (sh->client); sh->client = NULL; sh->task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &reconnect_task, @@ -319,10 +316,11 @@ static struct Session * find_session (struct GNUNET_ATS_SchedulingHandle *sh, uint32_t session_id, const struct GNUNET_PeerIdentity *peer) { -#if DEBUG_ATS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Find session %u from peer %s in %p\n", + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", + "Find session %u from peer %s in %p\n", (unsigned int) session_id, GNUNET_i2s (peer), sh); -#endif + if (session_id >= sh->session_array_size) { GNUNET_break (0); @@ -366,11 +364,11 @@ get_session_id (struct GNUNET_ATS_SchedulingHandle *sh, struct Session *session, unsigned int i; unsigned int f; -#if DEBUG_ATS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", "Get session ID for session %p from peer %s in %p\n", session, GNUNET_i2s (peer), sh); -#endif + if (NULL == session) return 0; f = 0; @@ -396,11 +394,11 @@ get_session_id (struct GNUNET_ATS_SchedulingHandle *sh, struct Session *session, sh->session_array[f].session = session; sh->session_array[f].peer = *peer; sh->session_array[f].slot_used = GNUNET_YES; -#if DEBUG_ATS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", "Assigning session ID %u for session %p of peer %s in %p\n", f, session, GNUNET_i2s (peer), sh); -#endif + return f; } @@ -417,11 +415,13 @@ static void remove_session (struct GNUNET_ATS_SchedulingHandle *sh, uint32_t session_id, const struct GNUNET_PeerIdentity *peer) { -#if DEBUG_ATS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Remove sessionID %u from peer %s in %p\n", + GNUNET_assert (peer != NULL); + GNUNET_assert (sh != NULL); + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", + "Release sessionID %u from peer %s in %p\n", (unsigned int) session_id, GNUNET_i2s (peer), sh); -#endif + if (0 == session_id) return; GNUNET_assert (session_id < sh->session_array_size); @@ -445,11 +445,11 @@ static void release_session (struct GNUNET_ATS_SchedulingHandle *sh, uint32_t session_id, const struct GNUNET_PeerIdentity *peer) { -#if DEBUG_ATS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", "Release sessionID %u from peer %s in %p\n", (unsigned int) session_id, GNUNET_i2s (peer), sh); -#endif + if (session_id >= sh->session_array_size) { GNUNET_break (0); @@ -552,11 +552,10 @@ process_ats_message (void *cls, const struct GNUNET_MessageHeader *msg) s = find_session (sh, session_id, &m->peer); if (s == NULL) { -#if DEBUG_ATS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", "ATS tries to use outdated session `%s'\n", GNUNET_i2s (&m->peer)); -#endif GNUNET_CLIENT_receive (sh->client, &process_ats_message, sh, GNUNET_TIME_UNIT_FOREVER_REL); return; @@ -618,10 +617,10 @@ reconnect (struct GNUNET_ATS_SchedulingHandle *sh) do_transmit (sh); } + /** * delete the current network list */ - static void delete_networks (struct GNUNET_ATS_SchedulingHandle *sh) { @@ -734,7 +733,6 @@ interface_proc (void *cls, const char *name, } - /** * Periodically get list of addresses * @param cls closure @@ -752,15 +750,16 @@ get_addresses (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) sh); } + /** * Returns where the address is located: LAN or WAN or ... + * * @param sh the scheduling handle * @param addr address * @param addrlen address length * @return location as GNUNET_ATS_Information */ - -const struct GNUNET_ATS_Information +struct GNUNET_ATS_Information GNUNET_ATS_address_get_type (struct GNUNET_ATS_SchedulingHandle * sh, const struct sockaddr * addr, socklen_t addrlen) { GNUNET_assert (sh != NULL); @@ -807,7 +806,8 @@ GNUNET_ATS_address_get_type (struct GNUNET_ATS_SchedulingHandle * sh, const stru if (((a4->sin_addr.s_addr & mask4->sin_addr.s_addr)) == net4->sin_addr.s_addr) { char * net = GNUNET_strdup (GNUNET_a2s ((const struct sockaddr *) net4, addrlen)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' is in network `%s'\n", + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", + "`%s' is in network `%s'\n", GNUNET_a2s ((const struct sockaddr *)a4, addrlen), net); GNUNET_free (net); @@ -845,33 +845,12 @@ GNUNET_ATS_address_get_type (struct GNUNET_ATS_SchedulingHandle * sh, const stru /* no local network found for this address, default: WAN */ if (type == GNUNET_ATS_NET_UNSPECIFIED) type = GNUNET_ATS_NET_WAN; - -#if VERBOSE - const char * range; - switch (type) { - case GNUNET_ATS_NET_WAN: - range = "WAN"; - break; - case GNUNET_ATS_NET_LAN: - range = "LAN"; - break; - case GNUNET_ATS_NET_LOOPBACK: - range = "LOOPBACK"; - break; - default: - - break; - } - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "`%s' is in network `%s'\n", - GNUNET_a2s ((const struct sockaddr *) addr, addrlen), - range); -#endif - ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); ats.value = htonl (type); return (const struct GNUNET_ATS_Information) ats; } + /** * Initialize the ATS subsystem. * @@ -918,7 +897,7 @@ GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh) } if (NULL != sh->client) { - GNUNET_CLIENT_disconnect (sh->client, GNUNET_NO); + GNUNET_CLIENT_disconnect (sh->client); sh->client = NULL; } if (GNUNET_SCHEDULER_NO_TASK != sh->task) @@ -938,6 +917,32 @@ GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh) sh = NULL; } +/** + * We would like to reset the address suggestion block time for this + * peer + * + * @param sh handle + * @param peer identity of the peer we want to reset + */ +void +GNUNET_ATS_reset_backoff (struct GNUNET_ATS_SchedulingHandle *sh, + const struct GNUNET_PeerIdentity *peer) +{ + struct PendingMessage *p; + struct ResetBackoffMessage *m; + + p = GNUNET_malloc (sizeof (struct PendingMessage) + + sizeof (struct ResetBackoffMessage)); + p->size = sizeof (struct ResetBackoffMessage); + p->is_init = GNUNET_NO; + m = (struct ResetBackoffMessage *) &p[1]; + m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_RESET_BACKOFF); + m->header.size = htons (sizeof (struct ResetBackoffMessage)); + m->reserved = htonl (0); + m->peer = *peer; + GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p); + do_transmit (sh); +} /** * We would like to establish a new connection with a peer. ATS @@ -953,6 +958,8 @@ GNUNET_ATS_suggest_address (struct GNUNET_ATS_SchedulingHandle *sh, struct PendingMessage *p; struct RequestAddressMessage *m; + // FIXME: ATS needs to remember this in case of + // a disconnect! p = GNUNET_malloc (sizeof (struct PendingMessage) + sizeof (struct RequestAddressMessage)); p->size = sizeof (struct RequestAddressMessage); @@ -993,6 +1000,7 @@ GNUNET_ATS_suggest_address_cancel (struct GNUNET_ATS_SchedulingHandle *sh, do_transmit (sh); } + /** * We have updated performance statistics for a given address. Note * that this function can be called for addresses that are currently @@ -1117,10 +1125,10 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh, memcpy (pm, address->address, address->address_length); memcpy (&pm[address->address_length], address->transport_name, namelen); GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p); - do_transmit (sh); } + /** * A session got destroyed, stop including it as a valid address. * diff --git a/src/ats/gnunet-service-ats.c b/src/ats/gnunet-service-ats.c index 7deca0b..aef72f1 100644 --- a/src/ats/gnunet-service-ats.c +++ b/src/ats/gnunet-service-ats.c @@ -39,6 +39,9 @@ */ struct GNUNET_STATISTICS_Handle *GSA_stats; +static struct GNUNET_SERVER_Handle *GSA_server; + + /** * We have received a 'ClientStartMessage' from a client. Find out which * type of client it is and notify the respective subsystem. @@ -54,7 +57,6 @@ handle_ats_start (void *cls, struct GNUNET_SERVER_Client *client, const struct ClientStartMessage *msg = (const struct ClientStartMessage *) message; enum StartFlag flag; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "ATS_START"); flag = ntohl (msg->start_flag); switch (flag) @@ -111,6 +113,7 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GAS_scheduling_done (); GAS_performance_done (); GAS_reservations_done (); + GNUNET_SERVER_disconnect_notify_cancel (GSA_server, &client_disconnect_handler, NULL); if (NULL != GSA_stats) { GNUNET_STATISTICS_destroy (GSA_stats, GNUNET_NO); @@ -150,8 +153,12 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, sizeof (struct ReservationRequestMessage)}, {&GAS_handle_preference_change, NULL, GNUNET_MESSAGE_TYPE_ATS_PREFERENCE_CHANGE, 0}, + {&GAS_handle_reset_backoff, NULL, + GNUNET_MESSAGE_TYPE_ATS_RESET_BACKOFF, + sizeof (struct ResetBackoffMessage)}, {NULL, NULL, 0, 0} }; + GSA_server = server; GSA_stats = GNUNET_STATISTICS_create ("ats", cfg); GAS_reservations_init (); GAS_performance_init (server); diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c index fb9bad0..9bf5ca6 100644 --- a/src/ats/gnunet-service-ats_addresses.c +++ b/src/ats/gnunet-service-ats_addresses.c @@ -37,6 +37,8 @@ #define VERBOSE GNUNET_NO +#define ATS_BLOCKING_DELTA GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 100) + enum ATS_Mode { /* @@ -66,6 +68,25 @@ static unsigned int active_addr_count; static int ats_mode; +static int running; + + +static void +send_bw_notification (struct ATS_Address *aa) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New bandwidth for peer %s is %u/%u\n", + GNUNET_i2s (&aa->peer), ntohl (aa->assigned_bw_in.value__), + ntohl (aa->assigned_bw_out.value__)); + GAS_scheduling_transmit_address_suggestion (&aa->peer, aa->plugin, aa->addr, + aa->addr_len, aa->session_id, + aa->ats, aa->ats_count, + aa->assigned_bw_out, + aa->assigned_bw_in); + GAS_reservations_set_bandwidth (&aa->peer, aa->assigned_bw_in); + GAS_performance_notify_clients (&aa->peer, aa->plugin, aa->addr, aa->addr_len, + aa->ats, aa->ats_count, aa->assigned_bw_out, + aa->assigned_bw_in); +} /** * Update a bandwidth assignment for a peer. This trivial method currently @@ -90,18 +111,8 @@ update_bw_simple_it (void *cls, const GNUNET_HashCode * key, void *value) aa->assigned_bw_in.value__ = htonl (wan_quota_in / active_addr_count); aa->assigned_bw_out.value__ = htonl (wan_quota_out / active_addr_count); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New bandwidth for peer %s is %u/%u\n", - GNUNET_i2s (&aa->peer), ntohl (aa->assigned_bw_in.value__), - ntohl (aa->assigned_bw_out.value__)); - GAS_scheduling_transmit_address_suggestion (&aa->peer, aa->plugin, aa->addr, - aa->addr_len, aa->session_id, - aa->ats, aa->ats_count, - aa->assigned_bw_out, - aa->assigned_bw_in); - GAS_reservations_set_bandwidth (&aa->peer, aa->assigned_bw_in); - GAS_performance_notify_clients (&aa->peer, aa->plugin, aa->addr, aa->addr_len, - aa->ats, aa->ats_count, aa->assigned_bw_out, - aa->assigned_bw_in); + send_bw_notification (aa); + return GNUNET_OK; } @@ -159,9 +170,6 @@ create_address (const struct GNUNET_PeerIdentity *peer, memcpy (&aa[1], plugin_addr, plugin_addr_len); aa->plugin = GNUNET_strdup (plugin_name); aa->session_id = session_id; - aa->mlp_information = NULL; - aa->next = NULL; - aa->prev = NULL; return aa; } @@ -332,6 +340,11 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, struct ATS_Address *old; uint32_t i; + if (GNUNET_NO == running) + return; + + GNUNET_assert (NULL != addresses); + aa = create_address (peer, plugin_name, plugin_addr, plugin_addr_len, @@ -342,11 +355,10 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, aa->ats_count = atsi_count; memcpy (aa->ats, atsi, atsi_count * sizeof (struct GNUNET_ATS_Information)); -#if DEBUG_ATS GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s' %u\n", GNUNET_i2s (peer), session_id); -#endif + /* Get existing address or address with session == 0 */ old = find_address (peer, aa); if (old == NULL) @@ -445,11 +457,11 @@ destroy_by_session_id (void *cls, const GNUNET_HashCode * key, void *value) (aa->addr_len == info->addr_len) && (0 == memcmp (info->addr, aa->addr, aa->addr_len))) { -#if VERBOSE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting address for peer `%s': `%s' %u\n", GNUNET_i2s (&aa->peer), aa->plugin, aa->session_id); -#endif + if (GNUNET_YES == destroy_address (aa)) recalculate_assigned_bw (); return GNUNET_OK; @@ -503,6 +515,9 @@ GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer, { struct ATS_Address *aa; + if (GNUNET_NO == running) + return; + GNUNET_break (0 < strlen (plugin_name)); aa = create_address (peer, plugin_name, plugin_addr, plugin_addr_len, session_id); @@ -529,6 +544,49 @@ find_address_it (void *cls, const GNUNET_HashCode * key, void *value) struct ATS_Address **ap = cls; struct ATS_Address *aa = (struct ATS_Address *) value; struct ATS_Address *ab = *ap; + struct GNUNET_TIME_Absolute now; + + now = GNUNET_TIME_absolute_get(); + + if (aa->blocked_until.abs_value == GNUNET_TIME_absolute_max (now, aa->blocked_until).abs_value) + { + /* This address is blocked for suggestion */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Address %p blocked for suggestion for %llu ms \n", + aa, + GNUNET_TIME_absolute_get_difference(now, aa->blocked_until).rel_value); + return GNUNET_OK; + } + + aa->block_interval = GNUNET_TIME_relative_add (aa->block_interval, ATS_BLOCKING_DELTA); + aa->blocked_until = GNUNET_TIME_absolute_add (now, aa->block_interval); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Address %p ready for suggestion, block interval now %llu \n", aa, aa->block_interval); + + /* FIXME this is a hack */ + + + if (NULL != ab) + { + if ((0 == strcmp (ab->plugin, "tcp")) && + (0 == strcmp (aa->plugin, "tcp"))) + { + if ((0 != ab->addr_len) && + (0 == aa->addr_len)) + { + /* saved address was an outbound address, but we have an inbound address */ + *ap = aa; + return GNUNET_OK; + } + if (0 == ab->addr_len) + { + /* saved address was an inbound address, so do not overwrite */ + return GNUNET_OK; + } + } + } + /* FIXME end of hack */ if (NULL == ab) { @@ -559,7 +617,7 @@ find_address_it (void *cls, const GNUNET_HashCode * key, void *value) } -void +int GAS_addresses_in_use (const struct GNUNET_PeerIdentity *peer, const char *plugin_name, const void *plugin_addr, size_t plugin_addr_len, uint32_t session_id, int in_use) @@ -573,19 +631,34 @@ GAS_addresses_in_use (const struct GNUNET_PeerIdentity *peer, 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); + aa = create_address (peer, plugin_name, plugin_addr, plugin_addr_len, session_id); old = find_exact_address (peer, aa); free_address (aa); - GNUNET_assert (old != NULL); - GNUNET_assert (old->used != in_use); + if (NULL == old) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (old->used == in_use) + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Address in use called multiple times for peer `%s': %s -> %s \n", + GNUNET_i2s (peer), + (GNUNET_NO == old->used) ? "NO" : "YES", + (GNUNET_NO == in_use) ? "NO" : "YES"); + return GNUNET_SYSERR; + } old->used = in_use; - #if HAVE_LIBGLPK if (ats_mode == MLP) GAS_mlp_address_update (mlp, addresses, old); #endif + return GNUNET_OK; } @@ -608,7 +681,7 @@ void request_address_mlp (const struct GNUNET_PeerIdentity *peer) if (aa == NULL) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "Cannot suggest address for peer `%s'\n", GNUNET_i2s (peer)); return; } @@ -617,18 +690,7 @@ void request_address_mlp (const struct GNUNET_PeerIdentity *peer) aa->active = GNUNET_YES; active_addr_count++; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New bandwidth for peer %s is %u/%u\n", - GNUNET_i2s (&aa->peer), ntohl (aa->assigned_bw_in.value__), - ntohl (aa->assigned_bw_out.value__)); - GAS_scheduling_transmit_address_suggestion (&aa->peer, aa->plugin, aa->addr, - aa->addr_len, aa->session_id, - aa->ats, aa->ats_count, - aa->assigned_bw_out, - aa->assigned_bw_in); - GAS_reservations_set_bandwidth (&aa->peer, aa->assigned_bw_in); - GAS_performance_notify_clients (&aa->peer, aa->plugin, aa->addr, aa->addr_len, - aa->ats, aa->ats_count, aa->assigned_bw_out, - aa->assigned_bw_in); + send_bw_notification (aa); } else { @@ -652,11 +714,14 @@ void request_address_simple (const struct GNUNET_PeerIdentity *peer) &find_address_it, &aa); if (aa == NULL) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "Cannot suggest address for peer `%s'\n", GNUNET_i2s (peer)); return; } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, + "Suggesting address %p for peer `%s'\n", aa, GNUNET_i2s (peer)); + if (aa->active == GNUNET_NO) { aa->active = GNUNET_YES; @@ -681,6 +746,9 @@ void request_address_simple (const struct GNUNET_PeerIdentity *peer) void GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer) { + if (GNUNET_NO == running) + return; + if (ats_mode == SIMPLE) { request_address_simple (peer); @@ -692,6 +760,30 @@ GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer) } +static int +reset_address_it (void *cls, const GNUNET_HashCode * key, void *value) +{ + struct ATS_Address *aa = value; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Resetting interval for peer `%s' address %p from %llu to 0\n", GNUNET_i2s (&aa->peer), aa, aa->block_interval); + + aa->blocked_until = GNUNET_TIME_UNIT_ZERO_ABS; + aa->block_interval = GNUNET_TIME_UNIT_ZERO; + return GNUNET_OK; +} + +void +GAS_addresses_handle_backoff_reset (const struct GNUNET_PeerIdentity *peer) +{ + GNUNET_break (GNUNET_SYSERR != GNUNET_CONTAINER_multihashmap_get_multiple (addresses, + &peer->hashPubKey, + &reset_address_it, + NULL)); +} + + + // FIXME: this function should likely end up in the LP-subsystem and // not with 'addresses' in the future... void @@ -699,6 +791,8 @@ GAS_addresses_change_preference (const struct GNUNET_PeerIdentity *peer, enum GNUNET_ATS_PreferenceKind kind, float score) { + if (GNUNET_NO == running) + return; #if HAVE_LIBGLPK if (ats_mode == MLP) GAS_mlp_address_change_preference (mlp, peer, kind, score); @@ -717,42 +811,86 @@ void GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_STATISTICS_Handle *stats) { - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_size (cfg, "ats", - "WAN_QUOTA_IN", - &wan_quota_in)); - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_size (cfg, "ats", - "WAN_QUOTA_OUT", - &wan_quota_out)); - - switch (GNUNET_CONFIGURATION_get_value_yesno (cfg, "ats", "MLP")) - { - /* MLP = YES */ - case GNUNET_YES: + int mode; + + char *quota_wan_in_str; + char *quota_wan_out_str; + + running = GNUNET_NO; + + addresses = GNUNET_CONTAINER_multihashmap_create (128); + GNUNET_assert (NULL != addresses); + + if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_IN", "a_wan_in_str)) + { + if (0 == strcmp(quota_wan_in_str, "unlimited") || + (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_wan_in_str, &wan_quota_in))) + wan_quota_in = (UINT32_MAX) /10; + + GNUNET_free (quota_wan_in_str); + quota_wan_in_str = NULL; + } + else + { + wan_quota_in = (UINT32_MAX) /10; + } + + if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_OUT", "a_wan_out_str)) + { + if (0 == strcmp(quota_wan_out_str, "unlimited") || + (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_wan_out_str, &wan_quota_out))) + wan_quota_out = (UINT32_MAX) /10; + + GNUNET_free (quota_wan_out_str); + quota_wan_out_str = NULL; + } + else + { + wan_quota_out = (UINT32_MAX) /10; + } + + mode = GNUNET_CONFIGURATION_get_value_yesno (cfg, "ats", "MLP"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MLP mode %u", mode); + switch (mode) + { + /* MLP = YES */ + case GNUNET_YES: #if HAVE_LIBGLPK - ats_mode = MLP; - /* Init the MLP solver with default values */ - mlp = GAS_mlp_init (cfg, stats, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS); - break; + ats_mode = MLP; + /* Init the MLP solver with default values */ + mlp = GAS_mlp_init (cfg, stats, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS); + if (NULL == mlp) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP mode was configured, but libglpk is not installed, switching to simple mode\n"); + GNUNET_STATISTICS_update (GSA_stats, "MLP mode enabled", 0, GNUNET_NO); + break; + } + else + { + GNUNET_STATISTICS_update (GSA_stats, "MLP enabled", 1, GNUNET_NO); + break; + } #else - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP mode was configured, but libglpk is not installed, switching to simple mode"); - ats_mode = SIMPLE; - break; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP mode was configured, but libglpk is not installed, switching to simple mode"); + GNUNET_STATISTICS_update (GSA_stats, "MLP enabled", 0, GNUNET_NO); + ats_mode = SIMPLE; + break; #endif - /* MLP = NO */ - case GNUNET_NO: - ats_mode = SIMPLE; - break; - /* No configuration value */ - case GNUNET_SYSERR: - ats_mode = SIMPLE; - break; - default: - break; + /* MLP = NO */ + case GNUNET_NO: + GNUNET_STATISTICS_update (GSA_stats, "MLP enabled", 0, GNUNET_NO); + ats_mode = SIMPLE; + break; + /* No configuration value */ + case GNUNET_SYSERR: + GNUNET_STATISTICS_update (GSA_stats, "MLP enabled", 0, GNUNET_NO); + ats_mode = SIMPLE; + break; + default: + break; } - - addresses = GNUNET_CONTAINER_multihashmap_create (128); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS started with %s mode\n", (SIMPLE == ats_mode) ? "SIMPLE" : "MLP"); + running = GNUNET_YES; } @@ -777,6 +915,9 @@ free_address_it (void *cls, const GNUNET_HashCode * key, void *value) void GAS_addresses_destroy_all () { + if (GNUNET_NO == running) + return; + if (addresses != NULL) GNUNET_CONTAINER_multihashmap_iterate (addresses, &free_address_it, NULL); GNUNET_assert (active_addr_count == 0); @@ -790,6 +931,7 @@ void GAS_addresses_done () { GAS_addresses_destroy_all (); + running = GNUNET_NO; GNUNET_CONTAINER_multihashmap_destroy (addresses); addresses = NULL; #if HAVE_LIBGLPK diff --git a/src/ats/gnunet-service-ats_addresses.h b/src/ats/gnunet-service-ats_addresses.h index 33ff586..fe07563 100644 --- a/src/ats/gnunet-service-ats_addresses.h +++ b/src/ats/gnunet-service-ats_addresses.h @@ -75,6 +75,16 @@ struct ATS_Address struct GNUNET_BANDWIDTH_Value32NBO assigned_bw_out; /** + * Blocking interval + */ + struct GNUNET_TIME_Relative block_interval; + + /** + * Time when address can be suggested again + */ + struct GNUNET_TIME_Absolute blocked_until; + + /** * Is this the active address for this peer? */ int active; @@ -102,10 +112,13 @@ GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg, void GAS_addresses_done (void); +void +GAS_addresses_handle_backoff_reset (const struct GNUNET_PeerIdentity *peer); + /** * This address is now used or not used anymore */ -void +int GAS_addresses_in_use (const struct GNUNET_PeerIdentity *peer, const char *plugin_name, const void *plugin_addr, size_t plugin_addr_len, uint32_t session_id, int in_use); diff --git a/src/ats/gnunet-service-ats_addresses_mlp.c b/src/ats/gnunet-service-ats_addresses_mlp.c index 61aa733..8bfa010 100644 --- a/src/ats/gnunet-service-ats_addresses_mlp.c +++ b/src/ats/gnunet-service-ats_addresses_mlp.c @@ -505,7 +505,9 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON * c 10) obey network specific quota */ + /* Row for c4) minimum connection */ int min = mlp->n_min; + /* Number of minimum connections is min(|Peers|, n_min) */ if (mlp->n_min > mlp->c_p) min = mlp->c_p; @@ -565,6 +567,7 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON mlp->ci++; struct ATS_Peer * peer = mlp->peer_head; + /* For all peers */ while (peer != NULL) { struct ATS_Address *addr = peer->head; @@ -590,16 +593,15 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON /* Set -r */ ia[mlp->ci] = peer->r_c9; ja[mlp->ci] = mlp->c_r; - ar[mlp->ci] = -1; + ar[mlp->ci] = -peer->f; mlp->ci++; #endif - + /* For all addresses of this peer */ while (addr != NULL) { mlpi = (struct MLP_information *) addr->mlp_information; /* coefficient for c 2) */ - ia[mlp->ci] = peer->r_c2; ja[mlp->ci] = mlpi->c_n; ar[mlp->ci] = 1; @@ -625,8 +627,6 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON } /* c 7) For all quality metrics */ - - for (c = 0; c < mlp->m_q; c++) { struct ATS_Peer *tp; @@ -640,7 +640,7 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON glp_set_row_name (mlp->prob, mlp->r_q[c], name); GNUNET_free (name); /* Set row bound == 0 */ - glp_set_row_bnds (mlp->prob, mlp->r_q[c], GLP_LO, 0.0, 0.0); + glp_set_row_bnds (mlp->prob, mlp->r_q[c], GLP_FX, 0.0, 0.0); ia[mlp->ci] = mlp->r_q[c]; ja[mlp->ci] = mlp->c_q[c]; @@ -657,7 +657,7 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON ia[mlp->ci] = mlp->r_q[c]; ja[mlp->ci] = mlpi->c_b; - ar[mlp->ci] = tp->f * value; + ar[mlp->ci] = tp->f_q[c] * value; mlp->ci++; } } @@ -747,7 +747,6 @@ mlp_create_problem (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHas /* Adding invariant columns */ /* Diversity d column */ - col = glp_add_cols (mlp->prob, 1); mlp->c_d = col; /* Column name */ @@ -758,7 +757,6 @@ mlp_create_problem (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHas glp_set_col_bnds (mlp->prob, col, GLP_LO, 0.0, 0.0); /* Utilization u column */ - col = glp_add_cols (mlp->prob, 1); mlp->c_u = col; /* Column name */ @@ -806,14 +804,16 @@ mlp_create_problem (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHas return res; } + /** * Solves the LP problem * * @param mlp the MLP Handle + * @param s_ctx context to return results * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure */ static int -mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp) +mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *s_ctx) { int res; struct GNUNET_TIME_Relative duration; @@ -867,13 +867,13 @@ lp_solv: duration = GNUNET_TIME_absolute_get_difference (start, end); mlp->lp_solved++; mlp->lp_total_duration =+ duration.rel_value; + s_ctx->lp_duration = duration; GNUNET_STATISTICS_update (mlp->stats,"# LP problem solved", 1, GNUNET_NO); - GNUNET_STATISTICS_set (mlp->stats,"# LP execution time", duration.rel_value, GNUNET_NO); - GNUNET_STATISTICS_set (mlp->stats,"# LP execution time average", + GNUNET_STATISTICS_set (mlp->stats,"# LP execution time (ms)", duration.rel_value, GNUNET_NO); + GNUNET_STATISTICS_set (mlp->stats,"# LP execution time average (ms)", mlp->lp_total_duration / mlp->lp_solved, GNUNET_NO); - /* Analyze problem status */ res = glp_get_status (mlp->prob); switch (res) { @@ -903,10 +903,11 @@ lp_solv: * Solves the MLP problem * * @param mlp the MLP Handle + * @param s_ctx context to return results * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure */ int -mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp) +mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *s_ctx) { int res; struct GNUNET_TIME_Relative duration; @@ -943,10 +944,11 @@ mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp) duration = GNUNET_TIME_absolute_get_difference (start, end); mlp->mlp_solved++; mlp->mlp_total_duration =+ duration.rel_value; + s_ctx->mlp_duration = duration; GNUNET_STATISTICS_update (mlp->stats,"# MLP problem solved", 1, GNUNET_NO); - GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time", duration.rel_value, GNUNET_NO); - GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time average", + GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time (ms)", duration.rel_value, GNUNET_NO); + GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time average (ms)", mlp->mlp_total_duration / mlp->mlp_solved, GNUNET_NO); /* Analyze problem status */ @@ -970,23 +972,24 @@ mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp) return GNUNET_OK; } -int GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp); +int GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *ctx); + static void mlp_scheduler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GAS_MLP_Handle *mlp = cls; + struct GAS_MLP_SolutionContext ctx; mlp->mlp_task = GNUNET_SCHEDULER_NO_TASK; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scheduled problem solving\n"); if (mlp->addr_in_problem != 0) - GAS_mlp_solve_problem(mlp); + GAS_mlp_solve_problem(mlp, &ctx); } @@ -994,17 +997,34 @@ mlp_scheduler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * Solves the MLP problem * * @param mlp the MLP Handle + * @param ctx solution context * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure */ int -GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp) +GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *ctx) { int res; - mlp->last_execution = GNUNET_TIME_absolute_get (); + /* Check if solving is already running */ + if (GNUNET_YES == mlp->semaphore) + { + if (mlp->mlp_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel(mlp->mlp_task); + mlp->mlp_task = GNUNET_SCHEDULER_NO_TASK; + } + mlp->mlp_task = GNUNET_SCHEDULER_add_delayed (mlp->exec_interval, &mlp_scheduler, mlp); + return GNUNET_SYSERR; + } + mlp->semaphore = GNUNET_YES; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Problem solving\n"); + mlp->last_execution = GNUNET_TIME_absolute_get (); + ctx->lp_result = GNUNET_SYSERR; + ctx->mlp_result = GNUNET_SYSERR; + ctx->lp_duration = GNUNET_TIME_UNIT_FOREVER_REL; + ctx->mlp_duration = GNUNET_TIME_UNIT_FOREVER_REL; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Solve LP problem\n"); #if WRITE_MLP char * name; static int i; @@ -1014,7 +1034,14 @@ GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp) GNUNET_free (name); # endif - res = mlp_solve_lp_problem (mlp); + res = mlp_solve_lp_problem (mlp, ctx); + ctx->lp_result = res; + if (res != GNUNET_OK) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "LP Problem solving failed\n"); + mlp->semaphore = GNUNET_NO; + return GNUNET_SYSERR; + } #if WRITE_MLP GNUNET_asprintf(&name, "problem_%i_lp_solution", i); @@ -1022,31 +1049,24 @@ GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp) GNUNET_free (name); # endif + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Solve MLP problem\n"); + res = mlp_solve_mlp_problem (mlp, ctx); + ctx->mlp_result = res; if (res != GNUNET_OK) { - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "LP Problem solving failed\n"); - + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP Problem solving failed\n"); + mlp->semaphore = GNUNET_NO; return GNUNET_SYSERR; } - - res = mlp_solve_mlp_problem (mlp); - #if WRITE_MLP GNUNET_asprintf(&name, "problem_%i_mlp_solution", i); glp_print_mip (mlp->prob, name); GNUNET_free (name); # endif - if (res != GNUNET_OK) - { - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MLP Problem solving failed\n"); - return GNUNET_SYSERR; - } - - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Problem solved\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Problem solved %s (LP duration %llu / MLP duration %llu)\n", + (GNUNET_OK == res) ? "successfully" : "failed", ctx->lp_duration.rel_value, ctx->mlp_duration.rel_value); /* Process result */ struct ATS_Peer *p = NULL; struct ATS_Address *a = NULL; @@ -1082,6 +1102,7 @@ GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp) mlp->mlp_task = GNUNET_SCHEDULER_NO_TASK; } mlp->mlp_task = GNUNET_SCHEDULER_add_delayed (mlp->exec_interval, &mlp_scheduler, mlp); + mlp->semaphore = GNUNET_NO; return res; } @@ -1105,20 +1126,46 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg, double D; double R; double U; - long long unsigned int tmp; + unsigned long long tmp; unsigned int b_min; unsigned int n_min; struct GNUNET_TIME_Relative i_exec; int c; + char * quota_out_str; + char * quota_in_str; /* Init GLPK environment */ - GNUNET_assert (glp_init_env() == 0); + int res = glp_init_env(); + switch (res) { + case 0: + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GLPK: `%s'\n", + "initialization successful"); + break; + case 1: + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GLPK: `%s'\n", + "environment is already initialized"); + break; + case 2: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not init GLPK: `%s'\n", + "initialization failed (insufficient memory)"); + GNUNET_free(mlp); + return NULL; + break; + case 3: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not init GLPK: `%s'\n", + "initialization failed (unsupported programming model)"); + GNUNET_free(mlp); + return NULL; + break; + default: + break; + } /* Create initial MLP problem */ mlp->prob = glp_create_prob(); GNUNET_assert (mlp->prob != NULL); - mlp->BIG_M = (double) (UINT32_MAX) /10; + mlp->BIG_M = (double) BIG_M_VALUE; /* Get diversity coefficient from configuration */ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", @@ -1231,37 +1278,57 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg, if ((entry_in == NULL) || (entry_out == NULL)) continue; - if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", entry_out, "a_out)) + if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_out, "a_out_str)) + { + if (0 == strcmp(quota_out_str, BIG_M_STRING) || + (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, "a_out))) + quota_out = mlp->BIG_M; + + GNUNET_free (quota_out_str); + quota_out_str = NULL; + } + else if (GNUNET_ATS_NET_UNSPECIFIED == quotas[c]) + { + quota_out = mlp->BIG_M; + } + else { quota_out = mlp->BIG_M; } - if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", entry_in, "a_in)) + + if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_in, "a_in_str)) + { + if (0 == strcmp(quota_in_str, BIG_M_STRING) || + (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, "a_in))) + quota_in = mlp->BIG_M; + + GNUNET_free (quota_in_str); + quota_in_str = NULL; + } + else if (GNUNET_ATS_NET_UNSPECIFIED == quotas[c]) { quota_in = mlp->BIG_M; } + else + { + quota_in = mlp->BIG_M; + } + /* Check if defined quota could make problem unsolvable */ - if ((n_min * b_min) > quota_out) + if (((n_min * b_min) > quota_out) && (GNUNET_ATS_NET_UNSPECIFIED != quotas[c])) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Inconsistent quota configuration value `%s': " \ - "outbound quota (%u Bps) too small for combination of minimum connections and minimum bandwidth per peer (%u * %u Bps = %u)\n", entry_out, quota_out, n_min, b_min, n_min * b_min); - unsigned int default_min = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__); - if ((quota_out / n_min) > default_min) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Reducing minimum bandwidth per peer to %u Bps\n", - (quota_out / n_min)); - b_min = (quota_out / n_min); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Reducing minimum bandwidth per peer to %u Bps and minimum connections to %u \n", - default_min, (quota_out / default_min)); - b_min = default_min; - n_min = (quota_out / default_min); - } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Inconsistent quota configuration value `%s': " + "outbound quota (%u Bps) too small for combination of minimum connections and minimum bandwidth per peer (%u * %u Bps = %u)\n", entry_out, quota_out, n_min, b_min, n_min * b_min); + + GAS_mlp_done(mlp); + mlp = NULL; + return NULL; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found `%s' quota %llu and `%s' quota %llu\n", entry_out, quota_out, entry_in, quota_in); + GNUNET_STATISTICS_update ((struct GNUNET_STATISTICS_Handle *) stats, entry_out, quota_out, GNUNET_NO); + GNUNET_STATISTICS_update ((struct GNUNET_STATISTICS_Handle *) stats, entry_in, quota_in, GNUNET_NO); mlp->quota_out[c] = quota_out; mlp->quota_in[c] = quota_in; } @@ -1302,7 +1369,7 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg, #endif mlp->control_param_mlp.tm_lim = max_duration.rel_value; - mlp->last_execution = GNUNET_TIME_absolute_get_forever(); + mlp->last_execution = GNUNET_TIME_UNIT_FOREVER_ABS; mlp->co_D = D; mlp->co_R = R; @@ -1310,7 +1377,7 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg, mlp->b_min = b_min; mlp->n_min = n_min; mlp->m_q = GNUNET_ATS_QualityPropertiesCount; - + mlp->semaphore = GNUNET_NO; return mlp; } @@ -1320,12 +1387,15 @@ update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality metrics for peer `%s'\n", GNUNET_i2s (&address->peer)); + GNUNET_assert (NULL != address); + GNUNET_assert (NULL != address->mlp_information); + GNUNET_assert (NULL != address->ats); + struct MLP_information *mlpi = address->mlp_information; struct GNUNET_ATS_Information *ats = address->ats; GNUNET_assert (mlpi != NULL); int c; - for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++) { int index = mlp_lookup_ats(address, mlp->q[c]); @@ -1374,7 +1444,7 @@ update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address) c3 ++; } } - if (c3 > 0) + if ((c3 > 0) && (avg > 0)) /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/ mlpi->q_averaged[c] = (double) c3 / avg; else @@ -1399,7 +1469,7 @@ update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address) c3 ++; } } - if (c3 > 0) + if ((c3 > 0) && (avg > 0)) /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/ mlpi->q_averaged[c] = (double) c3 / avg; else @@ -1487,8 +1557,9 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult { int new; struct MLP_information *mlpi; + struct GAS_MLP_SolutionContext ctx; - GNUNET_STATISTICS_update (mlp->stats,"# LP address updates", 1, GNUNET_NO); + GNUNET_STATISTICS_update (mlp->stats, "# MLP address updates", 1, GNUNET_NO); /* We add a new address */ if (address->mlp_information == NULL) @@ -1514,6 +1585,7 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult address->mlp_information = mlpi; mlp->addr_in_problem ++; + GNUNET_STATISTICS_update (mlp->stats, "# addresses in MLP", 1, GNUNET_NO); /* Check for and add peer */ struct ATS_Peer *peer = mlp_find_peer (mlp, &address->peer); @@ -1540,6 +1612,7 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult GNUNET_CONTAINER_DLL_insert (peer->head, peer->tail, address); GNUNET_CONTAINER_DLL_insert (mlp->peer_head, mlp->peer_tail, peer); mlp->c_p ++; + GNUNET_STATISTICS_update (mlp->stats, "# peers in MLP", 1, GNUNET_NO); } else { @@ -1549,7 +1622,6 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult GNUNET_CONTAINER_DLL_insert (peer->head, peer->tail, address); } - update_quality (mlp, address); } else @@ -1570,7 +1642,7 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult mlp->presolver_required = GNUNET_YES; } if (mlp->auto_solve == GNUNET_YES) - GAS_mlp_solve_problem (mlp); + GAS_mlp_solve_problem (mlp, &ctx); } /** @@ -1587,6 +1659,7 @@ void GAS_mlp_address_delete (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address) { GNUNET_STATISTICS_update (mlp->stats,"# LP address deletions", 1, GNUNET_NO); + struct GAS_MLP_SolutionContext ctx; /* Free resources */ if (address->mlp_information != NULL) @@ -1595,6 +1668,7 @@ GAS_mlp_address_delete (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult address->mlp_information = NULL; mlp->addr_in_problem --; + GNUNET_STATISTICS_update (mlp->stats, "# addresses in MLP", -1, GNUNET_NO); } /* Remove from peer list */ @@ -1613,6 +1687,7 @@ GAS_mlp_address_delete (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult GNUNET_CONTAINER_DLL_remove (mlp->peer_head, mlp->peer_tail, head); GNUNET_free (head); mlp->c_p --; + GNUNET_STATISTICS_update (mlp->stats, "# peers in MLP", -1, GNUNET_NO); } /* Update problem */ @@ -1626,7 +1701,7 @@ GAS_mlp_address_delete (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult /* Recalculate */ mlp->presolver_required = GNUNET_YES; if (mlp->auto_solve == GNUNET_YES) - GAS_mlp_solve_problem (mlp); + GAS_mlp_solve_problem (mlp, &ctx); } } @@ -1705,7 +1780,7 @@ void GAS_mlp_done (struct GAS_MLP_Handle *mlp) { struct ATS_Peer * peer; - struct ATS_Peer * tmp; + struct ATS_Address *addr; GNUNET_assert (mlp != NULL); @@ -1719,10 +1794,16 @@ GAS_mlp_done (struct GAS_MLP_Handle *mlp) peer = mlp->peer_head; while (peer != NULL) { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up peer `%s'\n", GNUNET_i2s (&peer->id)); GNUNET_CONTAINER_DLL_remove(mlp->peer_head, mlp->peer_tail, peer); - tmp = peer->next; + for (addr = peer->head; NULL != addr; addr = peer->head) + { + GNUNET_CONTAINER_DLL_remove(peer->head, peer->tail, addr); + GNUNET_free (addr->mlp_information); + addr->mlp_information = NULL; + } GNUNET_free (peer); - peer = tmp; + peer = mlp->peer_head; } mlp_delete_problem (mlp); diff --git a/src/ats/gnunet-service-ats_addresses_mlp.h b/src/ats/gnunet-service-ats_addresses_mlp.h index 8f60a85..d37eea7 100644 --- a/src/ats/gnunet-service-ats_addresses_mlp.h +++ b/src/ats/gnunet-service-ats_addresses_mlp.h @@ -36,6 +36,9 @@ #define DEBUG_MLP GNUNET_EXTRA_LOGGING +#define BIG_M_VALUE (UINT32_MAX) /10 +#define BIG_M_STRING "unlimited" + #define MLP_AVERAGING_QUEUE_LENGTH 3 #define MLP_MAX_EXEC_DURATION GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3) @@ -70,6 +73,14 @@ struct ATS_PreferedAddress struct ATS_Address *address; }; +struct GAS_MLP_SolutionContext +{ + int lp_result; + int mlp_result; + struct GNUNET_TIME_Relative lp_duration; + struct GNUNET_TIME_Relative mlp_duration; +}; + /** * MLP Handle */ @@ -128,6 +139,8 @@ struct GAS_MLP_Handle */ int auto_solve; + int semaphore; + /* state information */ /** @@ -318,10 +331,11 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg, * Solves the MLP problem on demand * * @param mlp the MLP Handle + * @param ctx solution context * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure */ int -GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp); +GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *ctx); /** diff --git a/src/ats/gnunet-service-ats_performance.c b/src/ats/gnunet-service-ats_performance.c index b127656..7ab8e9a 100644 --- a/src/ats/gnunet-service-ats_performance.c +++ b/src/ats/gnunet-service-ats_performance.c @@ -166,7 +166,7 @@ GAS_performance_notify_clients (const struct GNUNET_PeerIdentity *peer, sizeof (struct PeerInformationMessage) + atsi_count * sizeof (struct GNUNET_ATS_Information) + plugin_addr_len + plugin_name_length; - char buf[msize]; + char buf[msize] GNUNET_ALIGN; struct GNUNET_ATS_Information *atsp; char *addrp; diff --git a/src/ats/gnunet-service-ats_scheduling.c b/src/ats/gnunet-service-ats_scheduling.c index 72b72cd..0b66ac5 100644 --- a/src/ats/gnunet-service-ats_scheduling.c +++ b/src/ats/gnunet-service-ats_scheduling.c @@ -59,7 +59,6 @@ GAS_scheduling_add_client (struct GNUNET_SERVER_Client *client) } my_client = client; GNUNET_SERVER_notification_context_add (nc, client); - GNUNET_SERVER_client_keep (client); return GNUNET_OK; } @@ -76,7 +75,6 @@ GAS_scheduling_remove_client (struct GNUNET_SERVER_Client *client) if (my_client != client) return; GAS_addresses_destroy_all (); - GNUNET_SERVER_client_drop (client); my_client = NULL; } @@ -114,7 +112,7 @@ GAS_scheduling_transmit_address_suggestion (const struct GNUNET_PeerIdentity sizeof (struct AddressSuggestionMessage) + atsi_count * sizeof (struct GNUNET_ATS_Information) + plugin_addr_len + plugin_name_length; - char buf[msize]; + char buf[msize] GNUNET_ALIGN; struct GNUNET_ATS_Information *atsp; char *addrp; @@ -200,6 +198,30 @@ GAS_handle_request_address_cancel (void *cls, GNUNET_SERVER_receive_done (client, GNUNET_OK); } +/** + * Handle 'reset backoff' messages from clients. + * + * @param cls unused, NULL + * @param client client that sent the request + * @param message the request message + */ +void +GAS_handle_reset_backoff (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + const struct ResetBackoffMessage *msg = + (const struct ResetBackoffMessage *) message; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", + "RESET_BACKOFF"); + GNUNET_STATISTICS_update (GSA_stats, "# backoff reset requests received", 1, + GNUNET_NO); + GNUNET_break (0 == ntohl (msg->reserved)); + GAS_addresses_handle_backoff_reset (&msg->peer); + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} + /** * Handle 'address update' messages from clients. @@ -274,6 +296,7 @@ GAS_handle_address_in_use (void *cls, struct GNUNET_SERVER_Client *client, const struct AddressUseMessage *m; const char *address; const char *plugin_name; + int res; uint16_t address_length; uint16_t plugin_name_length; @@ -309,10 +332,21 @@ GAS_handle_address_in_use (void *cls, struct GNUNET_SERVER_Client *client, } in_use = ntohs (m->in_use); - GAS_addresses_in_use (&m->peer, plugin_name, address, address_length, - ntohl (m->session_id), in_use); + res = GAS_addresses_in_use (&m->peer, + plugin_name, + address, + address_length, + ntohl (m->session_id), + in_use); + + if (res == GNUNET_OK) + GNUNET_SERVER_receive_done (client, GNUNET_OK); + else + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + } - GNUNET_SERVER_receive_done (client, GNUNET_OK); } /** @@ -401,8 +435,13 @@ GAS_scheduling_init (struct GNUNET_SERVER_Handle *server) void GAS_scheduling_done () { + if (NULL != my_client) + { + my_client = NULL; + } GNUNET_SERVER_notification_context_destroy (nc); nc = NULL; + } diff --git a/src/ats/gnunet-service-ats_scheduling.h b/src/ats/gnunet-service-ats_scheduling.h index 45fca2f..08a7f1b 100644 --- a/src/ats/gnunet-service-ats_scheduling.h +++ b/src/ats/gnunet-service-ats_scheduling.h @@ -51,6 +51,19 @@ GAS_scheduling_remove_client (struct GNUNET_SERVER_Client *client); /** + * Handle 'reset backoff' messages from clients. + * + * @param cls unused, NULL + * @param client client that sent the request + * @param message the request message + */ +void +GAS_handle_reset_backoff (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message); + + +/** * Transmit the given address suggestion and bandwidth update to all scheduling * clients. * diff --git a/src/ats/perf_ats_mlp.c b/src/ats/perf_ats_mlp.c index a15e4b4..b9ee5e4 100644 --- a/src/ats/perf_ats_mlp.c +++ b/src/ats/perf_ats_mlp.c @@ -18,8 +18,8 @@ Boston, MA 02111-1307, USA. */ /** - * @file ats/test_ats_mlp.c - * @brief test for the MLP solver + * @file ats/perf_ats_mlp + * @brief performance test for the MLP solver * @author Christian Grothoff * @author Matthias Wachs @@ -29,110 +29,344 @@ #include "gnunet_statistics_service.h" #include "gnunet-service-ats_addresses_mlp.h" -#define VERBOSE GNUNET_YES -#define VERBOSE_ARM GNUNET_NO - #define MLP_MAX_EXEC_DURATION GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3) #define MLP_MAX_ITERATIONS INT_MAX +#define DEF_PEERS 10 +#define DEF_ADDRESSES_PER_PEER 5 +#define DEF_ATS_VALUES 2 +#define DEF_ATS_MAX_DELAY 30 +#define DEF_ATS_MAX_DISTANCE 3 + +static unsigned int peers; +static unsigned int addresses; +static unsigned int numeric; +static unsigned int update_percentage; + +static int start; +static int end; + +struct ATS_Peer *p; +struct ATS_Address *a; static int ret; -struct GNUNET_STATISTICS_Handle * stats; +static struct GNUNET_CONTAINER_MultiHashMap * amap; -struct GNUNET_CONTAINER_MultiHashMap * addresses; +static struct GAS_MLP_Handle *mlp; -struct GAS_MLP_Handle *mlp; -static void -check (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) + + +GNUNET_SCHEDULER_TaskIdentifier shutdown_task; + +struct PeerContext { -#if !HAVE_LIBGLPK - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GLPK not installed!"); - ret = 1; - return; -#endif - struct ATS_Address addr[10]; + struct GNUNET_PeerIdentity id; - stats = GNUNET_STATISTICS_create("ats", cfg); + struct Address *addr; +}; - addresses = GNUNET_CONTAINER_multihashmap_create (10); +struct Address +{ + char *plugin; + size_t plugin_len; - GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_WEAK, &addr[0].peer.hashPubKey); - addr[0].mlp_information = NULL; - addr[0].next = NULL; - addr[0].prev = NULL; - addr[0].plugin = strdup ("dummy"); + void *addr; + size_t addr_len; - addr[1].peer = addr[0].peer; - addr[1].mlp_information = NULL; - addr[1].next = NULL; - addr[1].prev = NULL; - addr[1].plugin = strdup ("dummy2"); + struct GNUNET_ATS_Information *ats; + int ats_count; - GNUNET_CONTAINER_multihashmap_put(addresses, &addr[0].peer.hashPubKey, &addr[0], GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + void *session; +}; - mlp = GAS_mlp_init (cfg, NULL, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS); +void +do_shutdown (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + unsigned int ca; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown\n"); + + if (NULL != mlp) + { + GAS_mlp_done (mlp); + mlp = NULL; + } + + if (NULL != a) + { + for (ca=0; ca < (peers * addresses); ca++) + { + GNUNET_free (a[ca].plugin); + GNUNET_free (a[ca].ats); + } + } + + if (NULL != amap) + GNUNET_CONTAINER_multihashmap_destroy(amap); + GNUNET_free_non_null (a); + GNUNET_free_non_null (p); - /* Add a new address */ -#if 0 - GAS_mlp_address_update (mlp, addresses, &addr[0]); +} - GNUNET_assert (mlp != NULL); - GNUNET_assert (mlp->addr_in_problem == 1); +static void +update_addresses (struct ATS_Address * a, unsigned int addrs, unsigned int percentage) +{ + if (percentage == 0) + return; + + unsigned int ua = (addrs) * ((float) percentage / 100); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Updating %u of %u addresses per peer\n", ua, addrs); + + unsigned int updated[addrs]; + unsigned int u_types[DEF_ATS_VALUES]; + unsigned int updates = 0; + unsigned int u_type = 0; + unsigned int u_val = 0; + unsigned int cur = 0; + + u_types[0] = 0; + u_types[1] = 0; + + for (cur = 0; cur < addrs; cur ++) + { + updated[cur] = 0; + } + cur = 0; + + while (updates < ua) + { + cur = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, addrs); + if (0 == updated[cur]) + { + u_type = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, DEF_ATS_VALUES); + switch (u_type) { + case 0: + do + { + u_val = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, DEF_ATS_MAX_DELAY); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating DELAY from %u to %u\n",a[cur].ats[u_type].value, u_val); + } + while (a[cur].ats[u_type].value == u_val); + break; + case 1: + do + { + u_val = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, DEF_ATS_MAX_DISTANCE); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating DISTANCE from %u to %u\n",a[cur].ats[u_type].value, u_val); + } + while (a[cur].ats[u_type].value == u_val); + break; + default: + GNUNET_break (0); + break; + } + u_types[u_type]++; + + a[cur].ats[u_type].value = u_val; + updated[cur] = 1; + GAS_mlp_address_update(mlp, amap, &a[cur]); + updates++; + } + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Updated %u delay and %u distance values\n", u_types[0], u_types[1]); - /* Update an new address */ - GAS_mlp_address_update (mlp, addresses, &addr[0]); - GNUNET_assert (mlp->addr_in_problem == 1); +} - /* Add a second address for same peer */ - GNUNET_CONTAINER_multihashmap_put(addresses, &addr[0].peer.hashPubKey, &addr[1], GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); - GAS_mlp_address_update (mlp, addresses, &addr[1]); - GNUNET_assert (mlp->addr_in_problem == 2); - /* Delete an address */ - GNUNET_CONTAINER_multihashmap_remove (addresses, &addr[0].peer.hashPubKey, &addr[0]); - GAS_mlp_address_delete (mlp, addresses, &addr[0]); - GAS_mlp_address_delete (mlp, addresses, &addr[1]); +static void +check (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + unsigned int c = 0; + unsigned int c2 = 0; + unsigned int ca = 0; + int update = GNUNET_NO; + int range = GNUNET_NO; + int res; + +#if !HAVE_LIBGLPK + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GLPK not installed!"); + ret = 1; + return; #endif - GAS_mlp_done (mlp); - GNUNET_free (addr[0].plugin); - GNUNET_free (addr[1].plugin); - GNUNET_CONTAINER_multihashmap_destroy (addresses); - GNUNET_STATISTICS_destroy(stats, GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up %u peers with %u addresses per peer\n", peers, addresses); + + mlp = GAS_mlp_init (cfg, NULL, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS); + if (NULL == mlp) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to init MLP\n"); + ret = 1; + if (GNUNET_SCHEDULER_NO_TASK != shutdown_task) + GNUNET_SCHEDULER_cancel(shutdown_task); + shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); + } + + if (peers == 0) + peers = DEF_PEERS; + if (addresses == 0) + addresses = DEF_ADDRESSES_PER_PEER; + + p = GNUNET_malloc (peers * sizeof (struct ATS_Peer)); + a = GNUNET_malloc (peers * addresses * sizeof (struct ATS_Address)); + + amap = GNUNET_CONTAINER_multihashmap_create(addresses * peers); + + mlp->auto_solve = GNUNET_NO; + if (start == 0) + start = 0; + if (end == 0) + end = -1; + if ((start != -1) && (end != -1)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Solving problem starting from %u to %u\n", start , end); + range = GNUNET_YES; + } + else + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Solving problem for %u peers\n", peers); + + if ((update_percentage >= 0) && (update_percentage <= 100)) + { + update = GNUNET_YES; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Benchmarking with existing presolution and %u%% updated addresses\n", update_percentage); + } + else if ((update_percentage > 100) && (update_percentage != UINT_MAX)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Invalid percentage: %u\n", update_percentage); + ret = 1; + return; + } + + for (c=0; c < peers; c++) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up peer %u\n", c); + GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_NONCE, &p[c].id.hashPubKey); + + for (c2=0; c2 < addresses; c2++) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up address %u for peer %u\n", c2, c); + /* Setting required information */ + a[ca].mlp_information = NULL; + a[ca].prev = NULL; + a[ca].next = NULL; + + /* Setting address */ + a[ca].peer = p[c].id; + a[ca].plugin = GNUNET_strdup("test"); + a[ca].atsp_network_type = GNUNET_ATS_NET_LOOPBACK; + + a[ca].ats = GNUNET_malloc (DEF_ATS_VALUES * sizeof (struct GNUNET_ATS_Information)); + a[ca].ats[0].type = GNUNET_ATS_QUALITY_NET_DELAY; + a[ca].ats[0].value = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, DEF_ATS_MAX_DELAY); + a[ca].ats[1].type = GNUNET_ATS_QUALITY_NET_DISTANCE; + a[ca].ats[1].value = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, DEF_ATS_MAX_DISTANCE); + a[ca].ats_count = 2; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up address %u\n", ca); + GNUNET_CONTAINER_multihashmap_put (amap, &a[ca].peer.hashPubKey, &a[ca], GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + GAS_mlp_address_update(mlp, amap, &a[ca]); + ca++; + } + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Problem contains %u peers and %u adresses\n", mlp->c_p, mlp->addr_in_problem); + + if (((GNUNET_YES == range) && (((start >= 0) && ((c+1) >= start)) && (c <= end))) || ((c+1) == peers)) + { + GNUNET_assert ((c+1) == mlp->c_p); + GNUNET_assert ((c+1) * addresses == mlp->addr_in_problem); + + /* Solving the problem */ + struct GAS_MLP_SolutionContext ctx; + + res = GAS_mlp_solve_problem(mlp, &ctx); + + if (GNUNET_NO == update) + { + if (GNUNET_OK == res) + { + GNUNET_assert (GNUNET_OK == ctx.lp_result); + GNUNET_assert (GNUNET_OK == ctx.mlp_result); + if (GNUNET_YES == numeric) + printf ("%u;%u;%llu;%llu\n",mlp->c_p, mlp->addr_in_problem, (unsigned long long) ctx.lp_duration.rel_value, (unsigned long long) ctx.mlp_duration.rel_value); + else + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Problem solved for %u peers with %u address successfully (LP: %llu ms / MLP: %llu ms)\n", + mlp->c_p, mlp->addr_in_problem, ctx.lp_duration.rel_value, ctx.mlp_duration.rel_value); + } + else + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Solving problem with %u peers and %u addresses failed\n", c, c2); + } + else + { + struct GAS_MLP_SolutionContext uctx; + /* Update addresses */ + update_addresses (a, (c+1) * c2, update_percentage); + + /* Solve again */ + res = GAS_mlp_solve_problem(mlp, &uctx); + + if (GNUNET_OK == res) + { + GNUNET_assert (GNUNET_OK == uctx.lp_result); + GNUNET_assert (GNUNET_OK == uctx.mlp_result); + if (GNUNET_YES == numeric) + printf ("%u;%u;%llu;%llu;%llu;%llu\n",mlp->c_p, mlp->addr_in_problem, + (unsigned long long) ctx.lp_duration.rel_value, (unsigned long long) ctx.mlp_duration.rel_value, + (unsigned long long) uctx.lp_duration.rel_value, (unsigned long long) uctx.mlp_duration.rel_value); + else + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Updated problem solved for %u peers with %u address successfully (Initial: LP/MLP: %llu/%llu ms, Update: %llu/%llu ms)\n", + mlp->c_p, mlp->addr_in_problem, + (unsigned long long) ctx.lp_duration.rel_value, (unsigned long long) ctx.mlp_duration.rel_value, + (unsigned long long) uctx.lp_duration.rel_value, (unsigned long long) uctx.mlp_duration.rel_value); + } + else + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Solving updated problem with %u peers and %u addresses failed\n", c, c2); + } + } + } + + if (GNUNET_SCHEDULER_NO_TASK != shutdown_task) + GNUNET_SCHEDULER_cancel(shutdown_task); + shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); - ret = 0; - return; } int main (int argc, char *argv[]) { - - static char *const argv2[] = { "test_ats_mlp", - "-c", - "test_ats_api.conf", -#if VERBOSE - "-L", "DEBUG", -#else - "-L", "WARNING", -#endif - NULL - }; - + /* Init invalid */ + update_percentage = UINT_MAX; static struct GNUNET_GETOPT_CommandLineOption options[] = { + {'a', "addresses", NULL, + gettext_noop ("addresses per peer"), 1, + &GNUNET_GETOPT_set_uint, &addresses}, + {'p', "peers", NULL, + gettext_noop ("peers"), 1, + &GNUNET_GETOPT_set_uint, &peers}, + {'n', "numeric", NULL, + gettext_noop ("numeric output only"), 0, + &GNUNET_GETOPT_set_one, &numeric}, + {'e', "end", NULL, + gettext_noop ("end solving problem"), 1, + &GNUNET_GETOPT_set_uint, &end}, + {'s', "start", NULL, + gettext_noop ("start solving problem"), 1, + &GNUNET_GETOPT_set_uint, &start}, + {'u', "update", NULL, + gettext_noop ("benchmark with existing solution (address updates)"), 1, + &GNUNET_GETOPT_set_uint, &update_percentage}, GNUNET_GETOPT_OPTION_END }; - GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2, - "test_ats_mlp", "nohelp", options, + + GNUNET_PROGRAM_run (argc, argv, + "perf_ats_mlp", "nohelp", options, &check, NULL); return ret; } -/* end of file test_ats_api_bandwidth_consumption.c */ +/* end of file perf_ats_mlp.c */ diff --git a/src/ats/test_ats_api.conf b/src/ats/test_ats_api.conf index fa379c9..efd7fc9 100644 --- a/src/ats/test_ats_api.conf +++ b/src/ats/test_ats_api.conf @@ -9,8 +9,6 @@ UNIXPATH = /tmp/test-ats-scheduling-arm.sock [ats] #DEBUG = YES #PREFIX = valgrind --leak-check=full -#WAN_QUOTA_OUT = 4294967295 -#WAN_QUOTA_IN = 4294967295 AUTOSTART = YES PORT = 12002 HOSTNAME = localhost @@ -21,4 +19,30 @@ ACCEPT_FROM = 127.0.0.1; ACCEPT_FROM6 = ::1; UNIXPATH = /tmp/test-ats-scheduling-ats.sock UNIX_MATCH_UID = YES -UNIX_MATCH_GID = YES
\ No newline at end of file +UNIX_MATCH_GID = YES + +# Enable MLP mode (default: NO) +MLP = NO +# Network specific inbound/outbound quotas +# LOOPBACK +LOOPBACK_QUOTA_IN = unlimited +LOOPBACK_QUOTA_OUT = unlimited +# LAN +LAN_QUOTA_IN = unlimited +LAN_QUOTA_OUT = unlimited +# WAN +WAN_QUOTA_IN = 64 KiB +WAN_QUOTA_OUT = 64 KiB +# WLAN +WLAN_QUOTA_IN = 1 MiB +WLAN_QUOTA_OUT = 1 MiB + +# ATS extended options +DUMP_MLP = NO +DUMP_SOLUTION = NO +DUMP_OVERWRITE = NO +DUMP_MIN_PEERS = 0 +DUMP_MIN_ADDRS = 0 +DUMP_OVERWRITE = NO +ATS_MIN_INTERVAL = 15000 +ATS_EXEC_INTERVAL = 30000 diff --git a/src/ats/test_ats_api_reset_backoff.c b/src/ats/test_ats_api_reset_backoff.c new file mode 100644 index 0000000..38c18e1 --- /dev/null +++ b/src/ats/test_ats_api_reset_backoff.c @@ -0,0 +1,308 @@ +/* + 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_reset_backoff.c + * @brief test case for block reset 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) +#define ATS_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 90) + +static GNUNET_SCHEDULER_TaskIdentifier die_task; + +static GNUNET_SCHEDULER_TaskIdentifier suggest_timeout_task; + +static struct GNUNET_ATS_SchedulingHandle *ats; + +struct GNUNET_OS_Process *arm_proc; + +static int ret; + +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 GNUNET_HELLO_Address hello_addr; +struct Address address; +struct PeerContext peer; +struct GNUNET_ATS_Information atsi[2]; + +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 (suggest_timeout_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (suggest_timeout_task); + suggest_timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + + if (ats != NULL) + { + GNUNET_ATS_scheduling_done (ats); + ats = NULL; + } + + 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; + } + + if (suggest_timeout_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (suggest_timeout_task); + suggest_timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + + GNUNET_ATS_scheduling_done (ats); + + ret = 0; + + stop_arm (); +} + + +static void +suggest_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + suggest_timeout_task = GNUNET_SCHEDULER_NO_TASK; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Requesting address for peer timed out\n"); + + if (die_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + } + + die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL); +} + +static void +address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *a, + 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) +{ + static int suggestions; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS suggests address `%s'\n", + GNUNET_i2s (&a->peer)); + + if (0 != memcmp (&a->peer, &peer.id, + sizeof (struct GNUNET_PeerIdentity))) + { + GNUNET_break (0); + if (die_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_SCHEDULER_add_now (&end_badly, NULL); + return; + } + + if (0 != strcmp (a->transport_name, address.plugin)) + { + GNUNET_break (0); + if (die_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_SCHEDULER_add_now (&end_badly, NULL); + return; + } + + if (a->address_length != address.addr_len) + { + GNUNET_break (0); + if (die_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_SCHEDULER_add_now (&end_badly, NULL); + return; + } + + if (0 != memcmp (a->address, address.addr, + a->address_length)) + { + GNUNET_break (0); + if (die_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_SCHEDULER_add_now (&end_badly, NULL); + return; + } + + if (session != address.session) + { + GNUNET_break (0); + if (die_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_SCHEDULER_add_now (&end_badly, NULL); + return; + } + + suggestions ++; + + if (2 == suggestions) + { + GNUNET_SCHEDULER_add_now(&end, NULL); + return; + } + + if (suggest_timeout_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (suggest_timeout_task); + suggest_timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + suggest_timeout_task = GNUNET_SCHEDULER_add_delayed(ATS_TIMEOUT, &suggest_timeout, NULL); +} + +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, + &peer.id.hashPubKey); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n", GNUNET_i2s (&peer.id)); + + address.plugin = "test"; + address.session = NULL; + address.addr = GNUNET_strdup ("test"); + address.addr_len = 4; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding address\n"); + + hello_addr.peer = peer.id; + hello_addr.transport_name = address.plugin; + hello_addr.address = address.addr; + hello_addr.address_length = address.addr_len; + GNUNET_ATS_address_update (ats, &hello_addr, address.session, NULL, 0); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Requesting address for peer `%s'\n", + GNUNET_i2s (&peer.id)); + /* Increase block timout far beyond ATS_TIMEOUT */ + GNUNET_ATS_suggest_address (ats, &peer.id); + + GNUNET_ATS_reset_backoff(ats, &peer.id); + GNUNET_ATS_suggest_address (ats, &peer.id); +} + +int +main (int argc, char *argv[]) +{ + static char *const argv2[] = { "test_ats_api_scheduling", + "-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", "nohelp", options, &check, + NULL); + + + return ret; +} +/* end of file test_ats_api_reset_backoff.c */ diff --git a/src/ats/test_ats_api_scheduling.c b/src/ats/test_ats_api_scheduling.c index 892186c..c9d2206 100644 --- a/src/ats/test_ats_api_scheduling.c +++ b/src/ats/test_ats_api_scheduling.c @@ -34,10 +34,6 @@ #include "gnunet_ats_service.h" #include "ats.h" -#define VERBOSE GNUNET_NO - -#define VERBOSE_ARM GNUNET_NO - #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) static GNUNET_SCHEDULER_TaskIdentifier die_task; @@ -81,7 +77,7 @@ 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_close (arm_proc); + GNUNET_OS_process_destroy (arm_proc); arm_proc = NULL; } @@ -158,9 +154,6 @@ start_arm (const char *cfgname) arm_proc = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", "gnunet-service-arm", -#if VERBOSE_ARM - "-L", "DEBUG", -#endif "-c", cfgname, NULL); } @@ -241,11 +234,7 @@ main (int argc, char *argv[]) static char *const argv2[] = { "test_ats_api_scheduling", "-c", "test_ats_api.conf", -#if VERBOSE - "-L", "DEBUG", -#else "-L", "WARNING", -#endif NULL }; diff --git a/src/ats/test_ats_mlp.c b/src/ats/test_ats_mlp.c index 14df2d0..c467210 100644 --- a/src/ats/test_ats_mlp.c +++ b/src/ats/test_ats_mlp.c @@ -30,9 +30,6 @@ #include "gnunet_ats_service.h" #include "gnunet-service-ats_addresses_mlp.h" -#define VERBOSE GNUNET_YES -#define VERBOSE_ARM GNUNET_NO - #define MLP_MAX_EXEC_DURATION GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3) #define MLP_MAX_ITERATIONS INT_MAX @@ -52,7 +49,7 @@ create_address (struct ATS_Address *addr, char * plugin, int ats_count, struct G addr->mlp_information = NULL; addr->next = NULL; addr->prev = NULL; - addr->plugin = strdup (plugin); + addr->plugin = GNUNET_strdup (plugin); addr->ats_count = ats_count; addr->ats = ats; } @@ -75,6 +72,7 @@ check (void *cls, char *const *args, const char *cfgfile, #endif struct ATS_Address addr[10]; struct ATS_PreferedAddress *res[10]; + struct GAS_MLP_SolutionContext ctx; stats = GNUNET_STATISTICS_create("ats", cfg); @@ -140,7 +138,9 @@ check (void *cls, char *const *args, const char *cfgfile, GAS_mlp_address_update (mlp, addresses, &addr[2]); GNUNET_assert (mlp->addr_in_problem == 3); - GNUNET_assert (GNUNET_OK == GAS_mlp_solve_problem(mlp)); + GNUNET_assert (GNUNET_OK == GAS_mlp_solve_problem(mlp, &ctx)); + GNUNET_assert (GNUNET_OK == ctx.lp_result); + GNUNET_assert (GNUNET_OK == ctx.mlp_result); res[0] = GAS_mlp_get_preferred_address(mlp, addresses, &p[0]); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Preferred address `%s' outbound bandwidth: %u Bps\n",res[0]->address->plugin, res[0]->bandwidth_out); @@ -176,11 +176,7 @@ main (int argc, char *argv[]) static char *const argv2[] = { "test_ats_mlp", "-c", "test_ats_api.conf", -#if VERBOSE - "-L", "DEBUG", -#else "-L", "WARNING", -#endif NULL }; diff --git a/src/ats/test_ats_mlp_averaging.c b/src/ats/test_ats_mlp_averaging.c index f7b7b1d..97e9aa7 100644 --- a/src/ats/test_ats_mlp_averaging.c +++ b/src/ats/test_ats_mlp_averaging.c @@ -30,9 +30,6 @@ #include "gnunet_ats_service.h" #include "gnunet-service-ats_addresses_mlp.h" -#define VERBOSE GNUNET_YES -#define VERBOSE_ARM GNUNET_NO - #define MLP_MAX_EXEC_DURATION GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3) #define MLP_MAX_ITERATIONS INT_MAX @@ -52,7 +49,7 @@ create_address (struct ATS_Address *addr, char * plugin, int ats_count, struct G addr->mlp_information = NULL; addr->next = NULL; addr->prev = NULL; - addr->plugin = strdup (plugin); + addr->plugin = GNUNET_strdup (plugin); addr->ats_count = ats_count; addr->ats = ats; } @@ -76,6 +73,7 @@ check (void *cls, char *const *args, const char *cfgfile, struct ATS_Address addr[10]; struct ATS_PreferedAddress *res[10]; struct MLP_information *mlpi; + struct GAS_MLP_SolutionContext ctx; stats = GNUNET_STATISTICS_create("ats", cfg); @@ -129,7 +127,9 @@ check (void *cls, char *const *args, const char *cfgfile, GNUNET_assert (mlp->addr_in_problem == 1); - GNUNET_assert (GNUNET_OK == GAS_mlp_solve_problem(mlp)); + GNUNET_assert (GNUNET_OK == GAS_mlp_solve_problem(mlp, &ctx)); + GNUNET_assert (GNUNET_OK == ctx.lp_result); + GNUNET_assert (GNUNET_OK == ctx.mlp_result); res[0] = GAS_mlp_get_preferred_address(mlp, addresses, &p[0]); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Preferred address `%s' outbound bandwidth: %u Bps\n",res[0]->address->plugin, res[0]->bandwidth_out); @@ -159,11 +159,7 @@ main (int argc, char *argv[]) static char *const argv2[] = { "test_ats_mlp", "-c", "test_ats_api.conf", -#if VERBOSE - "-L", "DEBUG", -#else "-L", "WARNING", -#endif NULL }; |