From bf73f35e6102aa4152f6af9e9ae0b3e571edeb1c Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 15 Apr 2010 16:29:55 +0000 Subject: [PATCH] cleaning --- src/hostlist/gnunet-daemon-hostlist.c | 50 ++- src/hostlist/gnunet-daemon-hostlist.h | 25 -- src/hostlist/hostlist-client.c | 451 +++++++++++++------------- src/hostlist/hostlist-client.h | 42 --- src/hostlist/hostlist-server.c | 214 +++++------- src/hostlist/hostlist-server.h | 2 +- 6 files changed, 324 insertions(+), 460 deletions(-) diff --git a/src/hostlist/gnunet-daemon-hostlist.c b/src/hostlist/gnunet-daemon-hostlist.c index 3622e0e8f..c06ee5f56 100644 --- a/src/hostlist/gnunet-daemon-hostlist.c +++ b/src/hostlist/gnunet-daemon-hostlist.c @@ -168,21 +168,11 @@ static int advertisement_handler (void *cls, struct GNUNET_TIME_Relative latency, uint32_t distance) { - if ( !learning ) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Recieved hostlist advertisement, but I am not learning!\n"); - return GNUNET_NO; - } - - if (learning && (NULL != client_adv_handler)) - { - (*client_adv_handler) (cls, peer, message, latency, distance); - return GNUNET_YES; - } - return GNUNET_NO; + GNUNET_assert (NULL != client_adv_handler); + return (*client_adv_handler) (cls, peer, message, latency, distance); } + /** * Method called whenever a given peer connects. Wrapper to call both client's and server's functions * @@ -260,14 +250,22 @@ cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } /** - * List of handlers for the messages understood by this - * service. + * List of handlers if we are learning. */ -static struct GNUNET_CORE_MessageHandler handlers[] = { - { &advertisement_handler, GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT, 0}, +static struct GNUNET_CORE_MessageHandler learn_handlers[] = { + { &advertisement_handler, GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT, 0}, + { NULL, 0, 0 } +}; + + +/** + * List of handlers if we are not learning. + */ +static struct GNUNET_CORE_MessageHandler no_learn_handlers[] = { { NULL, 0, 0 } }; + /** * Main function that will be run. * @@ -295,13 +293,13 @@ run (void *cls, stats = GNUNET_STATISTICS_create (sched, "hostlist", cfg); core = GNUNET_CORE_connect (sched, cfg, - GNUNET_TIME_UNIT_FOREVER_REL, - NULL, - &core_init, - NULL, &connect_handler, &disconnect_handler, - NULL, GNUNET_NO, - NULL, GNUNET_NO, - handlers); + GNUNET_TIME_UNIT_FOREVER_REL, + NULL, + &core_init, + NULL, &connect_handler, &disconnect_handler, + NULL, GNUNET_NO, + NULL, GNUNET_NO, + learning? learn_handlers : no_learn_handlers); if (bootstrapping) { @@ -312,10 +310,6 @@ run (void *cls, { GNUNET_HOSTLIST_server_start (cfg, sched, stats, core, &server_ch, &server_dh, advertising ); } - if (learning) - { - - } GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_UNIT_FOREVER_REL, diff --git a/src/hostlist/gnunet-daemon-hostlist.h b/src/hostlist/gnunet-daemon-hostlist.h index 7c30344b2..0b185ab7e 100644 --- a/src/hostlist/gnunet-daemon-hostlist.h +++ b/src/hostlist/gnunet-daemon-hostlist.h @@ -41,30 +41,5 @@ */ #define DEBUG_HOSTLIST GNUNET_NO -/** - * A HOSTLIST_ADV message is used to exchange information about - * hostlist advertisements. This struct is always - * followed by the actual url under which the hostlist can be obtained: - * - * 1) transport-name (0-terminated) - * 2) address-length (uint32_t, network byte order; possibly - * unaligned!) - * 3) address expiration (GNUNET_TIME_AbsoluteNBO); possibly - * unaligned!) - * 4) address (address-length bytes; possibly unaligned!) - */ -struct GNUNET_HOSTLIST_ADV_Message -{ - /** - * Type will be GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT. - */ - struct GNUNET_MessageHeader header; - - /** - * Always zero (for alignment). - */ - uint32_t reserved GNUNET_PACKED; -}; - /* end of gnunet-daemon-hostlist.h */ diff --git a/src/hostlist/hostlist-client.c b/src/hostlist/hostlist-client.c index ccc00a2ab..d882cdfbd 100644 --- a/src/hostlist/hostlist-client.c +++ b/src/hostlist/hostlist-client.c @@ -21,7 +21,8 @@ /** * @file hostlist/hostlist-client.c * @brief hostlist support. Downloads HELLOs via HTTP. - * @author Christian Grothoff, Matthias Wachs + * @author Christian Grothoff + * @author Matthias Wachs */ #include "platform.h" @@ -37,12 +38,66 @@ #define DEBUG_HOSTLIST_CLIENT GNUNET_YES +#define MAX_URL_LEN 1000 + /** * Number of connections that we must have to NOT download * hostlists anymore. */ #define MIN_CONNECTIONS 4 +/** + * A single hostlist obtained by hostlist advertisements + */ +struct GNUNET_Hostlist +{ + struct GNUNET_Hostlist * prev; + + struct GNUNET_Hostlist * next; + + /** + * URI where hostlist can be obtained + */ + const char *hostlist_uri; + + /** + * Peer offering the hostlist. TO BE REMOVED. + */ + struct GNUNET_PeerIdentity peer; + + /** + * 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; + + /** + * 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; + + /** + * Number of HELLO messages obtained during last download + */ + uint32_t hello_count; + + /** + * Number of times the hostlist was obtained + */ + uint32_t times_used; + +}; + + /** * Our configuration. */ @@ -113,20 +168,19 @@ static int bogus_url; */ static unsigned int connection_count; -/** - * Set if the user allows us to learn about new hostlists - * from the network. - */ -static int learning; - /** * At what time MUST the current hostlist request be done? */ static struct GNUNET_TIME_Absolute end_time; -struct GNUNET_Hostlist * dll_head; -struct GNUNET_Hostlist * dll_tail; -int dll_size; +/* DLL_? */ +static struct GNUNET_Hostlist * dll_head; + +/* DLL_? */ +static struct GNUNET_Hostlist * dll_tail; + +/* DLL_? */ +static unsigned int dll_size; /** * Process downloaded bits by calling callback on each HELLO. @@ -352,7 +406,7 @@ clean_up () * receiving task with the scheduler. */ static void -run_multi (); +run_multi (void); /** @@ -723,88 +777,54 @@ disconnect_handler (void *cls, GNUNET_NO); } -static int dll_contains ( char * uri) -{ - struct GNUNET_Hostlist * actual = dll_head; - - if (dll_size == 0) - return GNUNET_NO; - actual = dll_head; - while ( GNUNET_YES ) - { - if ( 0 == strcmp(actual->hostlist_uri,uri) ) return GNUNET_YES; - if (actual == dll_tail) break; - actual = actual->next; - } +/* DLL_? */ +static int +dll_contains (const char * uri) +{ + struct GNUNET_Hostlist * pos; + pos = dll_head; + while (pos != NULL) + { + if (0 == strcmp(pos->hostlist_uri, uri) ) + return GNUNET_YES; + pos = pos->next; + } return GNUNET_NO; } -struct GNUNET_Hostlist * dll_get ( char * uri ) -{ - struct GNUNET_Hostlist * actual = dll_head; - - if (dll_size == 0) - return NULL; - actual = dll_head; - - while ( GNUNET_YES) - { - if ( 0 == strcmp(actual->hostlist_uri,uri) ) return actual; - if (actual == dll_tail) break; - actual = actual->next; - } - - return NULL; -} -struct GNUNET_Hostlist * dll_get_lowest_quality ( ) +/* DLL_? */ +static struct GNUNET_Hostlist * +dll_get_lowest_quality ( ) { - struct GNUNET_Hostlist * actual = dll_head; - struct GNUNET_Hostlist * lowest = NULL; + struct GNUNET_Hostlist * pos; + struct GNUNET_Hostlist * lowest; if (dll_size == 0) - return lowest; - - lowest = dll_tail; - actual = dll_head; - - while ( GNUNET_YES) - { - if ( actual->quality < lowest->quality) lowest = actual; - if (actual == dll_tail) break; - actual = actual->next; - } - + return NULL; + lowest = dll_head; + pos = dll_head->next; + while (pos != NULL) + { + if (pos->quality < lowest->quality) + lowest = pos; + pos = pos->next; + } return lowest; } -static int dll_insert ( struct GNUNET_Hostlist * elem) -{ - if (dll_size <= MAX_NUMBER_HOSTLISTS) - { - GNUNET_CONTAINER_DLL_insert(dll_head, dll_tail,elem); - dll_size++; - return GNUNET_OK; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Maximum number of %u for hostlist entries reached, \n", MAX_NUMBER_HOSTLISTS ); - return GNUNET_SYSERR; -} -static int dll_remove ( struct GNUNET_Hostlist * elem) +#if DUMMY +/* TO BE REMOVED later */ +static void dll_insert ( struct GNUNET_Hostlist *hostlist) { - if ( GNUNET_YES == dll_contains (elem->hostlist_uri)) - { - GNUNET_CONTAINER_DLL_remove(dll_head, dll_tail,elem); - dll_size--; - return GNUNET_OK; - } - return GNUNET_SYSERR; + GNUNET_CONTAINER_DLL_insert(dll_head, dll_tail, hostlist); + dll_size++; } -void create_dummy_entries () +static void create_dummy_entries () { /* test */ @@ -869,6 +889,7 @@ void create_dummy_entries () "Adding test peer '%s' with URI %s and quality %u to dll \n", GNUNET_h2s (&hostlist4->peer.hashPubKey) , hostlist4->hostlist_uri, hostlist4->quality); dll_insert (hostlist4); } +#endif /** * Method called whenever an advertisement message arrives. @@ -886,81 +907,64 @@ advertisement_handler (void *cls, struct GNUNET_TIME_Relative latency, uint32_t distance) { - if ( !learning ) - return GNUNET_NO; - - int size = ntohs (message->size); - int uri_size = size - sizeof ( struct GNUNET_HOSTLIST_ADV_Message ); - char * uri = GNUNET_malloc ( uri_size ); + size_t size; + size_t uri_size; + const struct GNUNET_MessageHeader * incoming; + const char *uri; struct GNUNET_Hostlist * hostlist; - if ( ntohs (message->type) != GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT) - return GNUNET_NO; - - const struct GNUNET_HOSTLIST_ADV_Message * incoming = (const struct GNUNET_HOSTLIST_ADV_Message *) message; - memcpy ( uri, &incoming[1], uri_size ); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Hostlist client recieved advertisement from '%s' containing URI %s\n", GNUNET_i2s (peer), uri ); - - create_dummy_entries(); - - hostlist = GNUNET_malloc ( sizeof (struct GNUNET_Hostlist) ); - - hostlist->peer = (*peer); - hostlist->hello_count = 0; - hostlist->hostlist_uri = GNUNET_malloc ( uri_size); - 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; - - if ( GNUNET_YES != dll_contains (hostlist->hostlist_uri) ) + GNUNET_assert (ntohs (message->type) == GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT); + size = ntohs (message->size); + if (size <= sizeof(struct GNUNET_MessageHeader)) { - if ( MAX_NUMBER_HOSTLISTS > dll_size ) - { - /* Entries available, add hostlist to dll */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Adding uri '%s' to dll\n", hostlist->hostlist_uri ); - dll_insert ( hostlist ); - return GNUNET_YES; - } - 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" ); - - struct GNUNET_Hostlist * lowest_quality = dll_get_lowest_quality(); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Hostlist with URI %s has the worst quality of all with value %u \n", lowest_quality->hostlist_uri, lowest_quality->quality ); - /* replacing the entry with worst quality, if quality is below initial quality value */ - if ( lowest_quality->quality < HOSTLIST_INITIAL) - { - dll_remove(lowest_quality); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "URI '%s' removed \n",lowest_quality->hostlist_uri); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "URI '%s' added %s\n", hostlist->hostlist_uri); - dll_insert ( hostlist ); - } - return GNUNET_YES; - } + GNUNET_break_op (0); + return GNUNET_SYSERR; } - else + incoming = (const struct GNUNET_MessageHeader *) message; + uri = (const char*) &incoming[1]; + uri_size = size - sizeof (struct GNUNET_MessageHeader); + if (uri [uri_size - 1] != '\0') { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Hostlist URI already in database\n"); + GNUNET_break_op (0); + return GNUNET_SYSERR; } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Hostlist client recieved advertisement from `%s' containing URI `%s'\n", + GNUNET_i2s (peer), + uri); + if (GNUNET_YES != dll_contains (uri)) + return GNUNET_OK; + hostlist = GNUNET_malloc (sizeof (struct GNUNET_Hostlist) + uri_size); + hostlist->peer = *peer; + hostlist->hostlist_uri = (const char*) &hostlist[1]; + memcpy (&hostlist[1], uri, uri_size); + hostlist->time_creation = GNUNET_TIME_absolute_get(); + hostlist->time_last_usage = GNUNET_TIME_absolute_get_zero(); + hostlist->quality = HOSTLIST_INITIAL; +#if DUMMY + create_dummy_entries(); /* FIXME: remove later... */ +#endif + GNUNET_CONTAINER_DLL_insert(dll_head, dll_tail, hostlist); + dll_size++; + + if (MAX_NUMBER_HOSTLISTS >= dll_size) + return GNUNET_OK; - /* since hostlist already existed in hashmap, object can be destroyed */ - GNUNET_free ( hostlist->hostlist_uri ); - GNUNET_free ( hostlist ); - - return GNUNET_YES; + /* No free entries available, replace existing entry */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Removing lowest quality entry\n" ); + struct GNUNET_Hostlist * lowest_quality = dll_get_lowest_quality(); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Hostlist with URI `%s' has the worst quality of all with value %llu\n", + lowest_quality->hostlist_uri, + (unsigned long long) lowest_quality->quality); + GNUNET_CONTAINER_DLL_remove (dll_head, dll_tail, lowest_quality); + dll_size--; + GNUNET_free (lowest_quality); + return GNUNET_OK; } + /** * Continuation called by the statistics code once * we go the stat. Initiates hostlist download scheduling. @@ -998,11 +1002,13 @@ process_stat (void *cls, /** * Method to load persistent hostlist file during hostlist client startup - * param c configuration to use */ -static int load_hostlist_file () +static void +load_hostlist_file () { char *filename; + char *uri; + char *emsg; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, @@ -1013,46 +1019,57 @@ static int load_hostlist_file () GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("No `%s' specified in `%s' configuration, cannot load hostlists from file.\n"), "HOSTLISTFILE", "HOSTLIST"); - return GNUNET_SYSERR; + return; } struct GNUNET_BIO_ReadHandle * rh = GNUNET_BIO_read_open (filename); - if ( NULL == rh) + if (NULL == rh) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - ("Could not open file %s for reading to load hostlists\n"), filename); - return GNUNET_SYSERR; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Could not open file `%s' for reading to load hostlists: %s\n"), + filename, + STRERROR (errno)); + GNUNET_free (filename); + return; } /* add code to read hostlists to file using bio */ - char *buffer = GNUNET_malloc (1000 * sizeof (char)); - /* char *token; - - while (GNUNET_OK == GNUNET_BIO_read_string (rh, NULL , &buffer, 1000) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - ("Read from file %s : %s \n"), filename, buffer); - - pch = strtok (str," ,.-"); - while (pch != NULL) + uri = NULL; + while ( (GNUNET_OK == GNUNET_BIO_read_string (rh, "url" , &uri, MAX_URL_LEN)) && +#if 0 + (GNUNET_OK == GNUNET_BIO_read_int32 (rh, ×_used)) && + (GNUNET_OK == GNUNET_BIO_read_int32 (rh, &hellos_returned)) && + (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &last_used.value)) && + (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &created.value)) && + (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &quality)) +#else + (1) +#endif +) { - printf ("%s\n",pch); - pch = strtok (NULL, " ,.-"); - } - +#if 0 + hostlist = GNUNET_malloc (...); +#endif + uri = NULL; } - */ - GNUNET_BIO_read_close ( rh , &buffer); - return GNUNET_OK; + GNUNET_free_non_null (uri); + emsg = NULL; + GNUNET_BIO_read_close (rh, &emsg); + if (emsg != NULL) + GNUNET_free (emsg); + GNUNET_free (filename); } + /** * Method to load persistent hostlist file during hostlist client shutdown - * param c configuration to use */ -static int save_hostlist_file () +static void save_hostlist_file () { char *filename; + struct GNUNET_Hostlist *pos; + struct GNUNET_BIO_WriteHandle * wh; + int ok; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, @@ -1063,71 +1080,48 @@ static int save_hostlist_file () GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("No `%s' specified in `%s' configuration, cannot save hostlists to file.\n"), "HOSTLISTFILE", "HOSTLIST"); - return GNUNET_SYSERR; + return; } - - struct GNUNET_BIO_WriteHandle * wh = GNUNET_BIO_write_open (filename); + wh = GNUNET_BIO_write_open (filename); if ( NULL == wh) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - ("Could not open file %s for writing to save hostlists\n"), - filename); - return GNUNET_SYSERR; + _("Could not open file `%s' for writing to save hostlists: %s\n"), + filename, + STRERROR (errno)); + return; } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Writing hostlist URIs to `%s'\n"), + filename); /* add code to write hostlists to file using bio */ - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Writing hostlist to disk\n"); - struct GNUNET_Hostlist * actual = dll_head; - struct GNUNET_Hostlist * next; - char * content = GNUNET_malloc(1000 * sizeof (char)); - char * buffer = GNUNET_malloc(1000 * sizeof (char)); - - actual = dll_head; - while ( GNUNET_YES) - { - /* serialize content */ - /* uri;hello_count;quality; */ - strcpy(content,actual->hostlist_uri); - strcat(content,";"); - sprintf(buffer, "%lu", actual->hello_count); - strcat(content,buffer); - strcat(content,";"); - sprintf(buffer, "%llu", (long long unsigned int) actual->quality); - strcat(content,buffer); - strcat(content,";"); - sprintf(buffer, "%llu", (long long unsigned int) actual->time_creation.value); - strcat(content,buffer); - strcat(content,";"); - sprintf(buffer, "%llu", (long long unsigned int) actual->time_last_usage.value); - strcat(content,buffer); - strcat(content,";"); - sprintf(buffer, "%lu", actual->times_used); - strcat(content,buffer); - strcat(content,";"); - - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - ("Content to write: %s\n"), - content); - - GNUNET_BIO_write_string ( wh, content ); - - - if (actual == dll_tail) break; - next = actual->next; - GNUNET_free (actual->hostlist_uri); - GNUNET_free (actual); - actual = next; - } - GNUNET_free (actual->hostlist_uri); - GNUNET_free (actual); - GNUNET_free (content); - + ok = GNUNET_YES; + while (NULL != (pos = dll_head)) + { + GNUNET_CONTAINER_DLL_remove (dll_head, dll_tail, pos); + dll_size--; + if (GNUNET_YES == ok) + { + if ( (GNUNET_OK != + GNUNET_BIO_write_string (wh, pos->hostlist_uri)) || + (GNUNET_OK != + GNUNET_BIO_write_int32 (wh, pos->times_used)) || + (0) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Error writing hostlist URIs to file `%s'\n"), + filename); + ok = GNUNET_NO; + } + } + GNUNET_free (pos); + } if ( GNUNET_OK != GNUNET_BIO_write_close ( wh ) ) GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - ("Error while closing file %s\n"), - filename); - return GNUNET_OK; + _("Error writing hostlist URIs to file `%s'\n"), + filename); + GNUNET_free (filename); } /** @@ -1164,9 +1158,10 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c, proxy = NULL; *ch = &connect_handler; *dh = &disconnect_handler; - *msgh = &advertisement_handler; - - learning = learn; + if (learn) + *msgh = &advertisement_handler; + else + *msgh = NULL; dll_head = NULL; dll_tail = NULL; load_hostlist_file (); diff --git a/src/hostlist/hostlist-client.h b/src/hostlist/hostlist-client.h index 37fc55c19..1393df8f1 100644 --- a/src/hostlist/hostlist-client.h +++ b/src/hostlist/hostlist-client.h @@ -42,48 +42,6 @@ #define HOSTLIST_FAILED_DOWNLOAD 100 #define HOSTLIST_SUCCESSFUL_DOWNLOAD 100 -/* - * a single hostlist obtained by hostlist advertisements - */ -struct GNUNET_Hostlist -{ - struct GNUNET_Hostlist * prev; - struct GNUNET_Hostlist * next; - /* - * 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; -}; - /** * Start downloading hostlists from hostlist servers as necessary. diff --git a/src/hostlist/hostlist-server.c b/src/hostlist/hostlist-server.c index c04e99c42..e9a72d42b 100644 --- a/src/hostlist/hostlist-server.c +++ b/src/hostlist/hostlist-server.c @@ -109,15 +109,18 @@ struct HostSet */ static int advertising; -/* +/** * How many times was the hostlist advertised? */ -static uint64_t hostlist_adv_count = 0; +static uint64_t hostlist_adv_count; -/* +/* FIXME: define once... */ +#define MAX_URL_LEN 1000 + +/** * Buffer for the hostlist address */ -char hostlist_uri[255]; +static char * hostlist_uri; /** @@ -373,6 +376,7 @@ access_handler_callback (void *cls, return MHD_queue_response (connection, MHD_HTTP_OK, response); } + /** * Handler called by core when core is ready to transmit message * @param cls closure @@ -384,139 +388,35 @@ adv_transmit_ready ( void *cls, size_t size, void *buf) { size_t transmission_size; size_t uri_size; /* Including \0 termination! */ - uri_size = strlen ( hostlist_uri ) + 1; - - struct GNUNET_HOSTLIST_ADV_Message * adv_message; - adv_message = GNUNET_malloc ( sizeof(struct GNUNET_HOSTLIST_ADV_Message) + uri_size); - if ( NULL == adv_message) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, - "Could not allocate memory for the message"); - return GNUNET_NO; - } - transmission_size = sizeof (struct GNUNET_HOSTLIST_ADV_Message) + uri_size; - - adv_message->header.type = htons (GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT); - adv_message->header.size = htons (transmission_size); - memcpy(&adv_message[1],hostlist_uri,uri_size); + struct GNUNET_MessageHeader header; + char *cbuf; if (buf == NULL) { - GNUNET_log ( GNUNET_ERROR_TYPE_DEBUG, "Transmission failed, buffer invalid!\n" ); + GNUNET_log ( GNUNET_ERROR_TYPE_DEBUG, + "Transmission failed, buffer invalid!\n" ); return 0; } - - if ( size >= transmission_size ) - { - memcpy ( buf, adv_message, transmission_size ); - GNUNET_log ( GNUNET_ERROR_TYPE_DEBUG, "Sent advertisement message: Copied %d bytes into buffer!\n", transmission_size); - GNUNET_free ( adv_message ); - return transmission_size; - } - + uri_size = strlen ( hostlist_uri ) + 1; + transmission_size = sizeof (struct GNUNET_MessageHeader) + uri_size; + header.type = htons (GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT); + header.size = htons (transmission_size); + GNUNET_assert (size >= transmission_size); + memcpy (buf, &header, sizeof (struct GNUNET_MessageHeader)); + cbuf = buf; + memcpy (&cbuf[sizeof (struct GNUNET_MessageHeader)], + hostlist_uri, uri_size); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sent advertisement message: Copied %u bytes into buffer!\n", + (unsigned int) transmission_size); hostlist_adv_count++; GNUNET_STATISTICS_set (stats, gettext_noop("# hostlist advertisements send"), hostlist_adv_count, GNUNET_YES); - - GNUNET_free (adv_message ); - return size; + return transmission_size; } -/** - * Method that asks core service to transmit the message to the peer - * @param peer peer to transmit message to - * @param size size of the message - */ -static size_t -adv_transmit_message ( const struct GNUNET_PeerIdentity * peer, size_t size ) -{ - /* transmit message to peer */ - if ( NULL == core) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Not connected to core, unable to send advertisement message\n")); - return GNUNET_NO; - } - - struct GNUNET_TIME_Relative timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, GNUNET_ADV_TIMEOUT); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Asked core to transmit advertisement message with a size of %u bytes\n"), size); - struct GNUNET_CORE_TransmitHandle * th; - th = GNUNET_CORE_notify_transmit_ready (core, - 0, - timeout, - peer, - size, - &adv_transmit_ready, NULL); - if ( NULL == th ) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Advertisement message could not be queued by core\n")); - return GNUNET_NO; - - return GNUNET_YES; -} - -/** - * Method that assembles our hostlist advertisement message - * @param peer peer to send the hostlist advertisement - */ -static size_t -adv_create_message ( const struct GNUNET_PeerIdentity * peer ) - -{ - size_t length = 0; - size_t size = 0; - unsigned long long port; - - char *uri; - char hostname[GNUNET_OS_get_hostname_max_length() + 1]; - char *protocol = "http://"; - char *port_s = GNUNET_malloc(6 * sizeof(char)); - - if (0 != gethostname (hostname, sizeof (hostname) - 1)) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, - "Could not get system's hostname, unable to create advertisement message"); - return GNUNET_NO; - } - if (-1 == GNUNET_CONFIGURATION_get_value_number (cfg, - "HOSTLIST", - "HTTPPORT", - &port)) - return GNUNET_SYSERR; - - sprintf(port_s, "%llu", port); - length = strlen(hostname)+strlen(protocol)+strlen(port_s)+2; - size = (length+1) * sizeof (char); - uri = GNUNET_malloc(size); - uri = strcpy(uri, protocol); - uri = strcat(uri, hostname); - uri = strcat(uri, ":"); - uri = strcat(uri, port_s); - uri = strcat(uri, "/"); - if ( length < 255); - strcpy(hostlist_uri,uri); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Address to obtain hostlist: %s\n", hostlist_uri); - - if ( ( size + sizeof( struct GNUNET_HOSTLIST_ADV_Message )) > GNUNET_SERVER_MAX_MESSAGE_SIZE) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, - "Advertisement message is bigger than GNUNET allows"); - return GNUNET_NO; - } - - /* Request core to transmit message to peer */ - size = size + sizeof ( struct GNUNET_HOSTLIST_ADV_Message ); - adv_transmit_message(peer, size); - - GNUNET_free ( port_s ); - GNUNET_free ( uri ); - - return GNUNET_OK; -} /** * Method called whenever a given peer connects. @@ -533,18 +433,37 @@ connect_handler (void *cls, struct GNUNET_TIME_Relative latency, uint32_t distance) { + size_t size; + if ( !advertising ) return; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "A new peer connected to the server, preparing to send hostlist advertisement\n"); - /* create a new advertisement message */ - if ( (GNUNET_OK != adv_create_message(peer))) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _(" GNUNET_OK Could not create a hostlist advertisement message, impossible to advertise hostlist\n")); + if (hostlist_uri == NULL) return; - } + size = strlen (hostlist_uri) + 1; + if (size + sizeof (struct GNUNET_MessageHeader) > GNUNET_SERVER_MAX_MESSAGE_SIZE) + { + GNUNET_break (0); + return; + } + size += sizeof (struct GNUNET_MessageHeader); + if (NULL == core) + { + GNUNET_break (0); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Asked core to transmit advertisement message with a size of %u bytes\n", + size); + if (NULL == GNUNET_CORE_notify_transmit_ready (core, + 0, + GNUNET_ADV_TIMEOUT, + peer, + size, + &adv_transmit_ready, NULL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Advertisement message could not be queued by core\n")); + } } @@ -559,7 +478,7 @@ disconnect_handler (void *cls, const struct GNUNET_PeerIdentity * peer) { - + /* nothing to do */ } @@ -570,6 +489,7 @@ disconnect_handler (void *cls, static GNUNET_SCHEDULER_TaskIdentifier prepare_daemon (struct MHD_Daemon *daemon_handle); + /** * Call MHD to process pending requests and then go back * and schedule the next run. @@ -666,6 +586,8 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, int advertise) { unsigned long long port; + char *hostname; + size_t size; advertising = advertise; if ( !advertising ) @@ -685,6 +607,26 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Hostlist service starts on port %llu\n"), port); + hostname = GNUNET_RESOLVER_local_hostname_get (); + if (NULL != hostname) + { + size = strlen (hostname); + if (size + 15 > MAX_URL_LEN) + { + GNUNET_break (0); + } + else + { + GNUNET_asprintf (&hostlist_uri, + "http://%s:%u/", + hostname, + (unsigned int) port); + GNUNET_free (hostname); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Address to obtain hostlist: `%s'\n"), + hostlist_uri); + } + } daemon_handle_v6 = MHD_start_daemon (MHD_USE_IPv6 #if DEBUG_HOSTLIST_SERVER | MHD_USE_DEBUG @@ -725,7 +667,7 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, return GNUNET_SYSERR; } - core=co; + core = co; *server_ch = &connect_handler; *server_dh = &disconnect_handler; diff --git a/src/hostlist/hostlist-server.h b/src/hostlist/hostlist-server.h index cffcac05f..f704f890d 100644 --- a/src/hostlist/hostlist-server.h +++ b/src/hostlist/hostlist-server.h @@ -31,7 +31,7 @@ #include "gnunet_statistics_service.h" #include "gnunet_util_lib.h" -#define GNUNET_ADV_TIMEOUT 2500 +#define GNUNET_ADV_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) /** * Start server offering our hostlist. -- 2.25.1