GNUnet  0.17.6
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 
73 static struct GNUNET_DHT_Handle *dht;
74 
79 
84 
85 
91 static void
92 cleanup_task (void *cls)
93 {
95  dht = NULL;
97  GNUNET_NO);
98  stats = NULL;
100  my_private_key = NULL;
101 }
102 
103 
110 static void
111 reannounce (void *cls)
112 {
113  struct ClientEntry *ce = cls;
114 
117  &reannounce,
118  ce);
119 }
120 
121 
129 static int
130 check_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 
152 static void
153 handle_announce (void *cls,
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 
196 static 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 
243 static int
244 check_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 
274 static void
275 handle_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 
307 static void
308 run (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);
328  stats = GNUNET_STATISTICS_create ("regex", cfg);
329 }
330 
331 
340 static void *
341 client_connect_cb (void *cls,
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 
361 static 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 const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static struct GNUNET_IDENTITY_Handle * id
Handle to identity service.
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 * 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 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_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:1039
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:1062
#define GNUNET_log(kind,...)
@ GNUNET_OK
Definition: gnunet_common.h:99
@ GNUNET_NO
Definition: gnunet_common.h:98
@ GNUNET_SYSERR
Definition: gnunet_common.h:97
#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:302
#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:56
#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:533
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:1316
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
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:1254
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2329
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2248
@ 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:627
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:67
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_search_cancel(struct REGEX_INTERNAL_Search *h)
Cancel an ongoing regex search in the DHT and free all resources.
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:237
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:86
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:135
Handle to a client that is connected to a service.
Definition: service.c:251
Handle to a service.
Definition: service.c:117
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