aboutsummaryrefslogtreecommitdiff
path: root/src/regex/gnunet-service-regex.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/regex/gnunet-service-regex.c')
-rw-r--r--src/regex/gnunet-service-regex.c416
1 files changed, 0 insertions, 416 deletions
diff --git a/src/regex/gnunet-service-regex.c b/src/regex/gnunet-service-regex.c
deleted file mode 100644
index eb10e7c07..000000000
--- a/src/regex/gnunet-service-regex.c
+++ /dev/null
@@ -1,416 +0,0 @@
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
19/**
20 * @file regex/gnunet-service-regex.c
21 * @brief service to advertise capabilities described as regex and to
22 * lookup capabilities by regex
23 * @author Christian Grothoff
24 */
25#include "platform.h"
26#include "gnunet_util_lib.h"
27#include "regex_internal_lib.h"
28#include "regex_ipc.h"
29
30
31/**
32 * Information about one of our clients.
33 */
34struct ClientEntry
35{
36
37 /**
38 * Queue for transmissions to @e client.
39 */
40 struct GNUNET_MQ_Handle *mq;
41
42 /**
43 * Handle identifying the client.
44 */
45 struct GNUNET_SERVICE_Client *client;
46
47 /**
48 * Search handle (if this client is searching).
49 */
50 struct REGEX_INTERNAL_Search *sh;
51
52 /**
53 * Announcement handle (if this client is announcing).
54 */
55 struct REGEX_INTERNAL_Announcement *ah;
56
57 /**
58 * Refresh frequency for announcements.
59 */
60 struct GNUNET_TIME_Relative frequency;
61
62 /**
63 * Task for re-announcing.
64 */
65 struct GNUNET_SCHEDULER_Task *refresh_task;
66
67};
68
69
70/**
71 * Connection to the DHT.
72 */
73static struct GNUNET_DHT_Handle *dht;
74
75/**
76 * Handle for doing statistics.
77 */
78static struct GNUNET_STATISTICS_Handle *stats;
79
80/**
81 * Private key for this peer.
82 */
83static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
84
85
86/**
87 * Task run during shutdown.
88 *
89 * @param cls unused
90 */
91static void
92cleanup_task (void *cls)
93{
94 GNUNET_DHT_disconnect (dht);
95 dht = NULL;
96 GNUNET_STATISTICS_destroy (stats,
97 GNUNET_NO);
98 stats = NULL;
99 GNUNET_free (my_private_key);
100 my_private_key = NULL;
101}
102
103
104/**
105 * Periodic task to refresh our announcement of the regex.
106 *
107 * @param cls the `struct ClientEntry *` of the client that triggered the
108 * announcement
109 */
110static void
111reannounce (void *cls)
112{
113 struct ClientEntry *ce = cls;
114
115 REGEX_INTERNAL_reannounce (ce->ah);
116 ce->refresh_task = GNUNET_SCHEDULER_add_delayed (ce->frequency,
117 &reannounce,
118 ce);
119}
120
121
122/**
123 * Check ANNOUNCE message.
124 *
125 * @param cls identification of the client
126 * @param am the actual message
127 * @return #GNUNET_OK if @am is well-formed
128 */
129static int
130check_announce (void *cls,
131 const struct AnnounceMessage *am)
132{
133 struct ClientEntry *ce = cls;
134 const char *regex;
135 uint16_t size;
136
137 size = ntohs (am->header.size) - sizeof (*am);
138 regex = (const char *) &am[1];
139 if ('\0' != regex[size - 1])
140 {
141 GNUNET_break (0);
142 return GNUNET_SYSERR;
143 }
144 if (NULL != ce->ah)
145 {
146 /* only one announcement per client allowed */
147 GNUNET_break (0);
148 return GNUNET_SYSERR;
149 }
150 return GNUNET_OK;
151}
152
153
154/**
155 * Handle ANNOUNCE message.
156 *
157 * @param cls identification of the client
158 * @param am the actual message
159 */
160static void
161handle_announce (void *cls,
162 const struct AnnounceMessage *am)
163{
164 struct ClientEntry *ce = cls;
165 const char *regex;
166
167 regex = (const char *) &am[1];
168 ce->frequency = GNUNET_TIME_relative_ntoh (am->refresh_delay);
169 ce->refresh_task = GNUNET_SCHEDULER_add_delayed (ce->frequency,
170 &reannounce,
171 ce);
172 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
173 "Starting to announce regex `%s' every %s\n",
174 regex,
175 GNUNET_STRINGS_relative_time_to_string (ce->frequency,
176 GNUNET_NO));
177 ce->ah = REGEX_INTERNAL_announce (dht,
178 my_private_key,
179 regex,
180 ntohs (am->compression),
181 stats);
182 if (NULL == ce->ah)
183 {
184 GNUNET_break (0);
185 GNUNET_SCHEDULER_cancel (ce->refresh_task);
186 ce->refresh_task = NULL;
187 GNUNET_SERVICE_client_drop (ce->client);
188 return;
189 }
190 GNUNET_SERVICE_client_continue (ce->client);
191}
192
193
194/**
195 * Handle result, pass it back to the client.
196 *
197 * @param cls the struct ClientEntry of the client searching
198 * @param id Peer providing a regex that matches the string.
199 * @param get_path Path of the get request.
200 * @param get_path_length Lenght of @a get_path.
201 * @param put_path Path of the put request.
202 * @param put_path_length Length of the @a put_path.
203 */
204static void
205handle_search_result (void *cls,
206 const struct GNUNET_PeerIdentity *id,
207 const struct GNUNET_PeerIdentity *get_path,
208 unsigned int get_path_length,
209 const struct GNUNET_PeerIdentity *put_path,
210 unsigned int put_path_length)
211{
212 struct ClientEntry *ce = cls;
213 struct GNUNET_MQ_Envelope *env;
214 struct ResultMessage *result;
215 struct GNUNET_PeerIdentity *gp;
216 uint16_t size;
217
218 if ( (get_path_length >= 65536) ||
219 (put_path_length >= 65536) ||
220 ( (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity))
221 + sizeof (struct ResultMessage) >= GNUNET_MAX_MESSAGE_SIZE)
222 {
223 GNUNET_break (0);
224 return;
225 }
226 size = (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity);
227 env = GNUNET_MQ_msg_extra (result,
228 size,
229 GNUNET_MESSAGE_TYPE_REGEX_RESULT);
230 result->get_path_length = htons ((uint16_t) get_path_length);
231 result->put_path_length = htons ((uint16_t) put_path_length);
232 result->id = *id;
233 gp = &result->id;
234 GNUNET_memcpy (&gp[1],
235 get_path,
236 get_path_length * sizeof (struct GNUNET_PeerIdentity));
237 GNUNET_memcpy (&gp[1 + get_path_length],
238 put_path,
239 put_path_length * sizeof (struct GNUNET_PeerIdentity));
240 GNUNET_MQ_send (ce->mq,
241 env);
242}
243
244
245/**
246 * Check SEARCH message.
247 *
248 * @param cls identification of the client
249 * @param message the actual message
250 */
251static int
252check_search (void *cls,
253 const struct RegexSearchMessage *sm)
254{
255 struct ClientEntry *ce = cls;
256 const char *string;
257 uint16_t size;
258
259 size = ntohs (sm->header.size) - sizeof (*sm);
260 string = (const char *) &sm[1];
261 if ('\0' != string[size - 1])
262 {
263 GNUNET_break (0);
264 return GNUNET_SYSERR;
265 }
266 if (NULL != ce->sh)
267 {
268 /* only one search allowed per client */
269 GNUNET_break (0);
270 return GNUNET_SYSERR;
271 }
272 return GNUNET_OK;
273}
274
275
276/**
277 * Handle SEARCH message.
278 *
279 * @param cls identification of the client
280 * @param message the actual message
281 */
282static void
283handle_search (void *cls,
284 const struct RegexSearchMessage *sm)
285{
286 struct ClientEntry *ce = cls;
287 const char *string;
288
289 string = (const char *) &sm[1];
290 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
291 "Starting to search for `%s'\n",
292 string);
293 ce->sh = REGEX_INTERNAL_search (dht,
294 string,
295 &handle_search_result,
296 ce,
297 stats);
298 if (NULL == ce->sh)
299 {
300 GNUNET_break (0);
301 GNUNET_SERVICE_client_drop (ce->client);
302 return;
303 }
304 GNUNET_SERVICE_client_continue (ce->client);
305}
306
307
308/**
309 * Process regex requests.
310 *
311 * @param cls closure
312 * @param cfg configuration to use
313 * @param service the initialized service
314 */
315static void
316run (void *cls,
317 const struct GNUNET_CONFIGURATION_Handle *cfg,
318 struct GNUNET_SERVICE_Handle *service)
319{
320 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
321 if (NULL == my_private_key)
322 {
323 GNUNET_SCHEDULER_shutdown ();
324 return;
325 }
326 dht = GNUNET_DHT_connect (cfg, 1024);
327 if (NULL == dht)
328 {
329 GNUNET_free (my_private_key);
330 my_private_key = NULL;
331 GNUNET_SCHEDULER_shutdown ();
332 return;
333 }
334 GNUNET_SCHEDULER_add_shutdown (&cleanup_task,
335 NULL);
336 stats = GNUNET_STATISTICS_create ("regex", cfg);
337}
338
339
340/**
341 * Callback called when a client connects to the service.
342 *
343 * @param cls closure for the service
344 * @param c the new client that connected to the service
345 * @param mq the message queue used to send messages to the client
346 * @return @a c
347 */
348static void *
349client_connect_cb (void *cls,
350 struct GNUNET_SERVICE_Client *c,
351 struct GNUNET_MQ_Handle *mq)
352{
353 struct ClientEntry *ce;
354
355 ce = GNUNET_new (struct ClientEntry);
356 ce->client = c;
357 ce->mq = mq;
358 return ce;
359}
360
361
362/**
363 * Callback called when a client disconnected from the service
364 *
365 * @param cls closure for the service
366 * @param c the client that disconnected
367 * @param internal_cls should be equal to @a c
368 */
369static void
370client_disconnect_cb (void *cls,
371 struct GNUNET_SERVICE_Client *c,
372 void *internal_cls)
373{
374 struct ClientEntry *ce = internal_cls;
375
376 if (NULL != ce->refresh_task)
377 {
378 GNUNET_SCHEDULER_cancel (ce->refresh_task);
379 ce->refresh_task = NULL;
380 }
381 if (NULL != ce->ah)
382 {
383 REGEX_INTERNAL_announce_cancel (ce->ah);
384 ce->ah = NULL;
385 }
386 if (NULL != ce->sh)
387 {
388 REGEX_INTERNAL_search_cancel (ce->sh);
389 ce->sh = NULL;
390 }
391 GNUNET_free (ce);
392}
393
394
395/**
396 * Define "main" method using service macro.
397 */
398GNUNET_SERVICE_MAIN
399("regex",
400 GNUNET_SERVICE_OPTION_NONE,
401 &run,
402 &client_connect_cb,
403 &client_disconnect_cb,
404 NULL,
405 GNUNET_MQ_hd_var_size (announce,
406 GNUNET_MESSAGE_TYPE_REGEX_ANNOUNCE,
407 struct AnnounceMessage,
408 NULL),
409 GNUNET_MQ_hd_var_size (search,
410 GNUNET_MESSAGE_TYPE_REGEX_SEARCH,
411 struct RegexSearchMessage,
412 NULL),
413 GNUNET_MQ_handler_end ());
414
415
416/* end of gnunet-service-regex.c */