aboutsummaryrefslogtreecommitdiff
path: root/src/namestore/namestore_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/namestore/namestore_api.c')
-rw-r--r--src/namestore/namestore_api.c1563
1 files changed, 0 insertions, 1563 deletions
diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c
deleted file mode 100644
index 2c5efb745..000000000
--- a/src/namestore/namestore_api.c
+++ /dev/null
@@ -1,1563 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010-2013, 2016 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
21/**
22 * @file namestore/namestore_api.c
23 * @brief API to access the NAMESTORE service
24 * @author Martin Schanzenbach
25 * @author Matthias Wachs
26 * @author Christian Grothoff
27 */
28
29#include "platform.h"
30#include "gnunet_error_codes.h"
31#include "gnunet_util_lib.h"
32#include "gnunet_constants.h"
33#include "gnunet_arm_service.h"
34#include "gnunet_signatures.h"
35#include "gnunet_gns_service.h"
36#include "gnunet_namestore_service.h"
37#include "namestore.h"
38
39
40#define LOG(kind, ...) GNUNET_log_from (kind, "namestore-api", __VA_ARGS__)
41
42/**
43 * We grant the namestore up to 1 minute of latency, if it is slower than
44 * that, store queries will fail.
45 */
46#define NAMESTORE_DELAY_TOLERANCE GNUNET_TIME_UNIT_MINUTES
47
48/**
49 * An QueueEntry used to store information for a pending
50 * NAMESTORE record operation
51 */
52struct GNUNET_NAMESTORE_QueueEntry
53{
54 /**
55 * Kept in a DLL.
56 */
57 struct GNUNET_NAMESTORE_QueueEntry *next;
58
59 /**
60 * Kept in a DLL.
61 */
62 struct GNUNET_NAMESTORE_QueueEntry *prev;
63
64 /**
65 * Main handle to access the namestore.
66 */
67 struct GNUNET_NAMESTORE_Handle *h;
68
69 /**
70 * Continuation to call
71 */
72 GNUNET_NAMESTORE_ContinuationWithStatus cont;
73
74 /**
75 * Closure for @e cont.
76 */
77 void *cont_cls;
78
79 /**
80 * Function to call with the records we get back; or NULL.
81 */
82 GNUNET_NAMESTORE_RecordMonitor proc;
83
84 /**
85 * Function to call with the records we get back; or NULL.
86 */
87 GNUNET_NAMESTORE_RecordSetMonitor proc2;
88
89 /**
90 * Closure for @e proc.
91 */
92 void *proc_cls;
93
94 /**
95 * Function to call on errors.
96 */
97 GNUNET_SCHEDULER_TaskCallback error_cb;
98
99 /**
100 * Closure for @e error_cb.
101 */
102 void *error_cb_cls;
103
104 /**
105 * Envelope of the message to send to the service, if not yet
106 * sent.
107 */
108 struct GNUNET_MQ_Envelope *env;
109
110 /**
111 * Task scheduled to warn us if the namestore is way too slow.
112 */
113 struct GNUNET_SCHEDULER_Task *timeout_task;
114
115 /**
116 * The operation id this zone iteration operation has
117 */
118 uint32_t op_id;
119};
120
121
122/**
123 * Handle for a zone iterator operation
124 */
125struct GNUNET_NAMESTORE_ZoneIterator
126{
127 /**
128 * Kept in a DLL.
129 */
130 struct GNUNET_NAMESTORE_ZoneIterator *next;
131
132 /**
133 * Kept in a DLL.
134 */
135 struct GNUNET_NAMESTORE_ZoneIterator *prev;
136
137 /**
138 * Main handle to access the namestore.
139 */
140 struct GNUNET_NAMESTORE_Handle *h;
141
142 /**
143 * Function to call on completion.
144 */
145 GNUNET_SCHEDULER_TaskCallback finish_cb;
146
147 /**
148 * Closure for @e error_cb.
149 */
150 void *finish_cb_cls;
151
152 /**
153 * The continuation to call with the results
154 */
155 GNUNET_NAMESTORE_RecordMonitor proc;
156
157 /**
158 * The continuation to call with the results
159 */
160 GNUNET_NAMESTORE_RecordSetMonitor proc2;
161
162 /**
163 * Closure for @e proc.
164 */
165 void *proc_cls;
166
167 /**
168 * Function to call on errors.
169 */
170 GNUNET_SCHEDULER_TaskCallback error_cb;
171
172 /**
173 * Closure for @e error_cb.
174 */
175 void *error_cb_cls;
176
177 /**
178 * Envelope of the message to send to the service, if not yet
179 * sent.
180 */
181 struct GNUNET_MQ_Envelope *env;
182
183 /**
184 * Private key of the zone.
185 */
186 struct GNUNET_IDENTITY_PrivateKey zone;
187
188 /**
189 * The operation id this zone iteration operation has
190 */
191 uint32_t op_id;
192};
193
194
195/**
196 * Connection to the NAMESTORE service.
197 */
198struct GNUNET_NAMESTORE_Handle
199{
200 /**
201 * Configuration to use.
202 */
203 const struct GNUNET_CONFIGURATION_Handle *cfg;
204
205 /**
206 * Connection to the service (if available).
207 */
208 struct GNUNET_MQ_Handle *mq;
209
210 /**
211 * Head of pending namestore queue entries
212 */
213 struct GNUNET_NAMESTORE_QueueEntry *op_head;
214
215 /**
216 * Tail of pending namestore queue entries
217 */
218 struct GNUNET_NAMESTORE_QueueEntry *op_tail;
219
220 /**
221 * Head of pending namestore zone iterator entries
222 */
223 struct GNUNET_NAMESTORE_ZoneIterator *z_head;
224
225 /**
226 * Tail of pending namestore zone iterator entries
227 */
228 struct GNUNET_NAMESTORE_ZoneIterator *z_tail;
229
230 /**
231 * Reconnect task
232 */
233 struct GNUNET_SCHEDULER_Task *reconnect_task;
234
235 /**
236 * Delay introduced before we reconnect.
237 */
238 struct GNUNET_TIME_Relative reconnect_delay;
239
240 /**
241 * Should we reconnect to service due to some serious error?
242 */
243 int reconnect;
244
245 /**
246 * The last operation id used for a NAMESTORE operation
247 */
248 uint32_t last_op_id_used;
249};
250
251
252/**
253 * Disconnect from service and then reconnect.
254 *
255 * @param h our handle
256 */
257static void
258force_reconnect (struct GNUNET_NAMESTORE_Handle *h);
259
260
261/**
262 * Find the queue entry that matches the @a rid
263 *
264 * @param h namestore handle
265 * @param rid id to look up
266 * @return NULL if @a rid was not found
267 */
268static struct GNUNET_NAMESTORE_QueueEntry *
269find_qe (struct GNUNET_NAMESTORE_Handle *h, uint32_t rid)
270{
271 struct GNUNET_NAMESTORE_QueueEntry *qe;
272
273 for (qe = h->op_head; qe != NULL; qe = qe->next)
274 if (qe->op_id == rid)
275 return qe;
276 return NULL;
277}
278
279
280/**
281 * Find the zone iteration entry that matches the @a rid
282 *
283 * @param h namestore handle
284 * @param rid id to look up
285 * @return NULL if @a rid was not found
286 */
287static struct GNUNET_NAMESTORE_ZoneIterator *
288find_zi (struct GNUNET_NAMESTORE_Handle *h, uint32_t rid)
289{
290 struct GNUNET_NAMESTORE_ZoneIterator *ze;
291
292 for (ze = h->z_head; ze != NULL; ze = ze->next)
293 if (ze->op_id == rid)
294 return ze;
295 return NULL;
296}
297
298
299/**
300 * Free @a qe.
301 *
302 * @param qe entry to free
303 */
304static void
305free_qe (struct GNUNET_NAMESTORE_QueueEntry *qe)
306{
307 struct GNUNET_NAMESTORE_Handle *h = qe->h;
308
309 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, qe);
310 if (NULL != qe->env)
311 GNUNET_MQ_discard (qe->env);
312 if (NULL != qe->timeout_task)
313 GNUNET_SCHEDULER_cancel (qe->timeout_task);
314 GNUNET_free (qe);
315}
316
317
318/**
319 * Free @a ze.
320 *
321 * @param ze entry to free
322 */
323static void
324free_ze (struct GNUNET_NAMESTORE_ZoneIterator *ze)
325{
326 struct GNUNET_NAMESTORE_Handle *h = ze->h;
327
328 GNUNET_CONTAINER_DLL_remove (h->z_head, h->z_tail, ze);
329 if (NULL != ze->env)
330 GNUNET_MQ_discard (ze->env);
331 GNUNET_free (ze);
332}
333
334
335/**
336 * Check that @a rd_buf of length @a rd_len contains
337 * @a rd_count records.
338 *
339 * @param rd_len length of @a rd_buf
340 * @param rd_buf buffer with serialized records
341 * @param rd_count number of records expected
342 * @return #GNUNET_OK if @a rd_buf is well-formed
343 */
344static int
345check_rd (size_t rd_len, const void *rd_buf, unsigned int rd_count)
346{
347 struct GNUNET_GNSRECORD_Data rd[rd_count];
348
349 if (GNUNET_OK !=
350 GNUNET_GNSRECORD_records_deserialize (rd_len, rd_buf, rd_count, rd))
351 {
352 GNUNET_break (0);
353 return GNUNET_SYSERR;
354 }
355 return GNUNET_OK;
356}
357
358/**
359 * Handle an incoming message of type
360 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
361 *
362 * @param cls
363 * @param msg the message we received
364 */
365static void
366handle_record_store_response (void *cls,
367 const struct RecordStoreResponseMessage *msg)
368{
369 struct GNUNET_NAMESTORE_Handle *h = cls;
370 struct GNUNET_NAMESTORE_QueueEntry *qe;
371 enum GNUNET_ErrorCode res;
372
373 qe = find_qe (h, ntohl (msg->gns_header.r_id));
374 res = ntohl (msg->ec);
375 LOG (GNUNET_ERROR_TYPE_DEBUG,
376 "Received RECORD_STORE_RESPONSE with result %d\n",
377 res);
378 if (NULL == qe)
379 return;
380 if (NULL != qe->cont)
381 qe->cont (qe->cont_cls, res);
382 free_qe (qe);
383}
384
385
386/**
387 * Check validity of an incoming message of type
388 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE
389 *
390 * @param cls
391 * @param msg the message we received
392 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
393 */
394static int
395check_lookup_result (void *cls, const struct LabelLookupResponseMessage *msg)
396{
397 const char *name;
398 size_t exp_msg_len;
399 size_t msg_len;
400 size_t name_len;
401 size_t rd_len;
402 size_t key_len;
403
404 (void) cls;
405 rd_len = ntohs (msg->rd_len);
406 msg_len = ntohs (msg->gns_header.header.size);
407 name_len = ntohs (msg->name_len);
408 key_len = ntohs (msg->key_len);
409 exp_msg_len = sizeof(*msg) + name_len + rd_len + key_len;
410 if (0 != ntohs (msg->reserved))
411 {
412 GNUNET_break (0);
413 return GNUNET_SYSERR;
414 }
415 if (msg_len != exp_msg_len)
416 {
417 GNUNET_break (0);
418 return GNUNET_SYSERR;
419 }
420 name = (const char *) &msg[1] + key_len;
421 if ((name_len > 0) && ('\0' != name[name_len - 1]))
422 {
423 GNUNET_break (0);
424 return GNUNET_SYSERR;
425 }
426 if (GNUNET_NO == ntohs (msg->found))
427 {
428 if (0 != ntohs (msg->rd_count))
429 {
430 GNUNET_break (0);
431 return GNUNET_SYSERR;
432 }
433 return GNUNET_OK;
434 }
435 return check_rd (rd_len, &name[name_len], ntohs (msg->rd_count));
436}
437
438
439/**
440 * Handle an incoming message of type
441 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE
442 *
443 * @param cls
444 * @param msg the message we received
445 */
446static void
447handle_lookup_result (void *cls, const struct LabelLookupResponseMessage *msg)
448{
449 struct GNUNET_NAMESTORE_Handle *h = cls;
450 struct GNUNET_NAMESTORE_QueueEntry *qe;
451 struct GNUNET_IDENTITY_PrivateKey private_key;
452 const char *name;
453 const char *rd_tmp;
454 size_t name_len;
455 size_t rd_len;
456 size_t key_len;
457 size_t kbytes_read;
458 unsigned int rd_count;
459 int16_t found = (int16_t) ntohs (msg->found);
460
461 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_LOOKUP_RESULT (found=%i)\n",
462 found);
463 qe = find_qe (h, ntohl (msg->gns_header.r_id));
464 if (NULL == qe)
465 return;
466 rd_len = ntohs (msg->rd_len);
467 rd_count = ntohs (msg->rd_count);
468 name_len = ntohs (msg->name_len);
469 key_len = ntohs (msg->key_len);
470 GNUNET_assert (GNUNET_SYSERR !=
471 GNUNET_IDENTITY_read_private_key_from_buffer (&msg[1],
472 key_len,
473 &private_key,
474 &kbytes_read));
475 GNUNET_assert (kbytes_read == key_len);
476 name = (const char *) &msg[1] + key_len;
477 if (GNUNET_NO == found)
478 {
479 /* label was not in namestore */
480 if (NULL != qe->proc)
481 qe->proc (qe->proc_cls, &private_key, name, 0, NULL);
482 free_qe (qe);
483 return;
484 }
485 if (GNUNET_SYSERR == found)
486 {
487 if (NULL != qe->error_cb)
488 qe->error_cb (qe->error_cb_cls);
489 free_qe (qe);
490 return;
491 }
492
493 rd_tmp = &name[name_len];
494 {
495 struct GNUNET_GNSRECORD_Data rd[rd_count];
496
497 GNUNET_assert (
498 GNUNET_OK ==
499 GNUNET_GNSRECORD_records_deserialize (rd_len, rd_tmp, rd_count, rd));
500 if (0 == name_len)
501 name = NULL;
502 if (NULL != qe->proc)
503 qe->proc (qe->proc_cls,
504 &private_key,
505 name,
506 rd_count,
507 (rd_count > 0) ? rd : NULL);
508 }
509 free_qe (qe);
510}
511
512
513/**
514 * Handle an incoming message of type
515 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
516 *
517 * @param cls
518 * @param msg the message we received
519 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
520 */
521static int
522check_record_result (void *cls, const struct RecordResultMessage *msg)
523{
524 const char *name;
525 size_t msg_len;
526 size_t name_len;
527 size_t rd_len;
528 size_t key_len;
529
530 (void) cls;
531 rd_len = ntohs (msg->rd_len);
532 msg_len = ntohs (msg->gns_header.header.size);
533 key_len = ntohs (msg->key_len);
534 name_len = ntohs (msg->name_len);
535 if (msg_len != sizeof(struct RecordResultMessage) + key_len + name_len
536 + rd_len)
537 {
538 GNUNET_break (0);
539 return GNUNET_SYSERR;
540 }
541 name = (const char *) &msg[1] + key_len;
542 if ((0 == name_len) || ('\0' != name[name_len - 1]))
543 {
544 GNUNET_break (0);
545 return GNUNET_SYSERR;
546 }
547 if (0 == key_len)
548 {
549 GNUNET_break (0);
550 return GNUNET_SYSERR;
551 }
552 return check_rd (rd_len, &name[name_len], ntohs (msg->rd_count));
553}
554
555
556/**
557 * Handle an incoming message of type
558 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
559 *
560 * @param cls
561 * @param msg the message we received
562 */
563static void
564handle_record_result (void *cls, const struct RecordResultMessage *msg)
565{
566 struct GNUNET_NAMESTORE_Handle *h = cls;
567 struct GNUNET_NAMESTORE_QueueEntry *qe;
568 struct GNUNET_NAMESTORE_ZoneIterator *ze;
569 struct GNUNET_IDENTITY_PrivateKey private_key;
570 const char *name;
571 const char *rd_tmp;
572 size_t name_len;
573 size_t rd_len;
574 size_t key_len;
575 size_t kbytes_read;
576 unsigned int rd_count;
577
578 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_RESULT\n");
579 rd_len = ntohs (msg->rd_len);
580 rd_count = ntohs (msg->rd_count);
581 name_len = ntohs (msg->name_len);
582 key_len = ntohs (msg->key_len);
583 ze = find_zi (h, ntohl (msg->gns_header.r_id));
584 qe = find_qe (h, ntohl (msg->gns_header.r_id));
585 if ((NULL == ze) && (NULL == qe))
586 return; /* rid not found */
587 if ((NULL != ze) && (NULL != qe))
588 {
589 GNUNET_break (0); /* rid ambiguous */
590 force_reconnect (h);
591 return;
592 }
593 name = (const char *) &msg[1] + key_len;
594 GNUNET_assert (GNUNET_SYSERR !=
595 GNUNET_IDENTITY_read_private_key_from_buffer (&msg[1],
596 key_len,
597 &private_key,
598 &kbytes_read));
599 GNUNET_assert (kbytes_read == key_len);
600 rd_tmp = &name[name_len];
601 {
602 struct GNUNET_GNSRECORD_Data rd[rd_count];
603
604 GNUNET_assert (
605 GNUNET_OK ==
606 GNUNET_GNSRECORD_records_deserialize (rd_len, rd_tmp, rd_count, rd));
607 if (0 == name_len)
608 name = NULL;
609 if (NULL != qe)
610 {
611 if (NULL != qe->proc)
612 qe->proc (qe->proc_cls,
613 &private_key,
614 name,
615 rd_count,
616 (rd_count > 0) ? rd : NULL);
617 free_qe (qe);
618 return;
619 }
620 if (NULL != ze)
621 {
622 // Store them here because a callback could free ze
623 GNUNET_NAMESTORE_RecordMonitor proc;
624 GNUNET_NAMESTORE_RecordSetMonitor proc2;
625 void *proc_cls = ze->proc_cls;
626 proc = ze->proc;
627 proc2 = ze->proc2;
628 if (NULL != proc)
629 proc (proc_cls, &private_key, name, rd_count, rd);
630 if (NULL != proc2)
631 proc2 (proc_cls, &private_key, name,
632 rd_count, rd, GNUNET_TIME_absolute_ntoh (msg->expire));
633 return;
634 }
635 }
636 GNUNET_assert (0);
637}
638
639
640/**
641 * Handle an incoming message of type
642 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT_END
643 *
644 * @param cls
645 * @param msg the message we received
646 */
647static void
648handle_record_result_end (void *cls, const struct GNUNET_NAMESTORE_Header *msg)
649{
650 struct GNUNET_NAMESTORE_Handle *h = cls;
651 struct GNUNET_NAMESTORE_QueueEntry *qe;
652 struct GNUNET_NAMESTORE_ZoneIterator *ze;
653
654 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_RESULT_END\n");
655 ze = find_zi (h, ntohl (msg->r_id));
656 qe = find_qe (h, ntohl (msg->r_id));
657 if ((NULL == ze) && (NULL == qe))
658 return; /* rid not found */
659 if ((NULL != ze) && (NULL != qe))
660 {
661 GNUNET_break (0); /* rid ambiguous */
662 force_reconnect (h);
663 return;
664 }
665 LOG (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration completed!\n");
666 if (NULL == ze)
667 {
668 GNUNET_break (0);
669 force_reconnect (h);
670 return;
671 }
672 if (NULL != ze->finish_cb)
673 ze->finish_cb (ze->finish_cb_cls);
674 free_ze (ze);
675}
676
677static void
678handle_tx_control_result (void *cls,
679 const struct TxControlResultMessage *msg)
680{
681 struct GNUNET_NAMESTORE_Handle *h = cls;
682 struct GNUNET_NAMESTORE_QueueEntry *qe;
683 enum GNUNET_ErrorCode res;
684
685 qe = find_qe (h, ntohl (msg->gns_header.r_id));
686 res = ntohs (msg->ec);
687 LOG (GNUNET_ERROR_TYPE_DEBUG,
688 "Received TX_CONTROL_RESULT with result %d\n",
689 res);
690 if (NULL == qe)
691 return;
692 if (NULL != qe->cont)
693 qe->cont (qe->cont_cls, res);
694 free_qe (qe);
695}
696
697/**
698 * Handle an incoming message of type
699 * #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
700 *
701 * @param qe the respective entry in the message queue
702 * @param msg the message we received
703 * @return #GNUNET_OK on success, #GNUNET_SYSERR if message malformed
704 */
705static int
706check_zone_to_name_response (void *cls,
707 const struct ZoneToNameResponseMessage *msg)
708{
709 size_t name_len;
710 size_t rd_ser_len;
711 size_t key_len;
712 const char *name_tmp;
713
714 (void) cls;
715 if (GNUNET_EC_NONE != ntohl (msg->ec))
716 return GNUNET_OK;
717 key_len = ntohs (msg->key_len);
718 name_len = ntohs (msg->name_len);
719 rd_ser_len = ntohs (msg->rd_len);
720 if (ntohs (msg->gns_header.header.size) !=
721 sizeof(struct ZoneToNameResponseMessage) + key_len + name_len
722 + rd_ser_len)
723 {
724 GNUNET_break (0);
725 return GNUNET_SYSERR;
726 }
727 name_tmp = (const char *) &msg[1] + key_len;
728 if ((name_len > 0) && ('\0' != name_tmp[name_len - 1]))
729 {
730 GNUNET_break (0);
731 return GNUNET_SYSERR;
732 }
733 return check_rd (rd_ser_len, &name_tmp[name_len], ntohs (msg->rd_count));
734}
735
736
737/**
738 * Handle an incoming message of type
739 * #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
740 *
741 * @param cls
742 * @param msg the message we received
743 */
744static void
745handle_zone_to_name_response (void *cls,
746 const struct ZoneToNameResponseMessage *msg)
747{
748 struct GNUNET_NAMESTORE_Handle *h = cls;
749 struct GNUNET_NAMESTORE_QueueEntry *qe;
750 struct GNUNET_IDENTITY_PrivateKey zone;
751 enum GNUNET_ErrorCode res;
752 size_t name_len;
753 size_t rd_ser_len;
754 unsigned int rd_count;
755 const char *name_tmp;
756 const char *rd_tmp;
757 size_t key_len;
758 size_t kbytes_read;
759
760 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_TO_NAME_RESPONSE\n");
761 qe = find_qe (h, ntohl (msg->gns_header.r_id));
762 if (NULL == qe)
763 {
764 LOG (GNUNET_ERROR_TYPE_WARNING,
765 "Response queue already gone...\n");
766 return;
767 }
768 res = ntohl (msg->ec);
769 key_len = ntohs (msg->key_len);
770 GNUNET_assert (GNUNET_SYSERR !=
771 GNUNET_IDENTITY_read_private_key_from_buffer (&msg[1],
772 key_len,
773 &zone,
774 &kbytes_read));
775 GNUNET_assert (kbytes_read == key_len);
776 switch (res)
777 {
778 break;
779
780 case GNUNET_EC_NAMESTORE_NO_RESULTS:
781 LOG (GNUNET_ERROR_TYPE_DEBUG,
782 "Namestore has no result for zone to name mapping \n");
783 if (NULL != qe->proc)
784 qe->proc (qe->proc_cls, &zone, NULL, 0, NULL);
785 free_qe (qe);
786 return;
787
788 case GNUNET_EC_NONE:
789 LOG (GNUNET_ERROR_TYPE_DEBUG,
790 "Namestore has result for zone to name mapping \n");
791 name_len = ntohs (msg->name_len);
792 rd_count = ntohs (msg->rd_count);
793 rd_ser_len = ntohs (msg->rd_len);
794 name_tmp = (const char *) &msg[1] + key_len;
795 rd_tmp = &name_tmp[name_len];
796 {
797 struct GNUNET_GNSRECORD_Data rd[rd_count];
798
799 GNUNET_assert (GNUNET_OK ==
800 GNUNET_GNSRECORD_records_deserialize (rd_ser_len,
801 rd_tmp,
802 rd_count,
803 rd));
804 /* normal end, call continuation with result */
805 if (NULL != qe->proc)
806 qe->proc (qe->proc_cls, &zone, name_tmp, rd_count, rd);
807 /* return is important here: break would call continuation with error! */
808 free_qe (qe);
809 return;
810 }
811
812 default:
813 LOG (GNUNET_ERROR_TYPE_DEBUG,
814 "An error occurred during zone to name operation: %s\n",
815 GNUNET_ErrorCode_get_hint (res));
816 break;
817 }
818 /* error case, call continuation with error */
819 if (NULL != qe->error_cb)
820 qe->error_cb (qe->error_cb_cls);
821 free_qe (qe);
822}
823
824
825/**
826 * Generic error handler, called with the appropriate error code and
827 * the same closure specified at the creation of the message queue.
828 * Not every message queue implementation supports an error handler.
829 *
830 * @param cls closure with the `struct GNUNET_NAMESTORE_Handle *`
831 * @param error error code
832 */
833static void
834mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
835{
836 struct GNUNET_NAMESTORE_Handle *h = cls;
837
838 (void) error;
839 force_reconnect (h);
840}
841
842
843/**
844 * Reconnect to namestore service.
845 *
846 * @param h the handle to the NAMESTORE service
847 */
848static void
849reconnect (struct GNUNET_NAMESTORE_Handle *h)
850{
851 struct GNUNET_MQ_MessageHandler handlers[] =
852 { GNUNET_MQ_hd_fixed_size (record_store_response,
853 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE,
854 struct RecordStoreResponseMessage,
855 h),
856 GNUNET_MQ_hd_var_size (zone_to_name_response,
857 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE,
858 struct ZoneToNameResponseMessage,
859 h),
860 GNUNET_MQ_hd_var_size (record_result,
861 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT,
862 struct RecordResultMessage,
863 h),
864 GNUNET_MQ_hd_fixed_size (record_result_end,
865 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT_END,
866 struct GNUNET_NAMESTORE_Header,
867 h),
868 GNUNET_MQ_hd_var_size (lookup_result,
869 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE,
870 struct LabelLookupResponseMessage,
871 h),
872 GNUNET_MQ_hd_fixed_size (tx_control_result,
873 GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL_RESULT,
874 struct TxControlResultMessage,
875 h),
876 GNUNET_MQ_handler_end () };
877 struct GNUNET_NAMESTORE_ZoneIterator *it;
878 struct GNUNET_NAMESTORE_QueueEntry *qe;
879
880 GNUNET_assert (NULL == h->mq);
881 h->mq =
882 GNUNET_CLIENT_connect (h->cfg, "namestore", handlers, &mq_error_handler, h);
883 if (NULL == h->mq)
884 return;
885 /* re-transmit pending requests that waited for a reconnect... */
886 for (it = h->z_head; NULL != it; it = it->next)
887 {
888 GNUNET_MQ_send (h->mq, it->env);
889 it->env = NULL;
890 }
891 for (qe = h->op_head; NULL != qe; qe = qe->next)
892 {
893 GNUNET_MQ_send (h->mq, qe->env);
894 qe->env = NULL;
895 }
896}
897
898
899/**
900 * Re-establish the connection to the service.
901 *
902 * @param cls handle to use to re-connect.
903 */
904static void
905reconnect_task (void *cls)
906{
907 struct GNUNET_NAMESTORE_Handle *h = cls;
908
909 h->reconnect_task = NULL;
910 reconnect (h);
911}
912
913
914/**
915 * Disconnect from service and then reconnect.
916 *
917 * @param h our handle
918 */
919static void
920force_reconnect (struct GNUNET_NAMESTORE_Handle *h)
921{
922 struct GNUNET_NAMESTORE_ZoneIterator *ze;
923 struct GNUNET_NAMESTORE_QueueEntry *qe;
924
925 GNUNET_MQ_destroy (h->mq);
926 h->mq = NULL;
927 while (NULL != (ze = h->z_head))
928 {
929 if (NULL != ze->error_cb)
930 ze->error_cb (ze->error_cb_cls);
931 free_ze (ze);
932 }
933 while (NULL != (qe = h->op_head))
934 {
935 if (NULL != qe->error_cb)
936 qe->error_cb (qe->error_cb_cls);
937 if (NULL != qe->cont)
938 qe->cont (qe->cont_cls,
939 GNUNET_EC_NAMESTORE_UNKNOWN);
940 free_qe (qe);
941 }
942
943 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting to namestore\n");
944 h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay);
945 h->reconnect_task =
946 GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect_task, h);
947}
948
949
950/**
951 * Get a fresh operation id to distinguish between namestore requests
952 *
953 * @param h the namestore handle
954 * @return next operation id to use
955 */
956static uint32_t
957get_op_id (struct GNUNET_NAMESTORE_Handle *h)
958{
959 return h->last_op_id_used++;
960}
961
962
963/**
964 * Initialize the connection with the NAMESTORE service.
965 *
966 * @param cfg configuration to use
967 * @return handle to the GNS service, or NULL on error
968 */
969struct GNUNET_NAMESTORE_Handle *
970GNUNET_NAMESTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
971{
972 struct GNUNET_NAMESTORE_Handle *h;
973
974 h = GNUNET_new (struct GNUNET_NAMESTORE_Handle);
975 h->cfg = cfg;
976 reconnect (h);
977 if (NULL == h->mq)
978 {
979 GNUNET_free (h);
980 return NULL;
981 }
982 return h;
983}
984
985
986/**
987 * Disconnect from the namestore service (and free associated
988 * resources).
989 *
990 * @param h handle to the namestore
991 */
992void
993GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h)
994{
995 struct GNUNET_NAMESTORE_QueueEntry *q;
996 struct GNUNET_NAMESTORE_ZoneIterator *z;
997
998 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
999 GNUNET_break (NULL == h->op_head);
1000 while (NULL != (q = h->op_head))
1001 {
1002 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, q);
1003 GNUNET_free (q);
1004 }
1005 GNUNET_break (NULL == h->z_head);
1006 while (NULL != (z = h->z_head))
1007 {
1008 GNUNET_CONTAINER_DLL_remove (h->z_head, h->z_tail, z);
1009 GNUNET_free (z);
1010 }
1011 if (NULL != h->mq)
1012 {
1013 GNUNET_MQ_destroy (h->mq);
1014 h->mq = NULL;
1015 }
1016 if (NULL != h->reconnect_task)
1017 {
1018 GNUNET_SCHEDULER_cancel (h->reconnect_task);
1019 h->reconnect_task = NULL;
1020 }
1021 GNUNET_free (h);
1022}
1023
1024
1025/**
1026 * Task launched to warn the user that the namestore is
1027 * excessively slow and that a query was thus dropped.
1028 *
1029 * @param cls a `struct GNUNET_NAMESTORE_QueueEntry *`
1030 */
1031static void
1032warn_delay (void *cls)
1033{
1034 struct GNUNET_NAMESTORE_QueueEntry *qe = cls;
1035
1036 qe->timeout_task = NULL;
1037 LOG (GNUNET_ERROR_TYPE_WARNING,
1038 "Did not receive response from namestore after %s!\n",
1039 GNUNET_STRINGS_relative_time_to_string (NAMESTORE_DELAY_TOLERANCE,
1040 GNUNET_YES));
1041 if (NULL != qe->cont)
1042 {
1043 qe->cont (qe->cont_cls, GNUNET_EC_NAMESTORE_UNKNOWN);
1044 qe->cont = NULL;
1045 }
1046 GNUNET_NAMESTORE_cancel (qe);
1047}
1048
1049
1050struct GNUNET_NAMESTORE_QueueEntry *
1051GNUNET_NAMESTORE_records_store (
1052 struct GNUNET_NAMESTORE_Handle *h,
1053 const struct GNUNET_IDENTITY_PrivateKey *pkey,
1054 const char *label,
1055 unsigned int rd_count,
1056 const struct GNUNET_GNSRECORD_Data *rd,
1057 GNUNET_NAMESTORE_ContinuationWithStatus cont,
1058 void *cont_cls)
1059{
1060 struct GNUNET_NAMESTORE_RecordInfo ri;
1061 unsigned int rds_sent;
1062 ri.a_label = label;
1063 ri.a_rd_count = rd_count;
1064 ri.a_rd = (struct GNUNET_GNSRECORD_Data *) rd;
1065 return GNUNET_NAMESTORE_records_store2 (h, pkey, 1, &ri, &rds_sent,
1066 cont, cont_cls);
1067}
1068
1069struct GNUNET_NAMESTORE_QueueEntry *
1070GNUNET_NAMESTORE_records_store2 (
1071 struct GNUNET_NAMESTORE_Handle *h,
1072 const struct GNUNET_IDENTITY_PrivateKey *pkey,
1073 unsigned int rd_set_count,
1074 const struct GNUNET_NAMESTORE_RecordInfo *record_info,
1075 unsigned int *rds_sent,
1076 GNUNET_NAMESTORE_ContinuationWithStatus cont,
1077 void *cont_cls)
1078{
1079 struct GNUNET_NAMESTORE_QueueEntry *qe;
1080 struct GNUNET_MQ_Envelope *env;
1081 const char *label;
1082 unsigned int rd_count;
1083 const struct GNUNET_GNSRECORD_Data *rd;
1084 char *name_tmp;
1085 char *rd_ser;
1086 ssize_t rd_ser_len[rd_set_count];
1087 size_t name_len;
1088 uint32_t rid;
1089 struct RecordStoreMessage *msg;
1090 struct RecordSet *rd_set;
1091 ssize_t sret;
1092 int i;
1093 size_t rd_set_len = 0;
1094 size_t key_len = 0;
1095 size_t max_len;
1096 key_len = GNUNET_IDENTITY_private_key_get_length (pkey);
1097 max_len = UINT16_MAX - key_len - sizeof (struct RecordStoreMessage);
1098
1099 *rds_sent = 0;
1100 for (i = 0; i < rd_set_count; i++)
1101 {
1102 label = record_info[i].a_label;
1103 rd_count = record_info[i].a_rd_count;
1104 rd = record_info[i].a_rd;
1105 name_len = strlen (label) + 1;
1106 if (name_len > MAX_NAME_LEN)
1107 {
1108 GNUNET_break (0);
1109 *rds_sent = 0;
1110 return NULL;
1111 }
1112 rd_ser_len[i] = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1113 if (rd_ser_len[i] < 0)
1114 {
1115 GNUNET_break (0);
1116 *rds_sent = 0;
1117 return NULL;
1118 }
1119 if (rd_ser_len[i] > max_len)
1120 {
1121 GNUNET_break (0);
1122 *rds_sent = 0;
1123 return NULL;
1124 }
1125 if ((rd_set_len + sizeof (struct RecordSet) + name_len + rd_ser_len[i]) >
1126 max_len)
1127 break;
1128 rd_set_len += sizeof (struct RecordSet) + name_len + rd_ser_len[i];
1129 }
1130 *rds_sent = i;
1131 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1132 "Sending %u of %u records!\n", *rds_sent, rd_set_count);
1133 rid = get_op_id (h);
1134 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1135 qe->h = h;
1136 qe->cont = cont;
1137 qe->cont_cls = cont_cls;
1138 qe->op_id = rid;
1139 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1140 /* setup msg */
1141 env = GNUNET_MQ_msg_extra (msg,
1142 key_len + rd_set_len,
1143 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE);
1144 GNUNET_assert (NULL != msg);
1145 GNUNET_assert (NULL != env);
1146 msg->gns_header.r_id = htonl (rid);
1147 msg->key_len = htons (key_len);
1148 msg->rd_set_count = htons ((uint16_t) (*rds_sent));
1149 GNUNET_IDENTITY_write_private_key_to_buffer (pkey,
1150 &msg[1],
1151 key_len);
1152 rd_set = (struct RecordSet*) (((char*) &msg[1]) + key_len);
1153 for (int i = 0; i < *rds_sent; i++)
1154 {
1155 label = record_info[i].a_label;
1156 rd = record_info[i].a_rd;
1157 name_len = strlen (label) + 1;
1158 rd_set->name_len = htons (name_len);
1159 rd_set->rd_count = htons (record_info[i].a_rd_count);
1160 rd_set->rd_len = htons (rd_ser_len[i]);
1161 rd_set->reserved = ntohs (0);
1162 name_tmp = (char *) &rd_set[1];
1163 GNUNET_memcpy (name_tmp, label, name_len);
1164 rd_ser = &name_tmp[name_len];
1165 sret = GNUNET_GNSRECORD_records_serialize (record_info[i].a_rd_count,
1166 rd, rd_ser_len[i], rd_ser);
1167 if ((0 > sret) || (sret != rd_ser_len[i]))
1168 {
1169 GNUNET_break (0);
1170 GNUNET_free (env);
1171 return NULL;
1172 }
1173 // Point to next RecordSet
1174 rd_set = (struct RecordSet*) &name_tmp[name_len + rd_ser_len[i]];
1175 }
1176 LOG (GNUNET_ERROR_TYPE_DEBUG,
1177 "Sending NAMESTORE_RECORD_STORE message for name %u record sets\n",
1178 *rds_sent);
1179 qe->timeout_task =
1180 GNUNET_SCHEDULER_add_delayed (NAMESTORE_DELAY_TOLERANCE, &warn_delay, qe);
1181 if (NULL == h->mq)
1182 {
1183 qe->env = env;
1184 LOG (GNUNET_ERROR_TYPE_WARNING,
1185 "Delaying NAMESTORE_RECORD_STORE message as namestore is not ready!\n");
1186 }
1187 else
1188 {
1189 GNUNET_MQ_send (h->mq, env);
1190 }
1191 return qe;
1192}
1193
1194
1195static struct GNUNET_NAMESTORE_QueueEntry *
1196records_lookup (
1197 struct GNUNET_NAMESTORE_Handle *h,
1198 const struct GNUNET_IDENTITY_PrivateKey *pkey,
1199 const char *label,
1200 GNUNET_SCHEDULER_TaskCallback error_cb,
1201 void *error_cb_cls,
1202 GNUNET_NAMESTORE_RecordMonitor rm,
1203 void *rm_cls,
1204 int is_edit_request,
1205 enum GNUNET_GNSRECORD_Filter filter)
1206{
1207 struct GNUNET_NAMESTORE_QueueEntry *qe;
1208 struct GNUNET_MQ_Envelope *env;
1209 struct LabelLookupMessage *msg;
1210 size_t label_len;
1211 size_t key_len;
1212
1213 if (1 == (label_len = strlen (label) + 1))
1214 {
1215 GNUNET_break (0);
1216 return NULL;
1217 }
1218
1219 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1220 qe->h = h;
1221 qe->error_cb = error_cb;
1222 qe->error_cb_cls = error_cb_cls;
1223 qe->proc = rm;
1224 qe->proc_cls = rm_cls;
1225 qe->op_id = get_op_id (h);
1226 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1227
1228 key_len = GNUNET_IDENTITY_private_key_get_length (pkey);
1229 env = GNUNET_MQ_msg_extra (msg,
1230 label_len + key_len,
1231 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP);
1232 msg->gns_header.r_id = htonl (qe->op_id);
1233 GNUNET_IDENTITY_write_private_key_to_buffer (pkey,
1234 &msg[1],
1235 key_len);
1236
1237 msg->key_len = htons (key_len);
1238 msg->is_edit_request = htons (is_edit_request);
1239 msg->label_len = htons (label_len);
1240 msg->filter = htons (filter);
1241 GNUNET_memcpy (((char*) &msg[1]) + key_len, label, label_len);
1242 if (NULL == h->mq)
1243 qe->env = env;
1244 else
1245 GNUNET_MQ_send (h->mq, env);
1246 return qe;
1247}
1248
1249struct GNUNET_NAMESTORE_QueueEntry *
1250GNUNET_NAMESTORE_records_lookup (
1251 struct GNUNET_NAMESTORE_Handle *h,
1252 const struct GNUNET_IDENTITY_PrivateKey *pkey,
1253 const char *label,
1254 GNUNET_SCHEDULER_TaskCallback error_cb,
1255 void *error_cb_cls,
1256 GNUNET_NAMESTORE_RecordMonitor rm,
1257 void *rm_cls)
1258{
1259 return records_lookup (h, pkey, label,
1260 error_cb, error_cb_cls,
1261 rm, rm_cls, GNUNET_NO, GNUNET_GNSRECORD_FILTER_NONE);
1262
1263}
1264
1265struct GNUNET_NAMESTORE_QueueEntry *
1266GNUNET_NAMESTORE_records_lookup2 (
1267 struct GNUNET_NAMESTORE_Handle *h,
1268 const struct GNUNET_IDENTITY_PrivateKey *pkey,
1269 const char *label,
1270 GNUNET_SCHEDULER_TaskCallback error_cb,
1271 void *error_cb_cls,
1272 GNUNET_NAMESTORE_RecordMonitor rm,
1273 void *rm_cls,
1274 enum GNUNET_GNSRECORD_Filter filter)
1275{
1276 return records_lookup (h, pkey, label,
1277 error_cb, error_cb_cls,
1278 rm, rm_cls, GNUNET_NO, filter);
1279
1280}
1281
1282
1283struct GNUNET_NAMESTORE_QueueEntry *
1284GNUNET_NAMESTORE_records_edit (
1285 struct GNUNET_NAMESTORE_Handle *h,
1286 const struct GNUNET_IDENTITY_PrivateKey *pkey,
1287 const char *label,
1288 GNUNET_SCHEDULER_TaskCallback error_cb,
1289 void *error_cb_cls,
1290 GNUNET_NAMESTORE_RecordMonitor rm,
1291 void *rm_cls)
1292{
1293 return records_lookup (h, pkey, label,
1294 error_cb, error_cb_cls,
1295 rm, rm_cls, GNUNET_YES, GNUNET_GNSRECORD_FILTER_NONE);
1296}
1297
1298struct GNUNET_NAMESTORE_QueueEntry *
1299GNUNET_NAMESTORE_zone_to_name (
1300 struct GNUNET_NAMESTORE_Handle *h,
1301 const struct GNUNET_IDENTITY_PrivateKey *zone,
1302 const struct GNUNET_IDENTITY_PublicKey *value_zone,
1303 GNUNET_SCHEDULER_TaskCallback error_cb,
1304 void *error_cb_cls,
1305 GNUNET_NAMESTORE_RecordMonitor proc,
1306 void *proc_cls)
1307{
1308 struct GNUNET_NAMESTORE_QueueEntry *qe;
1309 struct GNUNET_MQ_Envelope *env;
1310 struct ZoneToNameMessage *msg;
1311 uint32_t rid;
1312 size_t key_len;
1313 ssize_t pkey_len;
1314
1315 rid = get_op_id (h);
1316 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1317 qe->h = h;
1318 qe->error_cb = error_cb;
1319 qe->error_cb_cls = error_cb_cls;
1320 qe->proc = proc;
1321 qe->proc_cls = proc_cls;
1322 qe->op_id = rid;
1323 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1324
1325 key_len = GNUNET_IDENTITY_private_key_get_length (zone);
1326 pkey_len = GNUNET_IDENTITY_public_key_get_length (value_zone);
1327 env = GNUNET_MQ_msg_extra (msg, key_len + pkey_len,
1328 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME);
1329 msg->gns_header.r_id = htonl (rid);
1330 msg->key_len = htons (key_len);
1331 msg->pkey_len = htons (pkey_len);
1332 GNUNET_IDENTITY_write_private_key_to_buffer (zone, &msg[1], key_len);
1333 GNUNET_IDENTITY_write_public_key_to_buffer (value_zone,
1334 (char*) &msg[1] + key_len,
1335 pkey_len);
1336 if (NULL == h->mq)
1337 qe->env = env;
1338 else
1339 GNUNET_MQ_send (h->mq, env);
1340 return qe;
1341}
1342
1343
1344struct GNUNET_NAMESTORE_ZoneIterator *
1345GNUNET_NAMESTORE_zone_iteration_start (
1346 struct GNUNET_NAMESTORE_Handle *h,
1347 const struct GNUNET_IDENTITY_PrivateKey *zone,
1348 GNUNET_SCHEDULER_TaskCallback error_cb,
1349 void *error_cb_cls,
1350 GNUNET_NAMESTORE_RecordMonitor proc,
1351 void *proc_cls,
1352 GNUNET_SCHEDULER_TaskCallback finish_cb,
1353 void *finish_cb_cls)
1354{
1355 struct GNUNET_NAMESTORE_ZoneIterator *it;
1356 struct GNUNET_MQ_Envelope *env;
1357 struct ZoneIterationStartMessage *msg;
1358 uint32_t rid;
1359 size_t key_len = 0;
1360
1361 LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending ZONE_ITERATION_START message\n");
1362 rid = get_op_id (h);
1363 it = GNUNET_new (struct GNUNET_NAMESTORE_ZoneIterator);
1364 it->h = h;
1365 it->error_cb = error_cb;
1366 it->error_cb_cls = error_cb_cls;
1367 it->finish_cb = finish_cb;
1368 it->finish_cb_cls = finish_cb_cls;
1369 it->proc = proc;
1370 it->proc_cls = proc_cls;
1371 it->op_id = rid;
1372 if (NULL != zone)
1373 {
1374 it->zone = *zone;
1375 key_len = GNUNET_IDENTITY_private_key_get_length (zone);
1376 }
1377 GNUNET_CONTAINER_DLL_insert_tail (h->z_head, h->z_tail, it);
1378 env = GNUNET_MQ_msg_extra (msg,
1379 key_len,
1380 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START);
1381 msg->gns_header.r_id = htonl (rid);
1382 msg->key_len = htons (key_len);
1383 if (NULL != zone)
1384 GNUNET_IDENTITY_write_private_key_to_buffer (zone, &msg[1], key_len);
1385 if (NULL == h->mq)
1386 it->env = env;
1387 else
1388 GNUNET_MQ_send (h->mq, env);
1389 return it;
1390}
1391
1392struct GNUNET_NAMESTORE_ZoneIterator *
1393GNUNET_NAMESTORE_zone_iteration_start2 (
1394 struct GNUNET_NAMESTORE_Handle *h,
1395 const struct GNUNET_IDENTITY_PrivateKey *zone,
1396 GNUNET_SCHEDULER_TaskCallback error_cb,
1397 void *error_cb_cls,
1398 GNUNET_NAMESTORE_RecordSetMonitor proc,
1399 void *proc_cls,
1400 GNUNET_SCHEDULER_TaskCallback finish_cb,
1401 void *finish_cb_cls,
1402 enum GNUNET_GNSRECORD_Filter filter)
1403{
1404 struct GNUNET_NAMESTORE_ZoneIterator *it;
1405 struct GNUNET_MQ_Envelope *env;
1406 struct ZoneIterationStartMessage *msg;
1407 uint32_t rid;
1408 size_t key_len = 0;
1409
1410 LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending ZONE_ITERATION_START message\n");
1411 rid = get_op_id (h);
1412 it = GNUNET_new (struct GNUNET_NAMESTORE_ZoneIterator);
1413 it->h = h;
1414 it->error_cb = error_cb;
1415 it->error_cb_cls = error_cb_cls;
1416 it->finish_cb = finish_cb;
1417 it->finish_cb_cls = finish_cb_cls;
1418 it->proc2 = proc;
1419 it->proc_cls = proc_cls;
1420 it->op_id = rid;
1421 if (NULL != zone)
1422 {
1423 it->zone = *zone;
1424 key_len = GNUNET_IDENTITY_private_key_get_length (zone);
1425 }
1426 GNUNET_CONTAINER_DLL_insert_tail (h->z_head, h->z_tail, it);
1427 env = GNUNET_MQ_msg_extra (msg,
1428 key_len,
1429 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START);
1430 msg->gns_header.r_id = htonl (rid);
1431 msg->key_len = htons (key_len);
1432 msg->filter = htons ((uint16_t) filter);
1433 if (NULL != zone)
1434 GNUNET_IDENTITY_write_private_key_to_buffer (zone, &msg[1], key_len);
1435 if (NULL == h->mq)
1436 it->env = env;
1437 else
1438 GNUNET_MQ_send (h->mq, env);
1439 return it;
1440}
1441
1442
1443void
1444GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it,
1445 uint64_t limit)
1446{
1447 struct GNUNET_NAMESTORE_Handle *h = it->h;
1448 struct ZoneIterationNextMessage *msg;
1449 struct GNUNET_MQ_Envelope *env;
1450
1451 LOG (GNUNET_ERROR_TYPE_DEBUG,
1452 "Sending ZONE_ITERATION_NEXT message with limit %llu\n",
1453 (unsigned long long) limit);
1454 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT);
1455 msg->gns_header.r_id = htonl (it->op_id);
1456 msg->limit = GNUNET_htonll (limit);
1457 GNUNET_MQ_send (h->mq, env);
1458}
1459
1460
1461/**
1462 * Stops iteration and releases the namestore handle for further calls.
1463 *
1464 * @param it the iterator
1465 */
1466void
1467GNUNET_NAMESTORE_zone_iteration_stop (struct GNUNET_NAMESTORE_ZoneIterator *it)
1468{
1469 struct GNUNET_NAMESTORE_Handle *h = it->h;
1470 struct GNUNET_MQ_Envelope *env;
1471 struct ZoneIterationStopMessage *msg;
1472
1473 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ZONE_ITERATION_STOP message\n");
1474 if (NULL != h->mq)
1475 {
1476 env =
1477 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP);
1478 msg->gns_header.r_id = htonl (it->op_id);
1479 GNUNET_MQ_send (h->mq, env);
1480 }
1481 free_ze (it);
1482}
1483
1484
1485/**
1486 * Cancel a namestore operation. The final callback from the
1487 * operation must not have been done yet.
1488 *
1489 * @param qe operation to cancel
1490 */
1491void
1492GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe)
1493{
1494 free_qe (qe);
1495}
1496
1497/**
1498 * New API draft. Experimental
1499 */
1500
1501static struct GNUNET_NAMESTORE_QueueEntry *
1502send_transaction_control_msg (struct GNUNET_NAMESTORE_Handle *h,
1503 GNUNET_NAMESTORE_ContinuationWithStatus cont,
1504 void *cont_cls,
1505 enum GNUNET_NAMESTORE_TxControl ctrl)
1506{
1507 struct GNUNET_NAMESTORE_QueueEntry *qe;
1508 struct GNUNET_MQ_Envelope *env;
1509 struct TxControlMessage *msg;
1510 uint32_t rid;
1511
1512 rid = get_op_id (h);
1513 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1514 qe->h = h;
1515 qe->cont = cont;
1516 qe->cont_cls = cont_cls;
1517 qe->op_id = rid;
1518 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1519
1520 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL);
1521 msg->gns_header.r_id = htonl (rid);
1522 msg->control = htons (ctrl);
1523 if (NULL == h->mq)
1524 qe->env = env;
1525 else
1526 GNUNET_MQ_send (h->mq, env);
1527 return qe;
1528 GNUNET_break (0);
1529 return NULL;
1530}
1531
1532struct GNUNET_NAMESTORE_QueueEntry *
1533GNUNET_NAMESTORE_transaction_begin (struct GNUNET_NAMESTORE_Handle *h,
1534 GNUNET_NAMESTORE_ContinuationWithStatus cont,
1535 void *cont_cls)
1536{
1537 return send_transaction_control_msg (h, cont, cont_cls,
1538 GNUNET_NAMESTORE_TX_BEGIN);
1539}
1540
1541struct GNUNET_NAMESTORE_QueueEntry *
1542GNUNET_NAMESTORE_transaction_commit (struct GNUNET_NAMESTORE_Handle *h,
1543 GNUNET_NAMESTORE_ContinuationWithStatus
1544 cont,
1545 void *cont_cls)
1546{
1547 return send_transaction_control_msg (h, cont, cont_cls,
1548 GNUNET_NAMESTORE_TX_COMMIT);
1549}
1550
1551
1552struct GNUNET_NAMESTORE_QueueEntry *
1553GNUNET_NAMESTORE_transaction_rollback (struct GNUNET_NAMESTORE_Handle *h,
1554 GNUNET_NAMESTORE_ContinuationWithStatus
1555 cont,
1556 void *cont_cls)
1557{
1558 return send_transaction_control_msg (h, cont, cont_cls,
1559 GNUNET_NAMESTORE_TX_ROLLBACK);
1560}
1561
1562
1563/* end of namestore_api.c */