2 This file is part of GNUnet.
3 Copyright (C) 2010-2013, 2016 GNUnet e.V.
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.
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.
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.
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
30 #include "gnunet_util_lib.h"
31 #include "gnunet_crypto_lib.h"
32 #include "gnunet_constants.h"
33 #include "gnunet_dnsparser_lib.h"
34 #include "gnunet_arm_service.h"
35 #include "gnunet_signatures.h"
36 #include "gnunet_gns_service.h"
37 #include "gnunet_namestore_service.h"
38 #include "namestore.h"
41 #define LOG(kind,...) GNUNET_log_from (kind, "namestore-api",__VA_ARGS__)
45 * An QueueEntry used to store information for a pending
46 * NAMESTORE record operation
48 struct GNUNET_NAMESTORE_QueueEntry
54 struct GNUNET_NAMESTORE_QueueEntry *next;
59 struct GNUNET_NAMESTORE_QueueEntry *prev;
62 * Main handle to access the namestore.
64 struct GNUNET_NAMESTORE_Handle *h;
67 * Continuation to call
69 GNUNET_NAMESTORE_ContinuationWithStatus cont;
72 * Closure for @e cont.
77 * Function to call with the records we get back; or NULL.
79 GNUNET_NAMESTORE_RecordMonitor proc;
82 * Closure for @e proc.
87 * Envelope of the message to send to the service, if not yet
90 struct GNUNET_MQ_Envelope *env;
93 * The operation id this zone iteration operation has
101 * Handle for a zone iterator operation
103 struct GNUNET_NAMESTORE_ZoneIterator
109 struct GNUNET_NAMESTORE_ZoneIterator *next;
114 struct GNUNET_NAMESTORE_ZoneIterator *prev;
117 * Main handle to access the namestore.
119 struct GNUNET_NAMESTORE_Handle *h;
122 * The continuation to call with the results
124 GNUNET_NAMESTORE_RecordMonitor proc;
127 * Closure for @e proc.
132 * Envelope of the message to send to the service, if not yet
135 struct GNUNET_MQ_Envelope *env;
138 * Private key of the zone.
140 struct GNUNET_CRYPTO_EcdsaPrivateKey zone;
143 * The operation id this zone iteration operation has
151 * Connection to the NAMESTORE service.
153 struct GNUNET_NAMESTORE_Handle
157 * Configuration to use.
159 const struct GNUNET_CONFIGURATION_Handle *cfg;
162 * Connection to the service (if available).
164 struct GNUNET_MQ_Handle *mq;
167 * Head of pending namestore queue entries
169 struct GNUNET_NAMESTORE_QueueEntry *op_head;
172 * Tail of pending namestore queue entries
174 struct GNUNET_NAMESTORE_QueueEntry *op_tail;
177 * Head of pending namestore zone iterator entries
179 struct GNUNET_NAMESTORE_ZoneIterator *z_head;
182 * Tail of pending namestore zone iterator entries
184 struct GNUNET_NAMESTORE_ZoneIterator *z_tail;
189 struct GNUNET_SCHEDULER_Task *reconnect_task;
192 * Delay introduced before we reconnect.
194 struct GNUNET_TIME_Relative reconnect_delay;
197 * Should we reconnect to service due to some serious error?
202 * The last operation id used for a NAMESTORE operation
204 uint32_t last_op_id_used;
210 * Disconnect from service and then reconnect.
212 * @param h our handle
215 force_reconnect (struct GNUNET_NAMESTORE_Handle *h);
219 * Find the queue entry that matches the @a rid
221 * @param h namestore handle
222 * @param rid id to look up
223 * @return NULL if @a rid was not found
225 static struct GNUNET_NAMESTORE_QueueEntry *
226 find_qe (struct GNUNET_NAMESTORE_Handle *h,
229 struct GNUNET_NAMESTORE_QueueEntry *qe;
231 for (qe = h->op_head; qe != NULL; qe = qe->next)
232 if (qe->op_id == rid)
239 * Find the zone iteration entry that matches the @a rid
241 * @param h namestore handle
242 * @param rid id to look up
243 * @return NULL if @a rid was not found
245 static struct GNUNET_NAMESTORE_ZoneIterator *
246 find_zi (struct GNUNET_NAMESTORE_Handle *h,
249 struct GNUNET_NAMESTORE_ZoneIterator *ze;
251 for (ze = h->z_head; ze != NULL; ze = ze->next)
252 if (ze->op_id == rid)
261 * @param qe entry to free
264 free_qe (struct GNUNET_NAMESTORE_QueueEntry *qe)
266 struct GNUNET_NAMESTORE_Handle *h = qe->h;
268 GNUNET_CONTAINER_DLL_remove (h->op_head,
272 GNUNET_MQ_discard (qe->env);
280 * @param ze entry to free
283 free_ze (struct GNUNET_NAMESTORE_ZoneIterator *ze)
285 struct GNUNET_NAMESTORE_Handle *h = ze->h;
287 GNUNET_CONTAINER_DLL_remove (h->z_head,
291 GNUNET_MQ_discard (ze->env);
297 * Check that @a rd_buf of lenght @a rd_len contains
298 * @a rd_count records.
300 * @param rd_len length of @a rd_buf
301 * @param rd_buf buffer with serialized records
302 * @param rd_count number of records expected
303 * @return #GNUNET_OK if @a rd_buf is well-formed
306 check_rd (size_t rd_len,
308 unsigned int rd_count)
310 struct GNUNET_GNSRECORD_Data rd[rd_count];
313 GNUNET_GNSRECORD_records_deserialize (rd_len,
319 return GNUNET_SYSERR;
326 * Handle an incoming message of type
327 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
330 * @param msg the message we received
333 handle_record_store_response (void *cls,
334 const struct RecordStoreResponseMessage *msg)
336 struct GNUNET_NAMESTORE_Handle *h = cls;
337 struct GNUNET_NAMESTORE_QueueEntry *qe;
342 ntohl (msg->gns_header.r_id));
343 res = ntohl (msg->op_result);
344 LOG (GNUNET_ERROR_TYPE_DEBUG,
345 "Received RECORD_STORE_RESPONSE with result %d\n",
347 /* TODO: add actual error message from namestore to response... */
348 if (GNUNET_SYSERR == res)
349 emsg = _("Namestore failed to store record\n");
352 if (NULL != qe->cont)
353 qe->cont (qe->cont_cls,
361 * Check validity of an incoming message of type
362 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE
365 * @param msg the message we received
366 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
369 check_lookup_result (void *cls,
370 const struct LabelLookupResponseMessage *msg)
378 rd_len = ntohs (msg->rd_len);
379 msg_len = ntohs (msg->gns_header.header.size);
380 name_len = ntohs (msg->name_len);
381 exp_msg_len = sizeof (*msg) + name_len + rd_len;
382 if (msg_len != exp_msg_len)
385 return GNUNET_SYSERR;
387 name = (const char *) &msg[1];
388 if ( (name_len > 0) &&
389 ('\0' != name[name_len -1]) )
392 return GNUNET_SYSERR;
394 if (GNUNET_NO == ntohs (msg->found))
396 if (0 != ntohs (msg->rd_count))
399 return GNUNET_SYSERR;
403 return check_rd (rd_len,
405 ntohs (msg->rd_count));
410 * Handle an incoming message of type
411 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE
414 * @param msg the message we received
417 handle_lookup_result (void *cls,
418 const struct LabelLookupResponseMessage *msg)
420 struct GNUNET_NAMESTORE_Handle *h = cls;
421 struct GNUNET_NAMESTORE_QueueEntry *qe;
426 unsigned int rd_count;
428 LOG (GNUNET_ERROR_TYPE_DEBUG,
429 "Received RECORD_LOOKUP_RESULT\n");
431 ntohl (msg->gns_header.r_id));
434 rd_len = ntohs (msg->rd_len);
435 rd_count = ntohs (msg->rd_count);
436 name_len = ntohs (msg->name_len);
437 name = (const char *) &msg[1];
438 if (GNUNET_NO == ntohs (msg->found))
440 /* label was not in namestore */
441 if (NULL != qe->proc)
442 qe->proc (qe->proc_cls,
451 rd_tmp = &name[name_len];
453 struct GNUNET_GNSRECORD_Data rd[rd_count];
455 GNUNET_assert (GNUNET_OK ==
456 GNUNET_GNSRECORD_records_deserialize (rd_len,
462 if (NULL != qe->proc)
463 qe->proc (qe->proc_cls,
467 (rd_count > 0) ? rd : NULL);
474 * Handle an incoming message of type
475 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
478 * @param msg the message we received
479 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
482 check_record_result (void *cls,
483 const struct RecordResultMessage *msg)
490 rd_len = ntohs (msg->rd_len);
491 msg_len = ntohs (msg->gns_header.header.size);
492 name_len = ntohs (msg->name_len);
493 if (0 != ntohs (msg->reserved))
496 return GNUNET_SYSERR;
498 if (msg_len != sizeof (struct RecordResultMessage) + name_len + rd_len)
501 return GNUNET_SYSERR;
503 name = (const char *) &msg[1];
504 if ( (name_len > 0) &&
505 ('\0' != name[name_len -1]) )
508 return GNUNET_SYSERR;
510 return check_rd (rd_len,
512 ntohs (msg->rd_count));
517 * Handle an incoming message of type
518 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
521 * @param msg the message we received
524 handle_record_result (void *cls,
525 const struct RecordResultMessage *msg)
527 static struct GNUNET_CRYPTO_EcdsaPrivateKey priv_dummy;
528 struct GNUNET_NAMESTORE_Handle *h = cls;
529 struct GNUNET_NAMESTORE_QueueEntry *qe;
530 struct GNUNET_NAMESTORE_ZoneIterator *ze;
535 unsigned int rd_count;
537 LOG (GNUNET_ERROR_TYPE_DEBUG,
538 "Received RECORD_RESULT\n");
539 rd_len = ntohs (msg->rd_len);
540 rd_count = ntohs (msg->rd_count);
541 name_len = ntohs (msg->name_len);
543 ntohl (msg->gns_header.r_id));
545 ntohl (msg->gns_header.r_id));
546 if ( (NULL == ze) && (NULL == qe) )
547 return; /* rid not found */
548 if ( (NULL != ze) && (NULL != qe) )
550 GNUNET_break (0); /* rid ambigous */
554 if ( (0 == name_len) &&
555 (0 == (memcmp (&msg->private_key,
557 sizeof (priv_dummy)))) )
559 LOG (GNUNET_ERROR_TYPE_DEBUG,
560 "Zone iteration completed!\n");
567 if (NULL != ze->proc)
568 ze->proc (ze->proc_cls, NULL, NULL, 0, NULL);
573 name = (const char *) &msg[1];
574 rd_tmp = &name[name_len];
576 struct GNUNET_GNSRECORD_Data rd[rd_count];
578 GNUNET_assert (GNUNET_OK ==
579 GNUNET_GNSRECORD_records_deserialize(rd_len,
587 if (NULL != qe->proc)
588 qe->proc (qe->proc_cls,
592 (rd_count > 0) ? rd : NULL);
598 if (NULL != ze->proc)
599 ze->proc (ze->proc_cls,
612 * Handle an incoming message of type
613 * #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
615 * @param qe the respective entry in the message queue
616 * @param msg the message we received
617 * @return #GNUNET_OK on success, #GNUNET_SYSERR if message malformed
620 check_zone_to_name_response (void *cls,
621 const struct ZoneToNameResponseMessage *msg)
625 const char *name_tmp;
627 if (GNUNET_OK != ntohs (msg->res))
629 name_len = ntohs (msg->name_len);
630 rd_ser_len = ntohs (msg->rd_len);
631 if (ntohs (msg->gns_header.header.size) !=
632 sizeof (struct ZoneToNameResponseMessage) + name_len + rd_ser_len)
635 return GNUNET_SYSERR;
637 name_tmp = (const char *) &msg[1];
638 if ( (name_len > 0) &&
639 ('\0' != name_tmp[name_len -1]) )
642 return GNUNET_SYSERR;
644 return check_rd (rd_ser_len,
646 ntohs (msg->rd_count));
651 * Handle an incoming message of type
652 * #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
655 * @param msg the message we received
658 handle_zone_to_name_response (void *cls,
659 const struct ZoneToNameResponseMessage *msg)
661 struct GNUNET_NAMESTORE_Handle *h = cls;
662 struct GNUNET_NAMESTORE_QueueEntry *qe;
666 unsigned int rd_count;
667 const char *name_tmp;
670 LOG (GNUNET_ERROR_TYPE_DEBUG,
671 "Received ZONE_TO_NAME_RESPONSE\n");
673 ntohl (msg->gns_header.r_id));
674 res = ntohs (msg->res);
678 LOG (GNUNET_ERROR_TYPE_DEBUG,
679 "An error occured during zone to name operation\n");
682 LOG (GNUNET_ERROR_TYPE_DEBUG,
683 "Namestore has no result for zone to name mapping \n");
684 if (NULL != qe->proc)
685 qe->proc (qe->proc_cls, &msg->zone, NULL, 0, NULL);
689 LOG (GNUNET_ERROR_TYPE_DEBUG,
690 "Namestore has result for zone to name mapping \n");
691 name_len = ntohs (msg->name_len);
692 rd_count = ntohs (msg->rd_count);
693 rd_ser_len = ntohs (msg->rd_len);
694 name_tmp = (const char *) &msg[1];
695 rd_tmp = &name_tmp[name_len];
697 struct GNUNET_GNSRECORD_Data rd[rd_count];
699 GNUNET_assert (GNUNET_OK ==
700 GNUNET_GNSRECORD_records_deserialize (rd_ser_len,
704 /* normal end, call continuation with result */
705 if (NULL != qe->proc)
706 qe->proc (qe->proc_cls,
710 /* return is important here: break would call continuation with error! */
719 /* error case, call continuation with error */
720 if (NULL != qe->proc)
721 qe->proc (qe->proc_cls, NULL, NULL, 0, NULL);
728 * Generic error handler, called with the appropriate error code and
729 * the same closure specified at the creation of the message queue.
730 * Not every message queue implementation supports an error handler.
732 * @param cls closure with the `struct GNUNET_NAMESTORE_Handle *`
733 * @param error error code
736 mq_error_handler (void *cls,
737 enum GNUNET_MQ_Error error)
739 struct GNUNET_NAMESTORE_Handle *h = cls;
746 * Reconnect to namestore service.
748 * @param h the handle to the NAMESTORE service
751 reconnect (struct GNUNET_NAMESTORE_Handle *h)
753 GNUNET_MQ_hd_fixed_size (record_store_response,
754 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE,
755 struct RecordStoreResponseMessage);
756 GNUNET_MQ_hd_var_size (zone_to_name_response,
757 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE,
758 struct ZoneToNameResponseMessage);
759 GNUNET_MQ_hd_var_size (record_result,
760 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT,
761 struct RecordResultMessage);
762 GNUNET_MQ_hd_var_size (lookup_result,
763 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE,
764 struct LabelLookupResponseMessage);
765 struct GNUNET_MQ_MessageHandler handlers[] = {
766 make_record_store_response_handler (h),
767 make_zone_to_name_response_handler (h),
768 make_record_result_handler (h),
769 make_lookup_result_handler (h),
770 GNUNET_MQ_handler_end ()
772 struct GNUNET_NAMESTORE_ZoneIterator *it;
773 struct GNUNET_NAMESTORE_QueueEntry *qe;
775 GNUNET_assert (NULL == h->mq);
776 h->mq = GNUNET_CLIENT_connecT (h->cfg,
783 /* re-transmit pending requests that waited for a reconnect... */
784 for (it = h->z_head; NULL != it; it = it->next)
786 GNUNET_MQ_send (h->mq,
790 for (qe = h->op_head; NULL != qe; qe = qe->next)
792 GNUNET_MQ_send (h->mq,
800 * Re-establish the connection to the service.
802 * @param cls handle to use to re-connect.
805 reconnect_task (void *cls)
807 struct GNUNET_NAMESTORE_Handle *h = cls;
809 h->reconnect_task = NULL;
815 * Disconnect from service and then reconnect.
817 * @param h our handle
820 force_reconnect (struct GNUNET_NAMESTORE_Handle *h)
822 struct GNUNET_NAMESTORE_ZoneIterator *ze;
823 struct GNUNET_NAMESTORE_QueueEntry *qe;
825 GNUNET_MQ_destroy (h->mq);
827 while (NULL != (ze = h->z_head))
829 /* FIXME: This does not allow clients to distinguish
830 iteration error from successful termination! */
831 if (NULL != ze->proc)
832 ze->proc (ze->proc_cls, NULL, NULL, 0, NULL);
835 while (NULL != (qe = h->op_head))
837 /* FIXME: This does not allow clients to distinguish
838 iteration error from successful termination! */
839 if (NULL != qe->proc)
840 qe->proc (qe->proc_cls, NULL, NULL, 0, NULL);
844 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
845 "Reconnecting to namestore\n");
846 h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay);
847 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_delay,
854 * Get a fresh operation id to distinguish between namestore requests
856 * @param h the namestore handle
857 * @return next operation id to use
860 get_op_id (struct GNUNET_NAMESTORE_Handle *h)
862 return h->last_op_id_used++;
867 * Initialize the connection with the NAMESTORE service.
869 * @param cfg configuration to use
870 * @return handle to the GNS service, or NULL on error
872 struct GNUNET_NAMESTORE_Handle *
873 GNUNET_NAMESTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
875 struct GNUNET_NAMESTORE_Handle *h;
877 h = GNUNET_new (struct GNUNET_NAMESTORE_Handle);
890 * Disconnect from the namestore service (and free associated
893 * @param h handle to the namestore
896 GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h)
898 struct GNUNET_NAMESTORE_QueueEntry *q;
899 struct GNUNET_NAMESTORE_ZoneIterator *z;
901 LOG (GNUNET_ERROR_TYPE_DEBUG,
903 GNUNET_break (NULL == h->op_head);
904 while (NULL != (q = h->op_head))
906 GNUNET_CONTAINER_DLL_remove (h->op_head,
911 GNUNET_break (NULL == h->z_head);
912 while (NULL != (z = h->z_head))
914 GNUNET_CONTAINER_DLL_remove (h->z_head,
921 GNUNET_MQ_destroy (h->mq);
924 if (NULL != h->reconnect_task)
926 GNUNET_SCHEDULER_cancel (h->reconnect_task);
927 h->reconnect_task = NULL;
934 * Store an item in the namestore. If the item is already present,
935 * it is replaced with the new record. Use an empty array to
936 * remove all records under the given name.
938 * @param h handle to the namestore
939 * @param pkey private key of the zone
940 * @param label name that is being mapped (at most 255 characters long)
941 * @param rd_count number of records in the @a rd array
942 * @param rd array of records with data to store
943 * @param cont continuation to call when done
944 * @param cont_cls closure for @a cont
945 * @return handle to abort the request
947 struct GNUNET_NAMESTORE_QueueEntry *
948 GNUNET_NAMESTORE_records_store (struct GNUNET_NAMESTORE_Handle *h,
949 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
951 unsigned int rd_count,
952 const struct GNUNET_GNSRECORD_Data *rd,
953 GNUNET_NAMESTORE_ContinuationWithStatus cont,
956 struct GNUNET_NAMESTORE_QueueEntry *qe;
957 struct GNUNET_MQ_Envelope *env;
963 struct RecordStoreMessage *msg;
965 name_len = strlen (label) + 1;
966 if (name_len > MAX_NAME_LEN)
972 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
975 qe->cont_cls = cont_cls;
977 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
982 rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count,
984 env = GNUNET_MQ_msg_extra (msg,
985 name_len + rd_ser_len,
986 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE);
987 msg->gns_header.r_id = htonl (rid);
988 msg->name_len = htons (name_len);
989 msg->rd_count = htons (rd_count);
990 msg->rd_len = htons (rd_ser_len);
991 msg->reserved = htons (0);
992 msg->private_key = *pkey;
994 name_tmp = (char *) &msg[1];
995 GNUNET_memcpy (name_tmp,
998 rd_ser = &name_tmp[name_len];
999 GNUNET_assert (rd_ser_len ==
1000 GNUNET_GNSRECORD_records_serialize (rd_count,
1004 LOG (GNUNET_ERROR_TYPE_DEBUG,
1005 "Sending NAMESTORE_RECORD_STORE message for name `%s' with %u records\n",
1012 GNUNET_MQ_send (h->mq,
1019 * Set the desired nick name for a zone
1021 * @param h handle to the namestore
1022 * @param pkey private key of the zone
1023 * @param nick the nick name to set
1024 * @param cont continuation to call when done
1025 * @param cont_cls closure for @a cont
1026 * @return handle to abort the request
1028 struct GNUNET_NAMESTORE_QueueEntry *
1029 GNUNET_NAMESTORE_set_nick (struct GNUNET_NAMESTORE_Handle *h,
1030 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1032 GNUNET_NAMESTORE_ContinuationWithStatus cont,
1035 struct GNUNET_GNSRECORD_Data rd;
1039 memset (&rd, 0, sizeof (rd));
1041 rd.data_size = strlen (nick) +1;
1042 rd.record_type = GNUNET_GNSRECORD_TYPE_NICK;
1043 rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
1044 rd.flags |= GNUNET_GNSRECORD_RF_PRIVATE;
1045 return GNUNET_NAMESTORE_records_store (h,
1047 GNUNET_GNS_MASTERZONE_STR,
1056 * Lookup an item in the namestore.
1058 * @param h handle to the namestore
1059 * @param pkey private key of the zone
1060 * @param label name that is being mapped (at most 255 characters long)
1061 * @param rm function to call with the result (with 0 records if we don't have that label)
1062 * @param rm_cls closure for @a rm
1063 * @return handle to abort the request
1065 struct GNUNET_NAMESTORE_QueueEntry *
1066 GNUNET_NAMESTORE_records_lookup (struct GNUNET_NAMESTORE_Handle *h,
1067 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1069 GNUNET_NAMESTORE_RecordMonitor rm,
1072 struct GNUNET_NAMESTORE_QueueEntry *qe;
1073 struct GNUNET_MQ_Envelope *env;
1074 struct LabelLookupMessage *msg;
1077 if (1 == (label_len = strlen (label) + 1))
1083 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1086 qe->proc_cls = rm_cls;
1087 qe->op_id = get_op_id(h);
1088 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1092 env = GNUNET_MQ_msg_extra (msg,
1094 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP);
1095 msg->gns_header.r_id = htonl (qe->op_id);
1097 msg->label_len = htonl (label_len);
1098 GNUNET_memcpy (&msg[1],
1104 GNUNET_MQ_send (h->mq,
1111 * Look for an existing PKEY delegation record for a given public key.
1112 * Returns at most one result to the processor.
1114 * @param h handle to the namestore
1115 * @param zone public key of the zone to look up in, never NULL
1116 * @param value_zone public key of the target zone (value), never NULL
1117 * @param proc function to call on the matching records, or with
1118 * NULL (rd_count == 0) if there are no matching records
1119 * @param proc_cls closure for @a proc
1120 * @return a handle that can be used to
1123 struct GNUNET_NAMESTORE_QueueEntry *
1124 GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h,
1125 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1126 const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone,
1127 GNUNET_NAMESTORE_RecordMonitor proc,
1130 struct GNUNET_NAMESTORE_QueueEntry *qe;
1131 struct GNUNET_MQ_Envelope *env;
1132 struct ZoneToNameMessage *msg;
1136 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1139 qe->proc_cls = proc_cls;
1141 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1145 env = GNUNET_MQ_msg (msg,
1146 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME);
1147 msg->gns_header.r_id = htonl (rid);
1149 msg->value_zone = *value_zone;
1153 GNUNET_MQ_send (h->mq,
1160 * Starts a new zone iteration (used to periodically PUT all of our
1161 * records into our DHT). This MUST lock the struct GNUNET_NAMESTORE_Handle
1162 * for any other calls than #GNUNET_NAMESTORE_zone_iterator_next and
1163 * #GNUNET_NAMESTORE_zone_iteration_stop. @a proc will be called once
1164 * immediately, and then again after
1165 * #GNUNET_NAMESTORE_zone_iterator_next is invoked.
1167 * @param h handle to the namestore
1168 * @param zone zone to access, NULL for all zones
1169 * @param proc function to call on each name from the zone; it
1170 * will be called repeatedly with a value (if available)
1171 * and always once at the end with a name of NULL.
1172 * @param proc_cls closure for @a proc
1173 * @return an iterator handle to use for iteration
1175 struct GNUNET_NAMESTORE_ZoneIterator *
1176 GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h,
1177 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1178 GNUNET_NAMESTORE_RecordMonitor proc,
1181 struct GNUNET_NAMESTORE_ZoneIterator *it;
1182 struct GNUNET_MQ_Envelope *env;
1183 struct ZoneIterationStartMessage *msg;
1186 rid = get_op_id (h);
1187 it = GNUNET_new (struct GNUNET_NAMESTORE_ZoneIterator);
1190 it->proc_cls = proc_cls;
1194 GNUNET_CONTAINER_DLL_insert_tail (h->z_head,
1197 env = GNUNET_MQ_msg (msg,
1198 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START);
1199 msg->gns_header.r_id = htonl (rid);
1205 GNUNET_MQ_send (h->mq,
1212 * Calls the record processor specified in #GNUNET_NAMESTORE_zone_iteration_start
1213 * for the next record.
1215 * @param it the iterator
1218 GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it)
1220 struct GNUNET_NAMESTORE_Handle *h = it->h;
1221 struct ZoneIterationNextMessage *msg;
1222 struct GNUNET_MQ_Envelope *env;
1224 LOG (GNUNET_ERROR_TYPE_DEBUG,
1225 "Sending ZONE_ITERATION_NEXT message\n");
1226 env = GNUNET_MQ_msg (msg,
1227 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT);
1228 msg->gns_header.r_id = htonl (it->op_id);
1229 GNUNET_MQ_send (h->mq,
1235 * Stops iteration and releases the namestore handle for further calls.
1237 * @param it the iterator
1240 GNUNET_NAMESTORE_zone_iteration_stop (struct GNUNET_NAMESTORE_ZoneIterator *it)
1242 struct GNUNET_NAMESTORE_Handle *h = it->h;
1243 struct GNUNET_MQ_Envelope *env;
1244 struct ZoneIterationStopMessage *msg;
1246 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1247 "Sending ZONE_ITERATION_STOP message\n");
1248 env = GNUNET_MQ_msg (msg,
1249 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP);
1250 msg->gns_header.r_id = htonl (it->op_id);
1251 GNUNET_MQ_send (h->mq,
1258 * Cancel a namestore operation. The final callback from the
1259 * operation must not have been done yet.
1261 * @param qe operation to cancel
1264 GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe)
1270 /* end of namestore_api.c */