GNUnet 0.21.1
gnunet-service-regex.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V.
4
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.
9
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.
14
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/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "regex_internal_lib.h"
30#include "regex_ipc.h"
31
32
37{
42
47
52
57
62
67};
68
69
73static struct GNUNET_DHT_Handle *dht;
74
79
84
85
91static void
92cleanup_task (void *cls)
93{
95 dht = NULL;
97 GNUNET_NO);
98 stats = NULL;
100 my_private_key = NULL;
101}
102
103
110static void
111reannounce (void *cls)
112{
113 struct ClientEntry *ce = cls;
114
117 &reannounce,
118 ce);
119}
120
121
129static int
130check_announce (void *cls,
131 const struct AnnounceMessage *am)
132{
133 struct ClientEntry *ce = cls;
134
136 if (NULL != ce->ah)
137 {
138 /* only one announcement per client allowed */
139 GNUNET_break (0);
140 return GNUNET_SYSERR;
141 }
142 return GNUNET_OK;
143}
144
145
152static void
154 const struct AnnounceMessage *am)
155{
156 struct ClientEntry *ce = cls;
157 const char *regex;
158
159 regex = (const char *) &am[1];
162 &reannounce,
163 ce);
165 "Starting to announce regex `%s' every %s\n",
166 regex,
168 GNUNET_NO));
171 regex,
172 ntohs (am->compression),
173 stats);
174 if (NULL == ce->ah)
175 {
176 GNUNET_break (0);
178 ce->refresh_task = NULL;
180 return;
181 }
183}
184
185
196static void
198 const struct GNUNET_PeerIdentity *id,
199 const struct GNUNET_DHT_PathElement *get_path,
200 unsigned int get_path_length,
201 const struct GNUNET_DHT_PathElement *put_path,
202 unsigned int put_path_length)
203{
204 struct ClientEntry *ce = cls;
205 struct GNUNET_MQ_Envelope *env;
206 struct ResultMessage *result;
207 struct GNUNET_PeerIdentity *gp;
208 uint16_t size;
209
210 if ((get_path_length >= 65536) ||
211 (put_path_length >= 65536) ||
212 ( ((get_path_length + put_path_length)
213 * sizeof(struct GNUNET_PeerIdentity))
214 + sizeof(struct ResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) )
215 {
216 GNUNET_break (0);
217 return;
218 }
219 size = (get_path_length + put_path_length)
220 * sizeof(struct GNUNET_PeerIdentity);
222 size,
224 result->get_path_length = htons ((uint16_t) get_path_length);
225 result->put_path_length = htons ((uint16_t) put_path_length);
226 result->id = *id;
227 gp = &result->id;
228 for (unsigned int i = 0; i<get_path_length; i++)
229 gp[i + 1] = get_path[i].pred;
230 for (unsigned int i = 0; i<put_path_length; i++)
231 gp[i + get_path_length + 1] = put_path[i].pred;
232 GNUNET_MQ_send (ce->mq,
233 env);
234}
235
236
243static int
244check_search (void *cls,
245 const struct RegexSearchMessage *sm)
246{
247 struct ClientEntry *ce = cls;
248 const char *string;
249 uint16_t size;
250
251 size = ntohs (sm->header.size) - sizeof(*sm);
252 string = (const char *) &sm[1];
253 if ('\0' != string[size - 1])
254 {
255 GNUNET_break (0);
256 return GNUNET_SYSERR;
257 }
258 if (NULL != ce->sh)
259 {
260 /* only one search allowed per client */
261 GNUNET_break (0);
262 return GNUNET_SYSERR;
263 }
264 return GNUNET_OK;
265}
266
267
274static void
275handle_search (void *cls,
276 const struct RegexSearchMessage *sm)
277{
278 struct ClientEntry *ce = cls;
279 const char *string;
280
281 string = (const char *) &sm[1];
283 "Starting to search for `%s'\n",
284 string);
286 string,
288 ce,
289 stats);
290 if (NULL == ce->sh)
291 {
292 GNUNET_break (0);
294 return;
295 }
297}
298
299
307static void
308run (void *cls,
309 const struct GNUNET_CONFIGURATION_Handle *cfg,
311{
313 if (NULL == my_private_key)
314 {
316 return;
317 }
318 dht = GNUNET_DHT_connect (cfg, 1024);
319 if (NULL == dht)
320 {
322 my_private_key = NULL;
324 return;
325 }
327 NULL);
329}
330
331
340static void *
342 struct GNUNET_SERVICE_Client *c,
343 struct GNUNET_MQ_Handle *mq)
344{
345 struct ClientEntry *ce;
346
347 ce = GNUNET_new (struct ClientEntry);
348 ce->client = c;
349 ce->mq = mq;
350 return ce;
351}
352
353
361static void
363 struct GNUNET_SERVICE_Client *c,
364 void *internal_cls)
365{
366 struct ClientEntry *ce = internal_cls;
367
368 if (NULL != ce->refresh_task)
369 {
371 ce->refresh_task = NULL;
372 }
373 if (NULL != ce->ah)
374 {
376 ce->ah = NULL;
377 }
378 if (NULL != ce->sh)
379 {
381 ce->sh = NULL;
382 }
383 GNUNET_free (ce);
384}
385
386
391 ("regex",
393 &run,
396 NULL,
397 GNUNET_MQ_hd_var_size (announce,
399 struct AnnounceMessage,
400 NULL),
401 GNUNET_MQ_hd_var_size (search,
403 struct RegexSearchMessage,
404 NULL),
406
407
408/* end of gnunet-service-regex.c */
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:109
static struct GNUNET_IDENTITY_Handle * id
Handle to IDENTITY.
static int result
Global testing status.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static struct GNUNET_DHT_Handle * dht
Connection to the DHT.
static int check_announce(void *cls, const struct AnnounceMessage *am)
Check ANNOUNCE message.
static void handle_announce(void *cls, const struct AnnounceMessage *am)
Handle ANNOUNCE message.
static void handle_search(void *cls, const struct RegexSearchMessage *sm)
Handle SEARCH message.
static struct GNUNET_STATISTICS_Handle * stats
Handle for doing statistics.
static void cleanup_task(void *cls)
Task run during shutdown.
static int check_search(void *cls, const struct RegexSearchMessage *sm)
Check SEARCH message.
static void handle_search_result(void *cls, const struct GNUNET_PeerIdentity *id, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *put_path, unsigned int put_path_length)
Handle result, pass it back to the client.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *c, struct GNUNET_MQ_Handle *mq)
Callback called when a client connects to the service.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *c, void *internal_cls)
Callback called when a client disconnected from the service.
GNUNET_SERVICE_MAIN("regex", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(announce, GNUNET_MESSAGE_TYPE_REGEX_ANNOUNCE, struct AnnounceMessage, NULL), GNUNET_MQ_hd_var_size(search, GNUNET_MESSAGE_TYPE_REGEX_SEARCH, struct RegexSearchMessage, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Private key for this peer.
static void reannounce(void *cls)
Periodic task to refresh our announcement of the regex.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
Process regex requests.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create_from_configuration(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new private key by reading our peer's key from the file specified in the configuration.
struct GNUNET_DHT_Handle * GNUNET_DHT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int ht_len)
Initialize the connection with the DHT service.
Definition: dht_api.c:1037
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:1060
#define GNUNET_log(kind,...)
@ GNUNET_OK
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:304
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_check_zero_termination(m)
Insert code for a "check_" function that verifies that a given variable-length message received over ...
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:63
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MESSAGE_TYPE_REGEX_ANNOUNCE
Advertise regex capability.
#define GNUNET_MESSAGE_TYPE_REGEX_SEARCH
Search for peer with matching capability.
#define GNUNET_MESSAGE_TYPE_REGEX_RESULT
Result in response to regex search.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:562
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1334
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1272
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2489
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2408
@ GNUNET_SERVICE_OPTION_NONE
Use defaults.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
struct GNUNET_TIME_Relative GNUNET_TIME_relative_ntoh(struct GNUNET_TIME_RelativeNBO a)
Convert relative time from network byte order.
Definition: time.c:628
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:570
static unsigned int size
Size of the "table".
Definition: peer.c:68
void REGEX_INTERNAL_search_cancel(struct REGEX_INTERNAL_Search *h)
Cancel an ongoing regex search in the DHT and free all resources.
struct REGEX_INTERNAL_Search * REGEX_INTERNAL_search(struct GNUNET_DHT_Handle *dht, const char *string, REGEX_INTERNAL_Found callback, void *callback_cls, struct GNUNET_STATISTICS_Handle *stats)
Search for a peer offering a regex matching certain string in the DHT.
void REGEX_INTERNAL_announce_cancel(struct REGEX_INTERNAL_Announcement *h)
Clear all cached data used by a regex announce.
void REGEX_INTERNAL_reannounce(struct REGEX_INTERNAL_Announcement *h)
Announce again a regular expression previously announced.
struct REGEX_INTERNAL_Announcement * REGEX_INTERNAL_announce(struct GNUNET_DHT_Handle *dht, const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const char *regex, uint16_t compression, struct GNUNET_STATISTICS_Handle *stats)
Announce a regular expression: put all states of the automaton in the DHT.
library to parse regular expressions into dfa
regex IPC messages (not called 'regex.h' due to conflict with system headers)
Request for regex service to announce capability.
Definition: regex_ipc.h:35
struct GNUNET_TIME_RelativeNBO refresh_delay
Delay between repeated announcements.
Definition: regex_ipc.h:54
uint16_t compression
How many characters can we squeeze per edge?
Definition: regex_ipc.h:44
Information about one of our clients.
struct GNUNET_SERVICE_Client * client
Handle identifying the client.
struct REGEX_INTERNAL_Announcement * ah
Announcement handle (if this client is announcing).
struct GNUNET_TIME_Relative frequency
Refresh frequency for announcements.
struct REGEX_INTERNAL_Search * sh
Search handle (if this client is searching).
struct GNUNET_MQ_Handle * mq
Queue for transmissions to client.
struct GNUNET_SCHEDULER_Task * refresh_task
Task for re-announcing.
Private ECC key encoded for transmission.
Connection to the DHT service.
Definition: dht_api.c:235
A (signed) path tracking a block's flow through the DHT is represented by an array of path elements,...
Handle to a message queue.
Definition: mq.c:87
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:136
Handle to a client that is connected to a service.
Definition: service.c:252
Handle to a service.
Definition: service.c:118
Handle for the service.
Time for relative time used by GNUnet, in microseconds.
Handle to store cached data about a regex announce.
Struct to keep information of searches of services described by a regex using a user-provided string ...
Message to initiate regex search.
Definition: regex_ipc.h:64
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_REGEX_SEARCH.
Definition: regex_ipc.h:68
Result from regex search.
Definition: regex_ipc.h:78