From ecae86479af22f233fec7a8c499976c0882b163f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 23 Jun 2016 17:48:40 +0000 Subject: migrate first half of regex API to MQ lib --- src/regex/Makefile.am | 4 +- src/regex/regex_api.c | 350 ----------------------------------------- src/regex/regex_api_announce.c | 186 ++++++++++++++++++++++ src/regex/regex_api_search.c | 215 +++++++++++++++++++++++++ 4 files changed, 404 insertions(+), 351 deletions(-) delete mode 100644 src/regex/regex_api.c create mode 100644 src/regex/regex_api_announce.c create mode 100644 src/regex/regex_api_search.c (limited to 'src/regex') diff --git a/src/regex/Makefile.am b/src/regex/Makefile.am index 43555cf72..6204a47d8 100644 --- a/src/regex/Makefile.am +++ b/src/regex/Makefile.am @@ -62,7 +62,9 @@ libgnunetregex_internal_a_DEPENDENCIES = \ libgnunetregex_la_SOURCES = \ - regex_api.c regex_ipc.h + regex_api_announce.c \ + regex_api_search.c \ + regex_ipc.h libgnunetregex_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la libgnunetregex_la_LDFLAGS = \ diff --git a/src/regex/regex_api.c b/src/regex/regex_api.c deleted file mode 100644 index c3be2020f..000000000 --- a/src/regex/regex_api.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - This file is part of GNUnet - Copyright (C) 2012, 2013 GNUnet e.V. - - 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 3, or (at your - option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -/** - * @file regex/regex_api.c - * @brief access regex service to advertise capabilities via regex and discover - * respective peers using matching strings - * @author Maximilian Szengel - * @author Christian Grothoff - */ -#include "platform.h" -#include "gnunet_protocols.h" -#include "gnunet_util_lib.h" -#include "gnunet_regex_service.h" -#include "regex_ipc.h" - -#define LOG(kind,...) GNUNET_log_from (kind, "regex-api",__VA_ARGS__) - -/** - * Handle to store cached data about a regex announce. - */ -struct GNUNET_REGEX_Announcement -{ - /** - * Connection to the regex service. - */ - struct GNUNET_CLIENT_Connection *client; - - /** - * Our configuration. - */ - const struct GNUNET_CONFIGURATION_Handle *cfg; - - /** - * Message we're sending to the service. - */ - struct AnnounceMessage msg; -}; - - -/** - * We got a response (!?) or disconnect after asking regex - * to do the announcement. Retry. - * - * @param cls the 'struct GNUNET_REGEX_Announcement' to retry - * @param msg NULL on disconnect - */ -static void -handle_a_reconnect (void *cls, - const struct GNUNET_MessageHeader *msg); - - -/** - * Try sending the announcement request to regex. On - * errors (i.e. regex died), try again. - * - * @param a the announcement to retry - */ -static void -retry_announcement (struct GNUNET_REGEX_Announcement *a) -{ - GNUNET_assert (NULL != a->client); - GNUNET_assert (GNUNET_OK == - GNUNET_CLIENT_transmit_and_get_response (a->client, - &a->msg.header, - GNUNET_TIME_UNIT_FOREVER_REL, - GNUNET_YES, - &handle_a_reconnect, - a)); -} - - -/** - * We got a response (!?) or disconnect after asking regex - * to do the announcement. Retry. - * - * @param cls the 'struct GNUNET_REGEX_Announcement' to retry - * @param msg NULL on disconnect - */ -static void -handle_a_reconnect (void *cls, - const struct GNUNET_MessageHeader *msg) -{ - struct GNUNET_REGEX_Announcement *a = cls; - - GNUNET_CLIENT_disconnect (a->client); - a->client = GNUNET_CLIENT_connect ("regex", a->cfg); - retry_announcement (a); -} - - -/** - * Announce the given peer under the given regular expression. - * - * @param cfg configuration to use - * @param regex Regular expression to announce. - * @param refresh_delay after what delay should the announcement be repeated? - * @param compression How many characters per edge can we squeeze? - * @return Handle to reuse o free cached resources. - * Must be freed by calling #GNUNET_REGEX_announce_cancel(). - */ -struct GNUNET_REGEX_Announcement * -GNUNET_REGEX_announce (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *regex, - struct GNUNET_TIME_Relative refresh_delay, - uint16_t compression) -{ - struct GNUNET_REGEX_Announcement *a; - size_t slen; - - slen = strlen (regex) + 1; - if (slen + sizeof (struct AnnounceMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Regex `%s' is too long!\n"), - regex); - GNUNET_break (0); - return NULL; - } - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Starting REGEX announcement %s\n", - regex); - a = GNUNET_malloc (sizeof (struct GNUNET_REGEX_Announcement) + slen); - a->cfg = cfg; - a->client = GNUNET_CLIENT_connect ("regex", cfg); - if (NULL == a->client) - { - GNUNET_free (a); - return NULL; - } - a->msg.header.type = htons (GNUNET_MESSAGE_TYPE_REGEX_ANNOUNCE); - a->msg.header.size = htons (slen + sizeof (struct AnnounceMessage)); - a->msg.compression = htons (compression); - a->msg.reserved = htons (0); - a->msg.refresh_delay = GNUNET_TIME_relative_hton (refresh_delay); - memcpy (&a[1], regex, slen); - retry_announcement (a); - return a; -} - - -/** - * Stop announcing the regex specified by the given handle. - * - * @param a handle returned by a previous GNUNET_REGEX_announce call. - */ -void -GNUNET_REGEX_announce_cancel (struct GNUNET_REGEX_Announcement *a) -{ - GNUNET_CLIENT_disconnect (a->client); - GNUNET_free (a); -} - - -/** - * Handle to store data about a regex search. - */ -struct GNUNET_REGEX_Search -{ - /** - * Connection to the regex service. - */ - struct GNUNET_CLIENT_Connection *client; - - /** - * Our configuration. - */ - const struct GNUNET_CONFIGURATION_Handle *cfg; - - /** - * Function to call with results. - */ - GNUNET_REGEX_Found callback; - - /** - * Closure for @e callback. - */ - void *callback_cls; - - /** - * Search message to transmit to the service. - */ - struct RegexSearchMessage *msg; -}; - - -/** - * We got a response or disconnect after asking regex - * to do the search. Handle it. - * - * @param cls the `struct GNUNET_REGEX_Search` to retry - * @param msg NULL on disconnect - */ -static void -handle_search_response (void *cls, - const struct GNUNET_MessageHeader *msg); - - -/** - * Try sending the search request to regex. On - * errors (i.e. regex died), try again. - * - * @param s the search to retry - */ -static void -retry_search (struct GNUNET_REGEX_Search *s) -{ - GNUNET_assert (NULL != s->client); - GNUNET_assert (GNUNET_OK == - GNUNET_CLIENT_transmit_and_get_response (s->client, - &s->msg->header, - GNUNET_TIME_UNIT_FOREVER_REL, - GNUNET_YES, - &handle_search_response, - s)); -} - - -/** - * We got a response or disconnect after asking regex - * to do the search. Handle it. - * - * @param cls the `struct GNUNET_REGEX_Search` to handle reply for - * @param msg NULL on disconnect, otherwise presumably a response - */ -static void -handle_search_response (void *cls, - const struct GNUNET_MessageHeader *msg) -{ - struct GNUNET_REGEX_Search *s = cls; - const struct ResultMessage *result; - uint16_t size; - uint16_t gpl; - uint16_t ppl; - - if (NULL == msg) - { - GNUNET_CLIENT_disconnect (s->client); - s->client = GNUNET_CLIENT_connect ("regex", s->cfg); - retry_search (s); - return; - } - size = ntohs (msg->size); - if ( (GNUNET_MESSAGE_TYPE_REGEX_RESULT == ntohs (msg->type)) && - (size >= sizeof (struct ResultMessage)) ) - { - result = (const struct ResultMessage *) msg; - gpl = ntohs (result->get_path_length); - ppl = ntohs (result->put_path_length); - if (size == (sizeof (struct ResultMessage) + - (gpl + ppl) * sizeof (struct GNUNET_PeerIdentity))) - { - const struct GNUNET_PeerIdentity *pid; - - GNUNET_CLIENT_receive (s->client, - &handle_search_response, s, - GNUNET_TIME_UNIT_FOREVER_REL); - pid = &result->id; - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Got regex result %s\n", - GNUNET_i2s (pid)); - s->callback (s->callback_cls, - pid, - &pid[1], gpl, - &pid[1 + gpl], ppl); - return; - } - } - GNUNET_break (0); - GNUNET_CLIENT_disconnect (s->client); - s->client = GNUNET_CLIENT_connect ("regex", s->cfg); - retry_search (s); -} - - -/** - * Search for a peer offering a regex matching certain string in the DHT. - * The search runs until #GNUNET_REGEX_search_cancel() is called, even if results - * are returned. - * - * @param cfg configuration to use - * @param string String to match against the regexes in the DHT. - * @param callback Callback for found peers. - * @param callback_cls Closure for @c callback. - * @return Handle to stop search and free resources. - * Must be freed by calling #GNUNET_REGEX_search_cancel(). - */ -struct GNUNET_REGEX_Search * -GNUNET_REGEX_search (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *string, - GNUNET_REGEX_Found callback, - void *callback_cls) -{ - struct GNUNET_REGEX_Search *s; - size_t slen; - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Starting regex search for %s\n", - string); - slen = strlen (string) + 1; - s = GNUNET_new (struct GNUNET_REGEX_Search); - s->cfg = cfg; - s->client = GNUNET_CLIENT_connect ("regex", cfg); - if (NULL == s->client) - { - GNUNET_free (s); - return NULL; - } - s->callback = callback; - s->callback_cls = callback_cls; - s->msg = GNUNET_malloc (sizeof (struct RegexSearchMessage) + slen); - s->msg->header.type = htons (GNUNET_MESSAGE_TYPE_REGEX_SEARCH); - s->msg->header.size = htons (sizeof (struct RegexSearchMessage) + slen); - memcpy (&s->msg[1], string, slen); - retry_search (s); - return s; -} - - -/** - * Stop search and free all data used by a #GNUNET_REGEX_search() call. - * - * @param s Handle returned by a previous #GNUNET_REGEX_search() call. - */ -void -GNUNET_REGEX_search_cancel (struct GNUNET_REGEX_Search *s) -{ - GNUNET_CLIENT_disconnect (s->client); - GNUNET_free (s->msg); - GNUNET_free (s); -} - - -/* end of regex_api.c */ diff --git a/src/regex/regex_api_announce.c b/src/regex/regex_api_announce.c new file mode 100644 index 000000000..8953436a1 --- /dev/null +++ b/src/regex/regex_api_announce.c @@ -0,0 +1,186 @@ +/* + This file is part of GNUnet + Copyright (C) 2012, 2013, 2016 GNUnet e.V. + + 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 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +/** + * @file regex/regex_api_announce.c + * @brief access regex service to advertise capabilities via regex + * @author Maximilian Szengel + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_protocols.h" +#include "gnunet_util_lib.h" +#include "gnunet_regex_service.h" +#include "regex_ipc.h" + +#define LOG(kind,...) GNUNET_log_from (kind, "regex-api",__VA_ARGS__) + +/** + * Handle to store cached data about a regex announce. + */ +struct GNUNET_REGEX_Announcement +{ + /** + * Connection to the regex service. + */ + struct GNUNET_MQ_Handle *mq; + + /** + * Our configuration. + */ + const struct GNUNET_CONFIGURATION_Handle *cfg; + + /** + * Message we're sending to the service. + */ + char *regex; + + /** + * Frequency of announcements. + */ + struct GNUNET_TIME_Relative refresh_delay; + + /** + * Number of characters per edge. + */ + uint16_t compression; +}; + + + +/** + * (Re)connect to the REGEX service with the given announcement @a a. + * + * @param a REGEX to announce. + */ +static void +announce_reconnect (struct GNUNET_REGEX_Announcement *a); + + +/** + * We got a disconnect after asking regex to do the announcement. + * Retry. + * + * @param cls the `struct GNUNET_REGEX_Announcement` to retry + * @param error error code + */ +static void +announce_mq_error_handler (void *cls, + enum GNUNET_MQ_Error error) +{ + struct GNUNET_REGEX_Announcement *a = cls; + + GNUNET_MQ_destroy (a->mq); + a->mq = NULL; + announce_reconnect (a); +} + + +/** + * (Re)connect to the REGEX service with the given announcement @a a. + * + * @param a REGEX to announce. + */ +static void +announce_reconnect (struct GNUNET_REGEX_Announcement *a) +{ + struct GNUNET_MQ_Envelope *env; + struct AnnounceMessage *am; + size_t slen; + + a->mq = GNUNET_CLIENT_connecT (a->cfg, + "regex", + NULL, + &announce_mq_error_handler, + a); + if (NULL == a->mq) + return; + slen = strlen (a->regex) + 1; + env = GNUNET_MQ_msg_extra (am, + slen, + GNUNET_MESSAGE_TYPE_REGEX_ANNOUNCE); + am->compression = htons (a->compression); + am->reserved = htons (0); + am->refresh_delay = GNUNET_TIME_relative_hton (a->refresh_delay); + memcpy (&am[1], + a->regex, + slen); + GNUNET_MQ_send (a->mq, + env); +} + + +/** + * Announce the given peer under the given regular expression. + * + * @param cfg configuration to use + * @param regex Regular expression to announce. + * @param refresh_delay after what delay should the announcement be repeated? + * @param compression How many characters per edge can we squeeze? + * @return Handle to reuse o free cached resources. + * Must be freed by calling #GNUNET_REGEX_announce_cancel(). + */ +struct GNUNET_REGEX_Announcement * +GNUNET_REGEX_announce (const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *regex, + struct GNUNET_TIME_Relative refresh_delay, + uint16_t compression) +{ + struct GNUNET_REGEX_Announcement *a; + size_t slen; + + slen = strlen (regex) + 1; + if (slen + sizeof (struct AnnounceMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Regex `%s' is too long!\n"), + regex); + GNUNET_break (0); + return NULL; + } + a = GNUNET_new (struct GNUNET_REGEX_Announcement); + a->cfg = cfg; + a->refresh_delay = refresh_delay; + a->compression = compression; + a->regex = GNUNET_strdup (regex); + announce_reconnect (a); + if (NULL == a->mq) + { + GNUNET_free (a->regex); + GNUNET_free (a); + return NULL; + } + return a; +} + + +/** + * Stop announcing the regex specified by the given handle. + * + * @param a handle returned by a previous #GNUNET_REGEX_announce() call. + */ +void +GNUNET_REGEX_announce_cancel (struct GNUNET_REGEX_Announcement *a) +{ + GNUNET_MQ_destroy (a->mq); + GNUNET_free (a->regex); + GNUNET_free (a); +} + +/* end of regex_api_announce.c */ diff --git a/src/regex/regex_api_search.c b/src/regex/regex_api_search.c new file mode 100644 index 000000000..728e12beb --- /dev/null +++ b/src/regex/regex_api_search.c @@ -0,0 +1,215 @@ +/* + This file is part of GNUnet + Copyright (C) 2012, 2013, 2016 GNUnet e.V. + + 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 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +/** + * @file regex/regex_api_search.c + * @brief access regex service to discover + * peers using matching strings + * @author Maximilian Szengel + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_protocols.h" +#include "gnunet_util_lib.h" +#include "gnunet_regex_service.h" +#include "regex_ipc.h" + +#define LOG(kind,...) GNUNET_log_from (kind, "regex-api",__VA_ARGS__) + + +/** + * Handle to store data about a regex search. + */ +struct GNUNET_REGEX_Search +{ + /** + * Connection to the regex service. + */ + struct GNUNET_CLIENT_Connection *client; + + /** + * Our configuration. + */ + const struct GNUNET_CONFIGURATION_Handle *cfg; + + /** + * Function to call with results. + */ + GNUNET_REGEX_Found callback; + + /** + * Closure for @e callback. + */ + void *callback_cls; + + /** + * Search message to transmit to the service. + */ + struct RegexSearchMessage *msg; +}; + + +/** + * We got a response or disconnect after asking regex + * to do the search. Handle it. + * + * @param cls the `struct GNUNET_REGEX_Search` to retry + * @param msg NULL on disconnect + */ +static void +handle_search_response (void *cls, + const struct GNUNET_MessageHeader *msg); + + +/** + * Try sending the search request to regex. On + * errors (i.e. regex died), try again. + * + * @param s the search to retry + */ +static void +retry_search (struct GNUNET_REGEX_Search *s) +{ + GNUNET_assert (NULL != s->client); + GNUNET_assert (GNUNET_OK == + GNUNET_CLIENT_transmit_and_get_response (s->client, + &s->msg->header, + GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_YES, + &handle_search_response, + s)); +} + + +/** + * We got a response or disconnect after asking regex + * to do the search. Handle it. + * + * @param cls the `struct GNUNET_REGEX_Search` to handle reply for + * @param msg NULL on disconnect, otherwise presumably a response + */ +static void +handle_search_response (void *cls, + const struct GNUNET_MessageHeader *msg) +{ + struct GNUNET_REGEX_Search *s = cls; + const struct ResultMessage *result; + uint16_t size; + uint16_t gpl; + uint16_t ppl; + + if (NULL == msg) + { + GNUNET_CLIENT_disconnect (s->client); + s->client = GNUNET_CLIENT_connect ("regex", s->cfg); + retry_search (s); + return; + } + size = ntohs (msg->size); + if ( (GNUNET_MESSAGE_TYPE_REGEX_RESULT == ntohs (msg->type)) && + (size >= sizeof (struct ResultMessage)) ) + { + result = (const struct ResultMessage *) msg; + gpl = ntohs (result->get_path_length); + ppl = ntohs (result->put_path_length); + if (size == (sizeof (struct ResultMessage) + + (gpl + ppl) * sizeof (struct GNUNET_PeerIdentity))) + { + const struct GNUNET_PeerIdentity *pid; + + GNUNET_CLIENT_receive (s->client, + &handle_search_response, s, + GNUNET_TIME_UNIT_FOREVER_REL); + pid = &result->id; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Got regex result %s\n", + GNUNET_i2s (pid)); + s->callback (s->callback_cls, + pid, + &pid[1], gpl, + &pid[1 + gpl], ppl); + return; + } + } + GNUNET_break (0); + GNUNET_CLIENT_disconnect (s->client); + s->client = GNUNET_CLIENT_connect ("regex", s->cfg); + retry_search (s); +} + + +/** + * Search for a peer offering a regex matching certain string in the DHT. + * The search runs until #GNUNET_REGEX_search_cancel() is called, even if results + * are returned. + * + * @param cfg configuration to use + * @param string String to match against the regexes in the DHT. + * @param callback Callback for found peers. + * @param callback_cls Closure for @c callback. + * @return Handle to stop search and free resources. + * Must be freed by calling #GNUNET_REGEX_search_cancel(). + */ +struct GNUNET_REGEX_Search * +GNUNET_REGEX_search (const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *string, + GNUNET_REGEX_Found callback, + void *callback_cls) +{ + struct GNUNET_REGEX_Search *s; + size_t slen; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Starting regex search for %s\n", + string); + slen = strlen (string) + 1; + s = GNUNET_new (struct GNUNET_REGEX_Search); + s->cfg = cfg; + s->client = GNUNET_CLIENT_connect ("regex", cfg); + if (NULL == s->client) + { + GNUNET_free (s); + return NULL; + } + s->callback = callback; + s->callback_cls = callback_cls; + s->msg = GNUNET_malloc (sizeof (struct RegexSearchMessage) + slen); + s->msg->header.type = htons (GNUNET_MESSAGE_TYPE_REGEX_SEARCH); + s->msg->header.size = htons (sizeof (struct RegexSearchMessage) + slen); + memcpy (&s->msg[1], string, slen); + retry_search (s); + return s; +} + + +/** + * Stop search and free all data used by a #GNUNET_REGEX_search() call. + * + * @param s Handle returned by a previous #GNUNET_REGEX_search() call. + */ +void +GNUNET_REGEX_search_cancel (struct GNUNET_REGEX_Search *s) +{ + GNUNET_CLIENT_disconnect (s->client); + GNUNET_free (s->msg); + GNUNET_free (s); +} + + +/* end of regex_api.c */ -- cgit v1.2.3