/* 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 Affero General Public License as published by the Free Software Foundation, either version 3 of the License, 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . SPDX-License-Identifier: AGPL3.0-or-later */ /** * @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); GNUNET_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_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 */