From ecd595792c22186f1dc610296ad7c1e39b54a902 Mon Sep 17 00:00:00 2001 From: Matthias Wachs Date: Wed, 14 Apr 2010 15:22:36 +0000 Subject: [PATCH] --- src/hostlist/hostlist-client.c | 67 +++++++++++++++++++++++++++++++--- src/hostlist/hostlist-client.h | 37 ++++++++++++++++++- src/hostlist/hostlist-server.c | 2 +- 3 files changed, 98 insertions(+), 8 deletions(-) diff --git a/src/hostlist/hostlist-client.c b/src/hostlist/hostlist-client.c index 0b05556e9..ec02f4545 100644 --- a/src/hostlist/hostlist-client.c +++ b/src/hostlist/hostlist-client.c @@ -726,6 +726,38 @@ disconnect_handler (void *cls, GNUNET_NO); } +struct compare_struct +{ + uint64_t lowest_quality; + const GNUNET_HashCode * key; + struct GNUNET_Hostlist * value; +}; + +static int iterate_hashmap_for_replacing ( void *cls, const GNUNET_HashCode *key, void *value ) +{ + struct compare_struct * cmp = cls; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + ("Now iterating over peer entry: %s\n"), GNUNET_i2s ( (const struct GNUNET_PeerIdentity *) key)); + if ( NULL == cmp->key ) + { + cmp->key = key; + cmp->lowest_quality = ((struct GNUNET_Hostlist *) value)->quality; + cmp->value = (struct GNUNET_Hostlist *) value; + } + else + { + if ( cmp->lowest_quality > ((struct GNUNET_Hostlist *) value)->quality) + { + cmp->lowest_quality = ((struct GNUNET_Hostlist *) value)->quality; + cmp->key = key; + cmp->value = (struct GNUNET_Hostlist *) value; + } + } + + return GNUNET_YES; +} + /** * Method called whenever an advertisement message arrives. * @@ -768,6 +800,9 @@ advertisement_handler (void *cls, memcpy ( hostlist->hostlist_uri, &incoming[1], uri_size ); hostlist->time_creation = GNUNET_TIME_absolute_get(); hostlist->time_last_usage = GNUNET_TIME_absolute_get_zero(); + hostlist->times_used = 0; + hostlist->quality = HOSTLIST_INITIAL; + GNUNET_HashCode * peer_ident_hash = (GNUNET_HashCode * ) &(peer->hashPubKey); @@ -775,14 +810,17 @@ advertisement_handler (void *cls, struct GNUNET_Hostlist * hostlist2; hostlist2 = GNUNET_malloc ( sizeof (struct GNUNET_Hostlist) ); char * str = "test"; + GNUNET_HashCode * peer_ident_test = GNUNET_malloc ( sizeof (GNUNET_HashCode) ); + GNUNET_CRYPTO_hash_from_string( "TEST", peer_ident_test); - hostlist2->peer = (*peer); + hostlist2->peer.hashPubKey = (*peer_ident_test) ; hostlist2->hello_count = 0; hostlist2->hostlist_uri = GNUNET_malloc ( strlen(str) +1 ); strcpy(hostlist2->hostlist_uri,str); hostlist2->time_creation = GNUNET_TIME_absolute_get(); hostlist2->time_last_usage = GNUNET_TIME_absolute_get_zero(); - GNUNET_CONTAINER_multihashmap_put ( hostlist_hashmap, peer_ident_hash, hostlist2, GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE ); + hostlist2->quality = HOSTLIST_INITIAL - 100; + GNUNET_CONTAINER_multihashmap_put ( hostlist_hashmap, peer_ident_test, hostlist2, GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE ); /* test */ if ( GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (hostlist_hashmap, peer_ident_hash) ) @@ -798,13 +836,32 @@ advertisement_handler (void *cls, else { /* No free entries available, replace existing entry */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "No free slots for hostlist available, searching for hostlist to replace\n", GNUNET_i2s (peer) ); + /* iterate over all entries in hashmap */ + struct compare_struct * cmp = GNUNET_malloc( sizeof( struct compare_struct) ); + cmp->lowest_quality = 0; + cmp->key = NULL; + GNUNET_CONTAINER_multihashmap_iterate ( hostlist_hashmap, + &iterate_hashmap_for_replacing, + cmp ); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peer %4s's hostlist has the worst quality of all peers with value %u \n", GNUNET_h2s (cmp->key), cmp->lowest_quality ); + /* replacing the entry with worst quality, if quality is below initial quality value */ + if ( cmp->lowest_quality < HOSTLIST_INITIAL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peer %4s' removed, added peer %4s \n", GNUNET_h2s (cmp->key), GNUNET_h2s ( peer_ident_hash) ); + GNUNET_CONTAINER_multihashmap_remove ( hostlist_hashmap, cmp->key, cmp->value ); + GNUNET_CONTAINER_multihashmap_put ( hostlist_hashmap, peer_ident_hash, hostlist, GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE ); + } return GNUNET_YES; } } else { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer already in hashmap\n"); /* hostlist entry already existing in hashmap */ @@ -920,7 +977,7 @@ static int load_hostlist_file () } -static int iterate_hashmap ( void *cls, const GNUNET_HashCode *key, void *value ) +static int iterate_hashmap_for_saving ( void *cls, const GNUNET_HashCode *key, void *value ) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, ("Now iterating over peer entry: %s\n"), GNUNET_i2s ( (const struct GNUNET_PeerIdentity *) key)); @@ -972,7 +1029,7 @@ static int save_hostlist_file () /* iterate over all entries in hashmap */ GNUNET_CONTAINER_multihashmap_iterate ( hostlist_hashmap, - &iterate_hashmap, + &iterate_hashmap_for_saving, wh ); if ( GNUNET_OK != GNUNET_BIO_write_close ( wh ) ) diff --git a/src/hostlist/hostlist-client.h b/src/hostlist/hostlist-client.h index 054a1c589..b7f1100e3 100644 --- a/src/hostlist/hostlist-client.h +++ b/src/hostlist/hostlist-client.h @@ -32,20 +32,53 @@ #include "gnunet_util_lib.h" #include "gnunet_time_lib.h" -#define MAX_NUMBER_HOSTLISTS 16 +#define MAX_NUMBER_HOSTLISTS 1 + +/* + * Defines concerning the hostlist quality metric + */ + +#define HOSTLIST_INITIAL 10000 +#define HOSTLIST_FAILED_DOWNLOAD 100 +#define HOSTLIST_SUCCESSFUL_DOWNLOAD 100 /* * a single hostlist obtained by hostlist advertisements */ struct GNUNET_Hostlist { - + /* + * peer offering the hostlist + */ struct GNUNET_PeerIdentity peer; + /* + * URI where hostlist can be obtained + */ char * hostlist_uri; + /* + * number of HELLO messages obtained during last download + */ unsigned long hello_count; + /* + * number of times the hostlist was obtained + */ unsigned long times_used; + /* + * time the hostlist advertisement was recieved and the entry was created + */ struct GNUNET_TIME_Absolute time_creation; + /* + * last time the hostlist was obtained + */ struct GNUNET_TIME_Absolute time_last_usage; + /* + * value describing the quality of the hostlist, the bigger the better but (should) never < 0 + * used for deciding which hostlist is replaced if MAX_NUMBER_HOSTLISTS in data structure is reached + * intial value = HOSTLIST_INITIAL + * increased every successful download by HOSTLIST_SUCCESSFULL_DOWNLOAD + * increased every successful download by number of obtained HELLO messages + * decreased every failed download by HOSTLIST_SUCCESSFULL_DOWNLOAD + */ uint64_t quality; }; diff --git a/src/hostlist/hostlist-server.c b/src/hostlist/hostlist-server.c index 92e5756ad..c04e99c42 100644 --- a/src/hostlist/hostlist-server.c +++ b/src/hostlist/hostlist-server.c @@ -20,7 +20,7 @@ /** * @file hostlist/hostlist-server.c - * @author Christian Grothoff + * @author Christian Grothoff, Matthias Wachs * @brief application to provide an integrated hostlist HTTP server */ -- 2.25.1