X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fhostlist%2Fgnunet-daemon-hostlist.c;h=bbc0d7e088ec2d8925aa7bf811dea6488c92cf10;hb=45cfb14b403565c06bd08c44a351d969c82f0ce2;hp=e2e64a7173f1ad0579e4213772b3c49318b5abfc;hpb=184240c9c28f784bbdea72742e0a3ce3e3ee4652;p=oweals%2Fgnunet.git diff --git a/src/hostlist/gnunet-daemon-hostlist.c b/src/hostlist/gnunet-daemon-hostlist.c index e2e64a717..bbc0d7e08 100644 --- a/src/hostlist/gnunet-daemon-hostlist.c +++ b/src/hostlist/gnunet-daemon-hostlist.c @@ -27,7 +27,6 @@ #include #include "platform.h" #include "hostlist-client.h" -#include "hostlist-server.h" #include "gnunet_core_service.h" #include "gnunet_getopt_lib.h" #include "gnunet_protocols.h" @@ -37,12 +36,32 @@ #include "gnunet_time_lib.h" #include "gnunet_util_lib.h" +#if HAVE_MHD + +#include "hostlist-server.h" /** * Set if we are allowed to advertise our hostlist to others. */ static int advertising; +/** + * Set if the user wants us to run a hostlist server. + */ +static int provide_hostlist; + +/** + * Handle to hostlist server's connect handler + */ +static GNUNET_CORE_ConnectEventHandler server_ch = NULL; + +/** + * Handle to hostlist server's disconnect handler + */ +static GNUNET_CORE_DisconnectEventHandler server_dh = NULL; + +#endif + /** * Set if we are allowed to learn about peers by accessing * hostlist servers. @@ -56,34 +75,78 @@ static int bootstrapping; static int learning; /** - * Set if the user wants us to run a hostlist server. + * Statistics handle. */ -static int provide_hostlist; +static struct GNUNET_STATISTICS_Handle *stats; /** - * Statistics handle. + * Handle to the core service (NULL until we've connected to it). */ -static struct GNUNET_STATISTICS_Handle *stats; +static struct GNUNET_CORE_Handle *core; + +/** + * Handle to the hostlist client's advertisement handler + */ +static GNUNET_CORE_MessageCallback client_adv_handler = NULL; + +/** + * Handle to hostlist client's connect handler + */ +static GNUNET_CORE_ConnectEventHandler client_ch = NULL; + +/** + * Handle to hostlist client's disconnect handler + */ +static GNUNET_CORE_DisconnectEventHandler client_dh = NULL; /** * gnunet-daemon-hostlist command line options. */ static struct GNUNET_GETOPT_CommandLineOption options[] = { +#if HAVE_MHD { 'a', "advertise", NULL, gettext_noop ("advertise our hostlist to other peers"), GNUNET_NO, &GNUNET_GETOPT_set_one, &advertising }, +#endif { 'b', "bootstrap", NULL, gettext_noop ("bootstrap using hostlists (it is highly recommended that you always use this option)"), GNUNET_NO, &GNUNET_GETOPT_set_one, &bootstrapping }, { 'e', "enable-learning", NULL, gettext_noop ("enable learning about hostlist servers from other peers"), GNUNET_NO, &GNUNET_GETOPT_set_one, &learning}, +#if HAVE_MHD { 'p', "provide-hostlist", NULL, gettext_noop ("provide a hostlist server"), GNUNET_NO, &GNUNET_GETOPT_set_one, &provide_hostlist}, +#endif GNUNET_GETOPT_OPTION_END }; +/** + * 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; +}; + static void core_init (void *cls, @@ -94,13 +157,70 @@ core_init (void *cls, GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded * publicKey) { - if (advertising && (NULL != server)) - { - /* TODO: provide "server" to 'hostlist' module */ - } + /* Nothing to do here */ +} + +/** + * Core handler for p2p hostlist advertisements + */ +static int advertisement_handler (void *cls, + const struct GNUNET_PeerIdentity * peer, + const struct GNUNET_MessageHeader * message, + struct GNUNET_TIME_Relative latency, + uint32_t distance) +{ + 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 + * + * @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' + */ +static void +connect_handler (void *cls, + const struct + GNUNET_PeerIdentity * peer, + struct GNUNET_TIME_Relative latency, + uint32_t distance) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "A new peer connected, notifying client and server\n"); + if ( NULL != client_ch) + (*client_ch) (cls, peer, latency, distance); +#if HAVE_MHD + if ( NULL != server_ch) + (*server_ch) (cls, peer, latency, distance); +#endif +} + +/** + * Method called whenever a given peer disconnects. Wrapper to call both client's and server's functions + * + * @param cls closure + * @param peer peer identity this notification is about + */ +static void +disconnect_handler (void *cls, + const struct + GNUNET_PeerIdentity * peer) +{ + + /* call hostlist client disconnect handler*/ + if ( NULL != client_dh) + (*client_dh) (cls, peer); +#if HAVE_MHD + /* call hostlist server disconnect handler*/ + if ( NULL != server_dh) + (*server_dh) (cls, peer); +#endif +} + /** * Last task run during shutdown. Disconnects us from * the other services. @@ -108,13 +228,47 @@ core_init (void *cls, static void cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Hostlist daemon is shutting down\n"); + if (core != NULL) + { + GNUNET_CORE_disconnect (core); + core = NULL; + } + if (bootstrapping) + { + GNUNET_HOSTLIST_client_stop (); + } +#if HAVE_MHD + if (provide_hostlist) + { + GNUNET_HOSTLIST_server_stop (); + } +#endif if (stats != NULL) { - GNUNET_STATISTICS_destroy (stats); + GNUNET_STATISTICS_destroy (stats, + GNUNET_NO); stats = NULL; } } +/** + * List of handlers if we are learning. + */ +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. @@ -130,53 +284,57 @@ run (void *cls, struct GNUNET_SCHEDULER_Handle * sched, char *const *args, const char *cfgfile, - struct GNUNET_CONFIGURATION_Handle * cfg) + const struct GNUNET_CONFIGURATION_Handle * cfg) { - GNUNET_CORE_ClientEventHandler ch = NULL; - GNUNET_CORE_ClientEventHandler dh = NULL; - struct GNUNET_CORE_MessageHandler handlers[] = - { - { NULL, 0, 0 } - }; - if ( (! bootstrapping) && - (! learning) && - (! provide_hostlist) ) + (! learning) +#if HAVE_MHD + && (! provide_hostlist) +#endif + ) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("None of the functions for the hostlist daemon were enabled. I have no reason to run!\n")); return; } + + + stats = GNUNET_STATISTICS_create (sched, "hostlist", cfg); - if (learning) - { - // FIXME! - // (register handler with core for hostlist ads) - } + + core = GNUNET_CORE_connect (sched, cfg, + GNUNET_TIME_UNIT_FOREVER_REL, + NULL, + &core_init, + &connect_handler, &disconnect_handler, + NULL, GNUNET_NO, + NULL, GNUNET_NO, + learning? learn_handlers : no_learn_handlers); + if (bootstrapping) { GNUNET_HOSTLIST_client_start (cfg, sched, stats, - &ch, &dh); + &client_ch, &client_dh, &client_adv_handler, learning); } + + #if HAVE_MHD if (provide_hostlist) { - GNUNET_HOSTLIST_server_start (cfg, sched, stats); + GNUNET_HOSTLIST_server_start (cfg, sched, stats, core, &server_ch, &server_dh, advertising ); } - GNUNET_CORE_connect (sched, cfg, - GNUNET_TIME_UNIT_FOREVER_REL, - NULL, - &core_init, - ch, dh, - NULL, - NULL, GNUNET_NO, - NULL, GNUNET_NO, - handlers); +#endif GNUNET_SCHEDULER_add_delayed (sched, - GNUNET_YES, - GNUNET_SCHEDULER_PRIORITY_IDLE, - GNUNET_SCHEDULER_NO_PREREQUISITE_TASK, GNUNET_TIME_UNIT_FOREVER_REL, &cleaning_task, NULL); + + if (NULL == core) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to connect to `%s' service.\n"), + "core"); + GNUNET_SCHEDULER_shutdown (sched); + return; + } } @@ -191,6 +349,7 @@ int main (int argc, char *const *argv) { int ret; + GNUNET_log_setup ("hostlist","DEBUG",NULL); ret = (GNUNET_OK == GNUNET_PROGRAM_run (argc, @@ -199,6 +358,7 @@ main (int argc, char *const *argv) _("GNUnet hostlist server and client"), options, &run, NULL)) ? 0 : 1; + return ret; }