From: Christian Grothoff Date: Fri, 24 Jun 2016 13:55:46 +0000 (+0000) Subject: converting peerinfo-notify to new MQ ApI X-Git-Tag: initial-import-from-subversion-38251~718 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=87cc7b0d43e19da65f8947950cfbcfbea95e265e;p=oweals%2Fgnunet.git converting peerinfo-notify to new MQ ApI --- diff --git a/src/include/gnunet_peerinfo_service.h b/src/include/gnunet_peerinfo_service.h index cdf7b26bd..44df483a0 100644 --- a/src/include/gnunet_peerinfo_service.h +++ b/src/include/gnunet_peerinfo_service.h @@ -172,7 +172,7 @@ struct GNUNET_PEERINFO_NotifyContext; * changes. Initially calls the given function for all known * peers and then only signals changes. * - * If include_friend_only is set to GNUNET_YES peerinfo will include HELLO + * If @a include_friend_only is set to #GNUNET_YES peerinfo will include HELLO * messages which are intended for friend to friend mode and which do not * have to be gossiped. Otherwise these messages are skipped. * diff --git a/src/peerinfo/peerinfo_api_notify.c b/src/peerinfo/peerinfo_api_notify.c index 2a80c6c1a..479d4bd86 100644 --- a/src/peerinfo/peerinfo_api_notify.c +++ b/src/peerinfo/peerinfo_api_notify.c @@ -40,7 +40,7 @@ struct GNUNET_PEERINFO_NotifyContext /** * Our connection to the PEERINFO service. */ - struct GNUNET_CLIENT_Connection *client; + struct GNUNET_MQ_Handle *mq; /** * Function to call with information. @@ -48,16 +48,10 @@ struct GNUNET_PEERINFO_NotifyContext GNUNET_PEERINFO_Processor callback; /** - * Closure for callback. + * Closure for @e callback. */ void *callback_cls; - /** - * Handle to our initial request for message transmission to - * the peerinfo service. - */ - struct GNUNET_CLIENT_TransmitHandle *init; - /** * Configuration. */ @@ -71,171 +65,144 @@ struct GNUNET_PEERINFO_NotifyContext /** * Include friend only HELLOs in callbacks */ - int include_friend_only; }; /** - * Send a request to the peerinfo service to start being - * notified about all changes to peer information. + * Task to re-try connecting to peerinfo. * - * @param nc our context + * @param cls the `struct GNUNET_PEERINFO_NotifyContext *` */ static void -request_notifications (struct GNUNET_PEERINFO_NotifyContext *nc); +reconnect (void *cls); /** - * Read notifications from the client handle and pass them - * to the callback. + * We encountered an error, reconnect to the service. * - * @param nc our context + * @param nc context to reconnect */ static void -receive_notifications (struct GNUNET_PEERINFO_NotifyContext *nc); +do_reconnect (struct GNUNET_PEERINFO_NotifyContext *nc) +{ + GNUNET_MQ_destroy (nc->mq); + nc->mq = NULL; + nc->task = GNUNET_SCHEDULER_add_now (&reconnect, + nc); +} /** - * Task to re-try connecting to peerinfo. + * We got a disconnect after asking regex to do the announcement. + * Retry. * - * @param cls the `struct GNUNET_PEERINFO_NotifyContext *` + * @param cls the `struct GNUNET_PEERINFO_NotifyContext` to retry + * @param error error code */ static void -reconnect (void *cls) +mq_error_handler (void *cls, + enum GNUNET_MQ_Error error) { struct GNUNET_PEERINFO_NotifyContext *nc = cls; - nc->task = NULL; - nc->client = GNUNET_CLIENT_connect ("peerinfo", nc->cfg); - if (NULL == nc->client) - { - /* ugh */ - nc->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, - &reconnect, nc); - return; - } - request_notifications (nc); + do_reconnect (nc); } /** - * Receive a peerinfo information message, process it and - * go for more. + * Check that a peerinfo information message is well-formed. * * @param cls closure - * @param msg message received, NULL on timeout or fatal error + * @param im message received + * @return #GNUNET_OK if the message is well-formed */ -static void -process_notification (void *cls, const struct GNUNET_MessageHeader *msg) +static int +check_notification (void *cls, + const struct InfoMessage *im) { - struct GNUNET_PEERINFO_NotifyContext *nc = cls; - const struct InfoMessage *im; - const struct GNUNET_HELLO_Message *hello; - uint16_t ms; + uint16_t ms = ntohs (im->header.size) - sizeof (*im); - if (msg == NULL) - { - GNUNET_CLIENT_disconnect (nc->client); - reconnect (nc); - return; - } - ms = ntohs (msg->size); - if ((ms < sizeof (struct InfoMessage)) || - (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_PEERINFO_INFO)) - { - GNUNET_break (0); - GNUNET_CLIENT_disconnect (nc->client); - nc->client = GNUNET_CLIENT_connect ("peerinfo", nc->cfg); - request_notifications (nc); - return; - } - im = (const struct InfoMessage *) msg; - hello = NULL; - if (ms > sizeof (struct InfoMessage) + sizeof (struct GNUNET_MessageHeader)) + if (ms >= sizeof (struct GNUNET_MessageHeader)) { + const struct GNUNET_HELLO_Message *hello; + hello = (const struct GNUNET_HELLO_Message *) &im[1]; - if (ms != sizeof (struct InfoMessage) + GNUNET_HELLO_size (hello)) + if (ms != GNUNET_HELLO_size (hello)) { GNUNET_break (0); - GNUNET_CLIENT_disconnect (nc->client); - nc->client = GNUNET_CLIENT_connect ("peerinfo", nc->cfg); - request_notifications (nc); - return; + return GNUNET_SYSERR; } + return GNUNET_OK; } - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Received information about peer `%s' from peerinfo database\n", - GNUNET_i2s (&im->peer)); - nc->callback (nc->callback_cls, &im->peer, hello, NULL); - receive_notifications (nc); + if (0 != ms) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; /* odd... */ } /** - * Read notifications from the client handle and pass them - * to the callback. + * Receive a peerinfo information message, process it. * - * @param nc our context + * @param cls closure + * @param im message received */ static void -receive_notifications (struct GNUNET_PEERINFO_NotifyContext *nc) -{ - GNUNET_CLIENT_receive (nc->client, &process_notification, nc, - GNUNET_TIME_UNIT_FOREVER_REL); -} - - -/** - * Transmit our init-notify request, start receiving. - * - * @param cls closure (our 'struct GNUNET_PEERINFO_NotifyContext') - * @param size number of bytes available in buf - * @param buf where the callee should write the message - * @return number of bytes written to buf - */ -static size_t -transmit_notify_request (void *cls, size_t size, void *buf) +handle_notification (void *cls, + const struct InfoMessage *im) { struct GNUNET_PEERINFO_NotifyContext *nc = cls; - struct NotifyMessage nm; + const struct GNUNET_HELLO_Message *hello; + uint16_t ms = ntohs (im->header.size) - sizeof (struct InfoMessage); - nc->init = NULL; - if (buf == NULL) - { - GNUNET_CLIENT_disconnect (nc->client); - nc->client = GNUNET_CLIENT_connect ("peerinfo", nc->cfg); - request_notifications (nc); - return 0; - } - GNUNET_assert (size >= sizeof (struct NotifyMessage)); - nm.header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY); - nm.header.size = htons (sizeof (struct NotifyMessage)); - nm.include_friend_only = htonl (nc->include_friend_only); - memcpy (buf, &nm, sizeof (struct NotifyMessage)); - receive_notifications (nc); - return sizeof (struct NotifyMessage); + if (0 == ms) + return; + hello = (const struct GNUNET_HELLO_Message *) &im[1]; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Received information about peer `%s' from peerinfo database\n", + GNUNET_i2s (&im->peer)); + nc->callback (nc->callback_cls, + &im->peer, + hello, + NULL); } /** - * Send a request to the peerinfo service to start being - * notified about all changes to peer information. + * Task to re-try connecting to peerinfo. * - * @param nc our context + * @param cls the `struct GNUNET_PEERINFO_NotifyContext *` */ static void -request_notifications (struct GNUNET_PEERINFO_NotifyContext *nc) +reconnect (void *cls) { - GNUNET_assert (NULL == nc->init); - nc->init = - GNUNET_CLIENT_notify_transmit_ready (nc->client, - sizeof (struct NotifyMessage), - GNUNET_TIME_UNIT_FOREVER_REL, - GNUNET_YES, &transmit_notify_request, - nc); + GNUNET_MQ_hd_var_size (notification, + GNUNET_MESSAGE_TYPE_PEERINFO_INFO, + struct InfoMessage); + struct GNUNET_PEERINFO_NotifyContext *nc = cls; + struct GNUNET_MQ_MessageHandler handlers[] = { + make_notification_handler (nc), + GNUNET_MQ_handler_end () + }; + struct GNUNET_MQ_Envelope *env; + struct NotifyMessage *nm; + + nc->task = NULL; + nc->mq = GNUNET_CLIENT_connecT (nc->cfg, + "peerinfo", + handlers, + &mq_error_handler, + nc); + if (NULL == nc->mq) + return; + env = GNUNET_MQ_msg (nm, + GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY); + nm->include_friend_only = htonl (nc->include_friend_only); + GNUNET_MQ_send (nc->mq, + env); } @@ -244,38 +211,37 @@ request_notifications (struct GNUNET_PEERINFO_NotifyContext *nc) * changes. Initially calls the given function for all known * peers and then only signals changes. * - * If include_friend_only is set to GNUNET_YES peerinfo will include HELLO + * If @a include_friend_only is set to #GNUNET_YES peerinfo will include HELLO * messages which are intended for friend to friend mode and which do not * have to be gossiped. Otherwise these messages are skipped. * * @param cfg configuration to use * @param include_friend_only include HELLO messages for friends only * @param callback the method to call for each peer - * @param callback_cls closure for callback + * @param callback_cls closure for @a callback * @return NULL on error */ struct GNUNET_PEERINFO_NotifyContext * GNUNET_PEERINFO_notify (const struct GNUNET_CONFIGURATION_Handle *cfg, - int include_friend_only, - GNUNET_PEERINFO_Processor callback, void *callback_cls) + int include_friend_only, + GNUNET_PEERINFO_Processor callback, + void *callback_cls) { struct GNUNET_PEERINFO_NotifyContext *nc; - struct GNUNET_CLIENT_Connection *client; - client = GNUNET_CLIENT_connect ("peerinfo", cfg); - if (client == NULL) - { - LOG (GNUNET_ERROR_TYPE_WARNING, _("Could not connect to `%s' service.\n"), - "peerinfo"); - return NULL; - } nc = GNUNET_new (struct GNUNET_PEERINFO_NotifyContext); nc->cfg = cfg; - nc->client = client; nc->callback = callback; nc->callback_cls = callback_cls; nc->include_friend_only = include_friend_only; - request_notifications (nc); + reconnect (nc); + if (NULL == nc->mq) + { + LOG (GNUNET_ERROR_TYPE_WARNING, + "Could not connect to PEERINFO service.\n"); + GNUNET_free (nc); + return NULL; + } return nc; } @@ -288,15 +254,16 @@ GNUNET_PEERINFO_notify (const struct GNUNET_CONFIGURATION_Handle *cfg, void GNUNET_PEERINFO_notify_cancel (struct GNUNET_PEERINFO_NotifyContext *nc) { - if (NULL != nc->init) + if (NULL != nc->mq) { - GNUNET_CLIENT_notify_transmit_ready_cancel (nc->init); - nc->init = NULL; + GNUNET_MQ_destroy (nc->mq); + nc->mq = NULL; } - if (NULL != nc->client) - GNUNET_CLIENT_disconnect (nc->client); if (NULL != nc->task) + { GNUNET_SCHEDULER_cancel (nc->task); + nc->task = NULL; + } GNUNET_free (nc); }