GNUnet 0.26.2-106-g126384b46
 
Loading...
Searching...
No Matches
gnunet-service-regex.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013, 2026 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 "gnunet_pils_service.h"
28#include "regex_internal_lib.h"
29#include "regex_ipc.h"
30
31#include "gnunet_util_lib.h"
32
33
69
70
74static struct GNUNET_DHT_Handle *dht;
75
80
84static struct GNUNET_PILS_Handle *pils;
85
86
92static void
93cleanup_task (void *cls)
94{
95 if (NULL != dht)
96 {
98 dht = NULL;
99 }
100 if (NULL != stats)
101 {
103 GNUNET_NO);
104 stats = NULL;
105 }
106 if (NULL != pils)
107 {
109 pils = NULL;
110 }
111}
112
113
120static void
121reannounce (void *cls)
122{
123 struct ClientEntry *ce = cls;
124
127 &reannounce,
128 ce);
129}
130
131
139static int
140check_announce (void *cls,
141 const struct AnnounceMessage *am)
142{
143 struct ClientEntry *ce = cls;
144
146 if (NULL != ce->ah)
147 {
148 /* only one announcement per client allowed */
149 GNUNET_break (0);
150 return GNUNET_SYSERR;
151 }
152 return GNUNET_OK;
153}
154
155
162static void
164 const struct AnnounceMessage *am)
165{
166 struct ClientEntry *ce = cls;
167 const char *regex;
168
169 regex = (const char *) &am[1];
172 &reannounce,
173 ce);
175 "Starting to announce regex `%s' every %s\n",
176 regex,
178 GNUNET_NO));
180 pils,
181 regex,
182 ntohs (am->compression),
183 stats);
184 if (NULL == ce->ah)
185 {
186 GNUNET_break (0);
188 ce->refresh_task = NULL;
190 return;
191 }
193}
194
195
206static void
208 const struct GNUNET_PeerIdentity *id,
209 const struct GNUNET_DHT_PathElement *get_path,
210 unsigned int get_path_length,
211 const struct GNUNET_DHT_PathElement *put_path,
212 unsigned int put_path_length)
213{
214 struct ClientEntry *ce = cls;
215 struct GNUNET_MQ_Envelope *env;
216 struct ResultMessage *result;
217 struct GNUNET_PeerIdentity *gp;
218 uint16_t size;
219
220 if ((get_path_length >= 65536) ||
221 (put_path_length >= 65536) ||
222 ( ((get_path_length + put_path_length)
223 * sizeof(struct GNUNET_PeerIdentity))
224 + sizeof(struct ResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) )
225 {
226 GNUNET_break (0);
227 return;
228 }
229 size = (get_path_length + put_path_length)
230 * sizeof(struct GNUNET_PeerIdentity);
232 size,
234 result->get_path_length = htons ((uint16_t) get_path_length);
235 result->put_path_length = htons ((uint16_t) put_path_length);
236 result->id = *id;
237 gp = &result->id;
238 for (unsigned int i = 0; i<get_path_length; i++)
239 gp[i + 1] = get_path[i].pred;
240 for (unsigned int i = 0; i<put_path_length; i++)
241 gp[i + get_path_length + 1] = put_path[i].pred;
242 GNUNET_MQ_send (ce->mq,
243 env);
244}
245
246
253static int
254check_search (void *cls,
255 const struct RegexSearchMessage *sm)
256{
257 struct ClientEntry *ce = cls;
258 const char *string;
259 uint16_t size;
260
261 size = ntohs (sm->header.size) - sizeof(*sm);
262 string = (const char *) &sm[1];
263 if ('\0' != string[size - 1])
264 {
265 GNUNET_break (0);
266 return GNUNET_SYSERR;
267 }
268 if (NULL != ce->sh)
269 {
270 /* only one search allowed per client */
271 GNUNET_break (0);
272 return GNUNET_SYSERR;
273 }
274 return GNUNET_OK;
275}
276
277
284static void
285handle_search (void *cls,
286 const struct RegexSearchMessage *sm)
287{
288 struct ClientEntry *ce = cls;
289 const char *string;
290
291 string = (const char *) &sm[1];
293 "Starting to search for `%s'\n",
294 string);
296 string,
298 ce,
299 stats);
300 if (NULL == ce->sh)
301 {
302 GNUNET_break (0);
304 return;
305 }
307}
308
309
317static void
318run (void *cls,
319 const struct GNUNET_CONFIGURATION_Handle *cfg,
321{
322 pils = GNUNET_PILS_connect (cfg, NULL, NULL);
323 if (NULL == pils)
324 {
326 return;
327 }
328 dht = GNUNET_DHT_connect (cfg, 1024);
329 if (NULL == dht)
330 {
332 pils = NULL;
334 return;
335 }
337 NULL);
339}
340
341
350static void *
352 struct GNUNET_SERVICE_Client *c,
353 struct GNUNET_MQ_Handle *mq)
354{
355 struct ClientEntry *ce;
356
357 ce = GNUNET_new (struct ClientEntry);
358 ce->client = c;
359 ce->mq = mq;
360 return ce;
361}
362
363
371static void
373 struct GNUNET_SERVICE_Client *c,
374 void *internal_cls)
375{
376 struct ClientEntry *ce = internal_cls;
377
378 if (NULL != ce->refresh_task)
379 {
381 ce->refresh_task = NULL;
382 }
383 if (NULL != ce->ah)
384 {
386 ce->ah = NULL;
387 }
388 if (NULL != ce->sh)
389 {
391 ce->sh = NULL;
392 }
393 GNUNET_free (ce);
394}
395
396
402 "regex",
404 &run,
407 NULL,
408 GNUNET_MQ_hd_var_size (announce,
410 struct AnnounceMessage,
411 NULL),
414 struct RegexSearchMessage,
415 NULL),
417
418
419/* end of gnunet-service-regex.c */
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition gnunet-arm.c:108
static struct GNUNET_IDENTITY_Handle * id
Handle to IDENTITY.
static struct GNUNET_SCHEDULER_Task * cleanup_task
Cleanup task.
static int result
Global testing status.
struct GNUNET_REGEX_Search * search
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 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.
static void reannounce(void *cls)
Periodic task to refresh our announcement of the regex.
static struct GNUNET_PILS_Handle * pils
Handle for pils service.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
Process regex requests.
struct GNUNET_PILS_Handle * GNUNET_PILS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_PILS_PidChangeCallback pid_change_cb, void *cls)
Connect to the PILS service.
Definition pils_api.c:465
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:488
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
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:1036
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition dht_api.c:1059
#define GNUNET_log(kind,...)
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ 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:305
#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.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
#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:572
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:1345
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
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:1283
#define GNUNET_SERVICE_MAIN(pd, service_name, service_options, init_cb, connect_cb, disconnect_cb, cls,...)
Creates the "main" function for a GNUnet service.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition service.c:2463
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition service.c:2434
@ 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:626
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:604
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_Announcement * REGEX_INTERNAL_announce(struct GNUNET_DHT_Handle *dht, struct GNUNET_PILS_Handle *pils, const char *regex, uint16_t compression, struct GNUNET_STATISTICS_Handle *stats)
Announce a regular expression: put all states of the automaton in the DHT.
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.
library to parse regular expressions into dfa
regex IPC messages (not called 'regex.h' due to conflict with system headers)
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
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.
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
A handle for the PILS service.
Definition pils_api.c:82
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition scheduler.c:141
Handle to a client that is connected to a service.
Definition service.c:249
Handle to a service.
Definition service.c:116
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