X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fhostlist%2Fhostlist-server.c;h=95272a555697f28a9b4c247a7340abc36ea572a6;hb=11489754ee4b080b31dc68471e3dc3c7ae2885ce;hp=37fb4a4e1c185044224c8b574199ff1c53d6b2de;hpb=db3d5a7a998d816be1810967a74454b45f830f1c;p=oweals%2Fgnunet.git diff --git a/src/hostlist/hostlist-server.c b/src/hostlist/hostlist-server.c index 37fb4a4e1..95272a555 100644 --- a/src/hostlist/hostlist-server.c +++ b/src/hostlist/hostlist-server.c @@ -4,7 +4,7 @@ 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 2, or (at your + 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 @@ -34,11 +34,6 @@ #define DEBUG_HOSTLIST_SERVER GNUNET_NO -/** - * How often should we recalculate our response to hostlist requests? - */ -#define RESPONSE_UPDATE_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) - /** * Handle to the HTTP server as provided by libmicrohttpd for IPv6. */ @@ -54,11 +49,6 @@ static struct MHD_Daemon *daemon_handle_v4; */ static const struct GNUNET_CONFIGURATION_Handle *cfg; -/** - * Our scheduler. - */ -static struct GNUNET_SCHEDULER_Handle *sched; - /** * For keeping statistics. */ @@ -67,7 +57,12 @@ static struct GNUNET_STATISTICS_Handle *stats; /** * Handle to the core service (NULL until we've connected to it). */ -struct GNUNET_CORE_Handle *core; +static struct GNUNET_CORE_Handle *core; + +/** + * Handle to the peerinfo notify service (NULL until we've connected to it). + */ +static struct GNUNET_PEERINFO_NotifyContext *notify; /** * Our primary task for IPv4. @@ -79,11 +74,6 @@ static GNUNET_SCHEDULER_TaskIdentifier hostlist_task_v4; */ static GNUNET_SCHEDULER_TaskIdentifier hostlist_task_v6; -/** - * Task that updates our HTTP response. - */ -static GNUNET_SCHEDULER_TaskIdentifier response_task; - /** * Our canonical response. */ @@ -114,33 +104,18 @@ struct HostSet */ static int advertising; -/** - * How many times was the hostlist advertised? - */ -static uint64_t hostlist_adv_count; - /** * Buffer for the hostlist address */ static char * hostlist_uri; -/** - * Task that will produce a new response object. - */ -static void -update_response (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc); - - /** * Function that assembles our response. */ static void finish_response (struct HostSet *results) { - struct GNUNET_TIME_Relative freq; - if (response != NULL) MHD_destroy_response (response); #if DEBUG_HOSTLIST_SERVER @@ -150,24 +125,12 @@ finish_response (struct HostSet *results) #endif response = MHD_create_response_from_data (results->size, results->data, MHD_YES, MHD_NO); - if ( (daemon_handle_v4 != NULL) || - (daemon_handle_v6 != NULL) ) - { - freq = RESPONSE_UPDATE_FREQUENCY; - if (results->size == 0) - freq = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 250); - /* schedule next update of the response */ - response_task = GNUNET_SCHEDULER_add_delayed (sched, - freq, - &update_response, - NULL); - } - else - { - /* already past shutdown */ - MHD_destroy_response (response); - response = NULL; - } + if ( (daemon_handle_v4 == NULL) && + (daemon_handle_v6 == NULL) ) + { + MHD_destroy_response (response); + response = NULL; + } GNUNET_STATISTICS_set (stats, gettext_noop("bytes in hostlist"), results->size, @@ -190,11 +153,12 @@ static int check_has_addr (void *cls, const char *tname, struct GNUNET_TIME_Absolute expiration, - const void *addr, size_t addrlen) + const void *addr, + uint16_t addrlen) { int *arg = cls; - if (GNUNET_TIME_absolute_get_remaining (expiration).value == 0) + if (GNUNET_TIME_absolute_get_remaining (expiration).rel_value == 0) { GNUNET_STATISTICS_update (stats, gettext_noop("expired addresses encountered"), @@ -214,8 +178,7 @@ check_has_addr (void *cls, static void host_processor (void *cls, const struct GNUNET_PeerIdentity * peer, - const struct GNUNET_HELLO_Message *hello, - uint32_t trust) + const struct GNUNET_HELLO_Message *hello) { struct HostSet *results = cls; size_t old; @@ -255,7 +218,7 @@ host_processor (void *cls, "HELLO", GNUNET_i2s (peer)); #endif - if (old + s >= GNUNET_MAX_MALLOC_CHECKED) + if ( (old + s >= GNUNET_MAX_MALLOC_CHECKED) || (old + s >= MAX_BYTES_PER_HOSTLISTS) ) { GNUNET_STATISTICS_update (stats, gettext_noop("bytes not included in hostlist (size limit)"), @@ -263,10 +226,12 @@ host_processor (void *cls, GNUNET_NO); return; /* too large, skip! */ } +#if DEBUG_HOSTLIST_SERVER GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Adding peer `%s' to hostlist (%u bytes)\n", GNUNET_i2s (peer), (unsigned int) s); +#endif GNUNET_array_grow (results->data, results->size, old + s); @@ -274,26 +239,6 @@ host_processor (void *cls, } -/** - * Task that will produce a new response object. - */ -static void -update_response (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct HostSet *results; - - response_task = GNUNET_SCHEDULER_NO_TASK; - results = GNUNET_malloc(sizeof(struct HostSet)); - GNUNET_assert (peerinfo != NULL); - pitr = GNUNET_PEERINFO_iterate (peerinfo, - NULL, - 0, - GNUNET_TIME_UNIT_MINUTES, - &host_processor, - results); -} - /** * Hostlist access policy (very permissive, allows everything). @@ -389,6 +334,8 @@ access_handler_callback (void *cls, static size_t adv_transmit_ready ( void *cls, size_t size, void *buf) { + static uint64_t hostlist_adv_count; + size_t transmission_size; size_t uri_size; /* Including \0 termination! */ struct GNUNET_MessageHeader header; @@ -413,10 +360,13 @@ adv_transmit_ready ( void *cls, size_t size, void *buf) "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_NO); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + " # Sent advertisement message: %u\n", + hostlist_adv_count); + GNUNET_STATISTICS_update (stats, + gettext_noop("# hostlist advertisements send"), + 1, + GNUNET_NO); return transmission_size; } @@ -426,15 +376,13 @@ adv_transmit_ready ( void *cls, size_t size, void *buf) * * @param cls closure * @param peer peer identity this notification is about - * @param latency reported latency of the connection with 'other' - * @param distance reported distance (DV) to 'other' + * @param atsi performance data */ static void connect_handler (void *cls, const struct GNUNET_PeerIdentity * peer, - struct GNUNET_TIME_Relative latency, - uint32_t distance) + const struct GNUNET_TRANSPORT_ATS_Information *atsi) { size_t size; @@ -443,7 +391,7 @@ connect_handler (void *cls, if (hostlist_uri == NULL) return; size = strlen (hostlist_uri) + 1; - if (size + sizeof (struct GNUNET_MessageHeader) > GNUNET_SERVER_MAX_MESSAGE_SIZE) + if (size + sizeof (struct GNUNET_MessageHeader) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) { GNUNET_break (0); return; @@ -455,8 +403,8 @@ connect_handler (void *cls, return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Asked core to transmit advertisement message with a size of %u bytes\n", - size); + "Asked core to transmit advertisement message with a size of %u bytes to peer `%s'\n", + size,GNUNET_i2s(peer)); if (NULL == GNUNET_CORE_notify_transmit_ready (core, 0, GNUNET_ADV_TIMEOUT, @@ -484,6 +432,32 @@ disconnect_handler (void *cls, /* nothing to do */ } +/** + * PEERINFO calls this function to let us know about a possible peer + * that we might want to connect to. + * + * @param cls closure (not used) + * @param peer potential peer to connect to + * @param hello HELLO for this peer (or NULL) + */ +static void +process_notify (void *cls, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HELLO_Message *hello) +{ + struct HostSet *results; +#if DEBUG_HOSTLIST_SERVER + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peerinfo is notifying us to rebuild our hostlist\n"); +#endif + results = GNUNET_malloc(sizeof(struct HostSet)); + GNUNET_assert (peerinfo != NULL); + pitr = GNUNET_PEERINFO_iterate (peerinfo, + NULL, + GNUNET_TIME_UNIT_MINUTES, + &host_processor, + results); +} /** * Function that queries MHD's select sets and @@ -552,14 +526,13 @@ prepare_daemon (struct MHD_Daemon *daemon_handle) &max)); haveto = MHD_get_timeout (daemon_handle, &timeout); if (haveto == MHD_YES) - tv.value = (uint64_t) timeout; + tv.rel_value = (uint64_t) timeout; else tv = GNUNET_TIME_UNIT_FOREVER_REL; - GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max); - GNUNET_NETWORK_fdset_copy_native (wws, &ws, max); - GNUNET_NETWORK_fdset_copy_native (wes, &es, max); - ret = GNUNET_SCHEDULER_add_select (sched, - GNUNET_SCHEDULER_PRIORITY_HIGH, + GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1); + GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1); + GNUNET_NETWORK_fdset_copy_native (wes, &es, max + 1); + ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, GNUNET_SCHEDULER_NO_TASK, tv, wrs, @@ -581,7 +554,6 @@ prepare_daemon (struct MHD_Daemon *daemon_handle) */ int GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, - struct GNUNET_SCHEDULER_Handle *s, struct GNUNET_STATISTICS_Handle *st, struct GNUNET_CORE_Handle *co, GNUNET_CORE_ConnectEventHandler *server_ch, @@ -599,25 +571,38 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, else GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Advertising enabled on this hostlist server\n"); - sched = s; cfg = c; stats = st; - peerinfo = GNUNET_PEERINFO_connect (sched, cfg); + peerinfo = GNUNET_PEERINFO_connect (cfg); if (peerinfo == NULL) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not access PEERINFO service. Exiting.\n")); return GNUNET_SYSERR; } - if (-1 == GNUNET_CONFIGURATION_get_value_number (cfg, - "HOSTLIST", - "HTTPPORT", - &port)) + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, + "HOSTLIST", + "HTTPPORT", + &port)) return GNUNET_SYSERR; + if ( (port == 0) || + (port > UINT16_MAX) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Invalid port number %llu. Exiting.\n"), + port); + return GNUNET_SYSERR; + } + + if ( GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg, + "HOSTLIST", + "EXTERNAL_DNS_NAME", + &hostname)) + hostname = GNUNET_RESOLVER_local_fqdn_get (); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Hostlist service starts on port %llu\n"), - port); - hostname = GNUNET_RESOLVER_local_fqdn_get (); + _("Hostlist service starts on %s:%llu\n"), + hostname, port); if (NULL != hostname) { size = strlen (hostname); @@ -686,9 +671,9 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, hostlist_task_v4 = prepare_daemon (daemon_handle_v4); if (daemon_handle_v6 != NULL) hostlist_task_v6 = prepare_daemon (daemon_handle_v6); - response_task = GNUNET_SCHEDULER_add_now (sched, - &update_response, - NULL); + + notify = GNUNET_PEERINFO_notify ( cfg, process_notify, NULL); + return GNUNET_OK; } @@ -702,14 +687,19 @@ GNUNET_HOSTLIST_server_stop () GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist server shutdown\n"); #endif + if (NULL != notify) + { + GNUNET_PEERINFO_notify_cancel (notify); + notify = NULL; + } if (GNUNET_SCHEDULER_NO_TASK != hostlist_task_v6) { - GNUNET_SCHEDULER_cancel (sched, hostlist_task_v6); + GNUNET_SCHEDULER_cancel (hostlist_task_v6); hostlist_task_v6 = GNUNET_SCHEDULER_NO_TASK; } if (GNUNET_SCHEDULER_NO_TASK != hostlist_task_v4) { - GNUNET_SCHEDULER_cancel (sched, hostlist_task_v4); + GNUNET_SCHEDULER_cancel (hostlist_task_v4); hostlist_task_v4 = GNUNET_SCHEDULER_NO_TASK; } if (pitr != NULL) @@ -717,11 +707,6 @@ GNUNET_HOSTLIST_server_stop () GNUNET_PEERINFO_iterate_cancel (pitr); pitr = NULL; } - if (GNUNET_SCHEDULER_NO_TASK != response_task) - { - GNUNET_SCHEDULER_cancel (sched, response_task); - response_task = GNUNET_SCHEDULER_NO_TASK; - } if (NULL != daemon_handle_v4) { MHD_stop_daemon (daemon_handle_v4); @@ -742,6 +727,9 @@ GNUNET_HOSTLIST_server_stop () GNUNET_PEERINFO_disconnect (peerinfo); peerinfo = NULL; } + cfg = NULL; + stats = NULL; + core = NULL; } /* end of hostlist-server.c */