GNUnet 0.22.2
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 "gnunet_util_lib.h"
28#include "regex_internal_lib.h"
29#include "regex_ipc.h"
30
31
36{
41
46
51
56
61
66};
67
68
72static struct GNUNET_DHT_Handle *dht;
73
78
83
84
90static void
91cleanup_task (void *cls)
92{
94 dht = NULL;
96 GNUNET_NO);
97 stats = NULL;
99 my_private_key = NULL;
100}
101
102
109static void
110reannounce (void *cls)
111{
112 struct ClientEntry *ce = cls;
113
116 &reannounce,
117 ce);
118}
119
120
128static int
129check_announce (void *cls,
130 const struct AnnounceMessage *am)
131{
132 struct ClientEntry *ce = cls;
133
135 if (NULL != ce->ah)
136 {
137 /* only one announcement per client allowed */
138 GNUNET_break (0);
139 return GNUNET_SYSERR;
140 }
141 return GNUNET_OK;
142}
143
144
151static void
153 const struct AnnounceMessage *am)
154{
155 struct ClientEntry *ce = cls;
156 const char *regex;
157
158 regex = (const char *) &am[1];
161 &reannounce,
162 ce);
164 "Starting to announce regex `%s' every %s\n",
165 regex,
167 GNUNET_NO));
170 regex,
171 ntohs (am->compression),
172 stats);
173 if (NULL == ce->ah)
174 {
175 GNUNET_break (0);
177 ce->refresh_task = NULL;
179 return;
180 }
182}
183
184
195static void
197 const struct GNUNET_PeerIdentity *id,
198 const struct GNUNET_DHT_PathElement *get_path,
199 unsigned int get_path_length,
200 const struct GNUNET_DHT_PathElement *put_path,
201 unsigned int put_path_length)
202{
203 struct ClientEntry *ce = cls;
204 struct GNUNET_MQ_Envelope *env;
205 struct ResultMessage *result;
206 struct GNUNET_PeerIdentity *gp;
207 uint16_t size;
208
209 if ((get_path_length >= 65536) ||
210 (put_path_length >= 65536) ||
211 ( ((get_path_length + put_path_length)
212 * sizeof(struct GNUNET_PeerIdentity))
213 + sizeof(struct ResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) )
214 {
215 GNUNET_break (0);
216 return;
217 }
218 size = (get_path_length + put_path_length)
219 * sizeof(struct GNUNET_PeerIdentity);
221 size,
223 result->get_path_length = htons ((uint16_t) get_path_length);
224 result->put_path_length = htons ((uint16_t) put_path_length);
225 result->id = *id;
226 gp = &result->id;
227 for (unsigned int i = 0; i<get_path_length; i++)
228 gp[i + 1] = get_path[i].pred;
229 for (unsigned int i = 0; i<put_path_length; i++)
230 gp[i + get_path_length + 1] = put_path[i].pred;
231 GNUNET_MQ_send (ce->mq,
232 env);
233}
234
235
242static int
243check_search (void *cls,
244 const struct RegexSearchMessage *sm)
245{
246 struct ClientEntry *ce = cls;
247 const char *string;
248 uint16_t size;
249
250 size = ntohs (sm->header.size) - sizeof(*sm);
251 string = (const char *) &sm[1];
252 if ('\0' != string[size - 1])
253 {
254 GNUNET_break (0);
255 return GNUNET_SYSERR;
256 }
257 if (NULL != ce->sh)
258 {
259 /* only one search allowed per client */
260 GNUNET_break (0);
261 return GNUNET_SYSERR;
262 }
263 return GNUNET_OK;
264}
265
266
273static void
274handle_search (void *cls,
275 const struct RegexSearchMessage *sm)
276{
277 struct ClientEntry *ce = cls;
278 const char *string;
279
280 string = (const char *) &sm[1];
282 "Starting to search for `%s'\n",
283 string);
285 string,
287 ce,
288 stats);
289 if (NULL == ce->sh)
290 {
291 GNUNET_break (0);
293 return;
294 }
296}
297
298
306static void
307run (void *cls,
308 const struct GNUNET_CONFIGURATION_Handle *cfg,
310{
312 if (NULL == my_private_key)
313 {
315 return;
316 }
317 dht = GNUNET_DHT_connect (cfg, 1024);
318 if (NULL == dht)
319 {
321 my_private_key = NULL;
323 return;
324 }
326 NULL);
328}
329
330
339static void *
341 struct GNUNET_SERVICE_Client *c,
342 struct GNUNET_MQ_Handle *mq)
343{
344 struct ClientEntry *ce;
345
346 ce = GNUNET_new (struct ClientEntry);
347 ce->client = c;
348 ce->mq = mq;
349 return ce;
350}
351
352
360static void
362 struct GNUNET_SERVICE_Client *c,
363 void *internal_cls)
364{
365 struct ClientEntry *ce = internal_cls;
366
367 if (NULL != ce->refresh_task)
368 {
370 ce->refresh_task = NULL;
371 }
372 if (NULL != ce->ah)
373 {
375 ce->ah = NULL;
376 }
377 if (NULL != ce->sh)
378 {
380 ce->sh = NULL;
381 }
382 GNUNET_free (ce);
383}
384
385
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:108
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.
GNUNET_SERVICE_MAIN(GNUNET_OS_project_data_gnunet(), "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 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.
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:1030
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:1053
#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.
Definition: gnunet_mq_lib.h:61
#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:567
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:1339
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:980
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:1277
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2418
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2389
@ 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:630
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:579
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
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: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