aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gnunet-service-gns_reverser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gns/gnunet-service-gns_reverser.c')
-rw-r--r--src/gns/gnunet-service-gns_reverser.c601
1 files changed, 0 insertions, 601 deletions
diff --git a/src/gns/gnunet-service-gns_reverser.c b/src/gns/gnunet-service-gns_reverser.c
deleted file mode 100644
index b5b8b31b7..000000000
--- a/src/gns/gnunet-service-gns_reverser.c
+++ /dev/null
@@ -1,601 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file gns/gnunet-service-gns_reverser.c
22 * @brief GNUnet GNS service
23 * @author Martin Schanzenbach
24 */
25
26
27#include "platform.h"
28#include "gnunet_gns_service.h"
29#include "gnunet-service-gns_resolver.h"
30#include "gnunet-service-gns_reverser.h"
31
32struct ReverseRecordEntry
33{
34 /**
35 * DLL
36 */
37 struct ReverseRecordEntry *next;
38
39 /**
40 * DLL
41 */
42 struct ReverseRecordEntry *prev;
43
44 /**
45 * ReverseRecord
46 */
47 struct GNUNET_GNSRECORD_ReverseRecord *record;
48
49 /**
50 * Record length
51 */
52 size_t record_len;
53
54};
55
56struct IteratorHandle
57{
58 /**
59 * Records found
60 */
61 struct ReverseRecordEntry *records_head;
62
63 /**
64 * Records found
65 */
66 struct ReverseRecordEntry *records_tail;
67
68 /**
69 * Record count
70 */
71 uint64_t record_count;
72
73 /**
74 * Current delegation to expect
75 */
76 struct GNUNET_CRYPTO_EcdsaPublicKey target;
77
78 /**
79 * Queue entry
80 */
81 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
82
83};
84
85struct ReverseTreeNode
86{
87 /**
88 * DLL
89 */
90 struct ReverseTreeNode *next;
91
92 /**
93 * DLL
94 */
95 struct ReverseTreeNode *prev;
96
97 /**
98 * Resolved name until now
99 */
100 char *name;
101
102 /**
103 * Depth of the resolution at this node
104 */
105 uint8_t depth;
106
107 /**
108 * The pkey of the namespace
109 */
110 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
111
112};
113
114
115struct GNS_ReverserHandle
116{
117 /**
118 * GNS resolver handle
119 */
120 struct GNS_ResolverHandle *rh;
121
122 /**
123 * The authority to look for
124 */
125 struct GNUNET_CRYPTO_EcdsaPublicKey authority;
126
127 /**
128 * Resolution candidate queue
129 */
130 struct ReverseTreeNode *node_queue_head;
131
132 /**
133 * Resolution candidate queue
134 */
135 struct ReverseTreeNode *node_queue_tail;
136
137 /**
138 * Max depth for the resolution
139 */
140 uint8_t max_depth;
141
142 /**
143 * Result callback
144 */
145 GNS_ReverseResultProcessor proc;
146
147 /**
148 * Callback closure
149 */
150 void *proc_cls;
151};
152
153/**
154 * Reverse record collection task
155 */
156static struct GNUNET_SCHEDULER_Task *reverse_record_check_task;
157
158/**
159 * NS iterator task
160 */
161static struct GNUNET_SCHEDULER_Task *it_task;
162
163/**
164 * GNS lookup handle
165 */
166static struct GNS_ResolverHandle *gns_lookup_reverse;
167
168/**
169 * NS handle
170 */
171static struct GNUNET_NAMESTORE_Handle *ns;
172
173/**
174 * NS Iterator
175 */
176static struct GNUNET_NAMESTORE_ZoneIterator *namestore_iter;
177
178/**
179 * The zone target for reverse record resolution
180 */
181static struct GNUNET_CRYPTO_EcdsaPublicKey myzone;
182
183/**
184 * The zone target for reverse record resolution
185 */
186static struct GNUNET_CRYPTO_EcdsaPrivateKey pzone;
187
188/**
189 * The nick of our zone
190 */
191static char *mynick;
192
193
194static void
195cleanup_handle (struct GNS_ReverserHandle *rh)
196{
197 struct ReverseTreeNode *rtn;
198
199 for (rtn = rh->node_queue_head; NULL != rtn; rtn = rh->node_queue_head)
200 {
201 if (NULL != rtn->name)
202 GNUNET_free (rtn->name);
203 GNUNET_CONTAINER_DLL_remove (rh->node_queue_head,
204 rh->node_queue_tail,
205 rtn);
206 GNUNET_free (rtn);
207 }
208 GNUNET_free (rh);
209}
210
211static void
212handle_gns_result (void *cls,
213 uint32_t rd_count,
214 const struct GNUNET_GNSRECORD_Data *rd)
215{
216 struct GNS_ReverserHandle *rh = cls;
217 const struct GNUNET_GNSRECORD_ReverseRecord *rr;
218 struct ReverseTreeNode *rtn;
219 char *result;
220 const char *name;
221 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
222 "Got result (%d)\n", rd_count);
223
224 for (int i = 0; i < rd_count; i++)
225 {
226 /**
227 * Check if we are in the delegation set
228 */
229 if (GNUNET_GNSRECORD_TYPE_REVERSE != rd[i].record_type)
230 continue;
231 rr = rd[i].data;
232 name = (const char*) &rr[1];
233 if (0 == memcmp (&rh->authority,
234 &rr->pkey,
235 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
236 {
237 //Found!
238 GNUNET_asprintf (&result,
239 "%s.%s.gnu",
240 rh->node_queue_head->name,
241 name);
242 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
243 "Found path from %s\n", result);
244
245 rh->proc (rh->proc_cls, result);
246 cleanup_handle (rh);
247 GNUNET_free (result);
248 return;
249 } else {
250 if (rh->node_queue_head->depth >= rh->max_depth)
251 break;
252 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
253 "Found REVERSE from %s\n", name);
254
255 rtn = GNUNET_new (struct ReverseTreeNode);
256 if (NULL == rh->node_queue_head->name)
257 rtn->name = GNUNET_strdup (name);
258 else
259 GNUNET_asprintf (&rtn->name,
260 "%s.%s",
261 rh->node_queue_head->name,
262 name);
263 rtn->depth = rh->node_queue_head->depth + 1;
264 rtn->pkey = rr->pkey;
265 GNUNET_CONTAINER_DLL_insert_tail (rh->node_queue_head,
266 rh->node_queue_tail,
267 rtn);
268 }
269 }
270
271 /**
272 * Done here remove node from queue
273 */
274 rtn = rh->node_queue_head;
275 if (NULL != rtn)
276 GNUNET_CONTAINER_DLL_remove (rh->node_queue_head,
277 rh->node_queue_tail,
278 rtn);
279 if (NULL == rh->node_queue_head)
280 {
281 //No luck
282 rh->proc (rh->proc_cls, NULL);
283 cleanup_handle (rh);
284 return;
285 }
286 rh->rh = GNS_resolver_lookup (&rh->node_queue_head->pkey,
287 GNUNET_GNSRECORD_TYPE_REVERSE,
288 "+.gnu",
289 NULL,
290 GNUNET_GNS_LO_DEFAULT,
291 &handle_gns_result,
292 rh);
293}
294
295/**
296 * Reverse lookup of a specific zone
297 * calls RecordLookupProcessor on result or timeout
298 *
299 * @param target the zone to perform the lookup in
300 * @param authority the authority
301 * @param proc the processor to call
302 * @param proc_cls the closure to pass to @a proc
303 * @return handle to cancel operation
304 */
305struct GNS_ReverserHandle *
306GNS_reverse_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *target,
307 const struct GNUNET_CRYPTO_EcdsaPublicKey *authority,
308 GNS_ReverseResultProcessor proc,
309 void *proc_cls)
310{
311 struct GNS_ReverserHandle *rh;
312 struct ReverseTreeNode *rtn;
313
314 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
315 "Starting reverse resolution\n");
316 rh = GNUNET_new (struct GNS_ReverserHandle);
317 rh->proc = proc;
318 rh->proc_cls = proc_cls;
319 rtn = GNUNET_new (struct ReverseTreeNode);
320 rtn->name = NULL;
321 rtn->pkey = *target;
322 rtn->depth = 0;
323 GNUNET_CONTAINER_DLL_insert (rh->node_queue_head,
324 rh->node_queue_tail,
325 rtn);
326 rh->authority = *authority;
327 rh->max_depth = 3; //TODO make argument
328 rh->rh = GNS_resolver_lookup (target,
329 GNUNET_GNSRECORD_TYPE_REVERSE,
330 "+.gnu",
331 NULL,
332 GNUNET_GNS_LO_DEFAULT,
333 &handle_gns_result,
334 rh);
335 return rh;
336}
337
338/**
339 * Cancel active resolution (i.e. client disconnected).
340 *
341 * @param rh resolution to abort
342 */
343void
344GNS_reverse_lookup_cancel (struct GNS_ReverserHandle *rh)
345{
346 cleanup_handle (rh);
347 return;
348}
349
350/********************************************
351 * Reverse iterator
352 * ******************************************/
353
354
355static void
356next_it (void *cls);
357
358static void
359handle_gns_result_iter (void *cls,
360 uint32_t rd_count,
361 const struct GNUNET_GNSRECORD_Data *rd)
362{
363 struct IteratorHandle *ith = cls;
364 struct ReverseRecordEntry *rr;
365 gns_lookup_reverse = NULL;
366 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
367 "GNS for REVERSE (%s)\n", mynick);
368
369
370 if ((rd_count != 1) ||
371 (GNUNET_GNSRECORD_TYPE_PKEY != rd->record_type))
372 {
373 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
374 "GNS invalid REVERSE (%s)\n", mynick);
375 gns_lookup_reverse = NULL;
376 it_task = GNUNET_SCHEDULER_add_now (&next_it, ith);
377 return;
378 }
379
380
381 rr = GNUNET_new (struct ReverseRecordEntry);
382 rr->record_len = sizeof (struct GNUNET_GNSRECORD_ReverseRecord)
383 + strlen (mynick) + 1;
384 rr->record = GNUNET_malloc (rr->record_len);
385 rr->record->pkey = ith->target;
386 rr->record->expiration.abs_value_us = rd->expiration_time;
387 GNUNET_memcpy ((char*)&rr->record[1],
388 mynick,
389 strlen (mynick));
390 GNUNET_CONTAINER_DLL_insert (ith->records_head,
391 ith->records_tail,
392 rr);
393 ith->record_count++;
394 it_task = GNUNET_SCHEDULER_add_now (&next_it, ith);
395}
396
397
398static void
399next_it (void *cls)
400{
401 it_task = NULL;
402 GNUNET_assert (NULL != namestore_iter);
403 GNUNET_NAMESTORE_zone_iterator_next (namestore_iter);
404}
405
406
407static void
408iterator_cb (void *cls,
409 const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
410 const char *label,
411 unsigned int rd_count,
412 const struct GNUNET_GNSRECORD_Data *rd)
413{
414 struct IteratorHandle *ith = cls;
415 struct GNUNET_CRYPTO_EcdsaPublicKey zone;
416 char *name;
417
418 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
419 "iterating for REVERSE (%s / %s)\n",
420 label,
421 mynick);
422
423
424 if ((rd_count != 1) ||
425 (GNUNET_GNSRECORD_TYPE_PKEY != rd->record_type))
426 {
427 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
428 "wrong format (%s)\n", mynick);
429
430
431 it_task = GNUNET_SCHEDULER_add_now (&next_it, ith);
432 return;
433 }
434 GNUNET_CRYPTO_ecdsa_key_get_public (key,
435 &zone);
436 if (0 != memcmp (&zone, &myzone,
437 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
438 {
439 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
440 "wrong zone (%s)\n", mynick);
441
442
443 it_task = GNUNET_SCHEDULER_add_now (&next_it, ith);
444 return;
445 }
446 ith->target = *((struct GNUNET_CRYPTO_EcdsaPublicKey *) rd->data);
447 GNUNET_asprintf (&name,
448 "%s.gnu",
449 mynick);
450 gns_lookup_reverse = GNS_resolver_lookup (&ith->target,
451 GNUNET_GNSRECORD_TYPE_PKEY,
452 name,
453 NULL,
454 GNUNET_GNS_LO_DEFAULT,
455 &handle_gns_result_iter,
456 ith);
457 GNUNET_free (name);
458}
459
460static void check_reverse_records (void *cls);
461
462static void
463store_reverse (void *cls,
464 int32_t success,
465 const char *emsg)
466{
467 struct IteratorHandle *ith = cls;
468 struct ReverseRecordEntry *rr;
469
470 if (GNUNET_SYSERR == success)
471 {
472 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
473 "%s\n",
474 emsg);
475 }
476 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stored records (%s)\n", mynick);
477
478 for (rr = ith->records_head; NULL != rr; rr = ith->records_head)
479 {
480 GNUNET_CONTAINER_DLL_remove (ith->records_head,
481 ith->records_tail,
482 rr);
483 GNUNET_free (rr->record);
484 GNUNET_free (rr);
485 }
486 reverse_record_check_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_DAYS,
487 &check_reverse_records,
488 NULL);
489 GNUNET_free (ith);
490}
491
492
493static void
494finished_cb (void *cls)
495{
496 struct IteratorHandle *ith = cls;
497 struct ReverseRecordEntry *rr;
498 struct GNUNET_GNSRECORD_Data rd[ith->record_count];
499
500 memset (rd, 0, sizeof (struct GNUNET_GNSRECORD_Data) * ith->record_count);
501
502 rr = ith->records_head;
503 for (int i = 0; i < ith->record_count; i++)
504 {
505 rd[i].data_size = rr->record_len;
506 rd[i].data = GNUNET_malloc (rr->record_len);
507 rd[i].record_type = GNUNET_GNSRECORD_TYPE_REVERSE;
508 rd[i].expiration_time = rr->record->expiration.abs_value_us;
509 GNUNET_memcpy ((char*) rd[i].data,
510 rr->record,
511 rr->record_len);
512 rr = rr->next;
513 }
514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
515 "Finished iterating for REVERSE\n");
516
517 ith->ns_qe = GNUNET_NAMESTORE_records_store (ns,
518 &pzone,
519 "+",
520 ith->record_count,
521 rd,
522 &store_reverse,
523 ith);
524 namestore_iter = NULL;
525
526}
527
528
529static void
530it_error (void *cls)
531{
532 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
533 "Error iterating for REVERSE\n");
534}
535
536
537static void
538check_reverse_records (void *cls)
539{
540 struct IteratorHandle *ith;
541 ith = GNUNET_new (struct IteratorHandle);
542 ith->record_count = 0;
543 reverse_record_check_task = NULL;
544 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
545 "Start iterating for REVERSE (%s)\n", mynick);
546 namestore_iter = GNUNET_NAMESTORE_zone_iteration_start (ns,
547 NULL,
548 &it_error,
549 ith,
550 &iterator_cb,
551 ith,
552 &finished_cb,
553 ith);
554}
555
556
557/**
558 * Initialize reverser
559 *
560 * @param nh handle to a namestore
561 * @param key the private key of the gns-reverse zone
562 * @param name the name of the gns-reverse zone
563 * @return GNUNET_OK
564 */
565int
566GNS_reverse_init (struct GNUNET_NAMESTORE_Handle *nh,
567 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
568 const char *nick)
569{
570 GNUNET_asprintf (&mynick,
571 "%s",
572 nick);
573 GNUNET_CRYPTO_ecdsa_key_get_public (zone,
574 &myzone);
575 GNUNET_memcpy (&pzone,
576 zone,
577 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
578 ns = nh;
579 reverse_record_check_task = GNUNET_SCHEDULER_add_now (&check_reverse_records,
580 NULL);
581 return GNUNET_OK;
582}
583
584/**
585 * Cleanup reverser
586 */
587void
588GNS_reverse_done ()
589{
590 if (NULL != mynick)
591 GNUNET_free (mynick);
592 if (NULL != it_task)
593 GNUNET_SCHEDULER_cancel (it_task);
594 if (NULL != reverse_record_check_task)
595 GNUNET_SCHEDULER_cancel (reverse_record_check_task);
596 if (NULL != gns_lookup_reverse)
597 GNS_resolver_lookup_cancel (gns_lookup_reverse);
598 if (NULL != namestore_iter)
599 GNUNET_NAMESTORE_zone_iteration_stop (namestore_iter);
600}
601