2 This file is part of GNUnet
3 Copyright (C) 2012, 2013, 2016 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
21 * @file regex/regex_api_search.c
22 * @brief access regex service to discover
23 * peers using matching strings
24 * @author Maximilian Szengel
25 * @author Christian Grothoff
28 #include "gnunet_protocols.h"
29 #include "gnunet_util_lib.h"
30 #include "gnunet_regex_service.h"
31 #include "regex_ipc.h"
33 #define LOG(kind, ...) GNUNET_log_from(kind, "regex-api", __VA_ARGS__)
37 * Handle to store data about a regex search.
39 struct GNUNET_REGEX_Search {
41 * Connection to the regex service.
43 struct GNUNET_MQ_Handle *mq;
48 const struct GNUNET_CONFIGURATION_Handle *cfg;
51 * Function to call with results.
53 GNUNET_REGEX_Found callback;
56 * Closure for @e callback.
61 * Search string to transmit to the service.
68 * (Re)connect to the REGEX service for the given search @a s.
70 * @param s context for the search search for
73 search_reconnect(struct GNUNET_REGEX_Search *s);
77 * We got a response or disconnect after asking regex
78 * to do the search. Check it is well-formed.
80 * @param cls the `struct GNUNET_REGEX_Search` to handle reply for
81 * @param result the message
82 * @return #GNUNET_SYSERR if @a rm is not well-formed.
85 check_search_response(void *cls,
86 const struct ResultMessage *result)
88 uint16_t size = ntohs(result->header.size) - sizeof(*result);
89 uint16_t gpl = ntohs(result->get_path_length);
90 uint16_t ppl = ntohs(result->put_path_length);
92 if (size != (gpl + ppl) * sizeof(struct GNUNET_PeerIdentity))
102 * We got a response or disconnect after asking regex
103 * to do the search. Handle it.
105 * @param cls the `struct GNUNET_REGEX_Search` to handle reply for
106 * @param result the message
109 handle_search_response(void *cls,
110 const struct ResultMessage *result)
112 struct GNUNET_REGEX_Search *s = cls;
113 uint16_t gpl = ntohs(result->get_path_length);
114 uint16_t ppl = ntohs(result->put_path_length);
115 const struct GNUNET_PeerIdentity *pid;
118 LOG(GNUNET_ERROR_TYPE_DEBUG,
119 "Got regex result %s\n",
121 s->callback(s->callback_cls,
131 * We got a disconnect after asking regex to do the announcement.
134 * @param cls the `struct GNUNET_REGEX_Search` to retry
135 * @param error error code
138 mq_error_handler(void *cls,
139 enum GNUNET_MQ_Error error)
141 struct GNUNET_REGEX_Search *s = cls;
143 GNUNET_MQ_destroy(s->mq);
150 * (Re)connect to the REGEX service for the given search @a s.
152 * @param s context for the search search for
155 search_reconnect(struct GNUNET_REGEX_Search *s)
157 struct GNUNET_MQ_MessageHandler handlers[] = {
158 GNUNET_MQ_hd_var_size(search_response,
159 GNUNET_MESSAGE_TYPE_REGEX_RESULT,
160 struct ResultMessage,
162 GNUNET_MQ_handler_end()
164 size_t slen = strlen(s->string) + 1;
165 struct GNUNET_MQ_Envelope *env;
166 struct RegexSearchMessage *rsm;
168 GNUNET_assert(NULL == s->mq);
169 s->mq = GNUNET_CLIENT_connect(s->cfg,
176 env = GNUNET_MQ_msg_extra(rsm,
178 GNUNET_MESSAGE_TYPE_REGEX_SEARCH);
179 GNUNET_memcpy(&rsm[1],
182 GNUNET_MQ_send(s->mq,
188 * Search for a peer offering a regex matching certain string in the DHT.
189 * The search runs until #GNUNET_REGEX_search_cancel() is called, even if results
192 * @param cfg configuration to use
193 * @param string String to match against the regexes in the DHT.
194 * @param callback Callback for found peers.
195 * @param callback_cls Closure for @c callback.
196 * @return Handle to stop search and free resources.
197 * Must be freed by calling #GNUNET_REGEX_search_cancel().
199 struct GNUNET_REGEX_Search *
200 GNUNET_REGEX_search(const struct GNUNET_CONFIGURATION_Handle *cfg,
202 GNUNET_REGEX_Found callback,
205 struct GNUNET_REGEX_Search *s;
206 size_t slen = strlen(string) + 1;
208 if (slen + sizeof(struct RegexSearchMessage) >= GNUNET_MAX_MESSAGE_SIZE)
210 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
211 _("Search string `%s' is too long!\n"),
216 LOG(GNUNET_ERROR_TYPE_DEBUG,
217 "Starting regex search for %s\n",
219 s = GNUNET_new(struct GNUNET_REGEX_Search);
221 s->string = GNUNET_strdup(string);
222 s->callback = callback;
223 s->callback_cls = callback_cls;
227 GNUNET_free(s->string);
236 * Stop search and free all data used by a #GNUNET_REGEX_search() call.
238 * @param s Handle returned by a previous #GNUNET_REGEX_search() call.
241 GNUNET_REGEX_search_cancel(struct GNUNET_REGEX_Search *s)
243 GNUNET_MQ_destroy(s->mq);
244 GNUNET_free(s->string);
249 /* end of regex_api_search.c */