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 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.
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.
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/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
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__)
44 * We grant the namestore up to 1 minute of latency, if it is slower than
45 * that, store queries will fail.
47 #define NAMESTORE_DELAY_TOLERANCE GNUNET_TIME_UNIT_MINUTES
50 * An QueueEntry used to store information for a pending
51 * NAMESTORE record operation
53 struct GNUNET_NAMESTORE_QueueEntry
58 struct GNUNET_NAMESTORE_QueueEntry *next;
63 struct GNUNET_NAMESTORE_QueueEntry *prev;
66 * Main handle to access the namestore.
68 struct GNUNET_NAMESTORE_Handle *h;
71 * Continuation to call
73 GNUNET_NAMESTORE_ContinuationWithStatus cont;
76 * Closure for @e cont.
81 * Function to call with the records we get back; or NULL.
83 GNUNET_NAMESTORE_RecordMonitor proc;
86 * Closure for @e proc.
91 * Function to call on errors.
93 GNUNET_SCHEDULER_TaskCallback error_cb;
96 * Closure for @e error_cb.
101 * Envelope of the message to send to the service, if not yet
104 struct GNUNET_MQ_Envelope *env;
107 * Task scheduled to warn us if the namestore is way too slow.
109 struct GNUNET_SCHEDULER_Task *timeout_task;
112 * The operation id this zone iteration operation has
119 * Handle for a zone iterator operation
121 struct GNUNET_NAMESTORE_ZoneIterator
126 struct GNUNET_NAMESTORE_ZoneIterator *next;
131 struct GNUNET_NAMESTORE_ZoneIterator *prev;
134 * Main handle to access the namestore.
136 struct GNUNET_NAMESTORE_Handle *h;
139 * Function to call on completion.
141 GNUNET_SCHEDULER_TaskCallback finish_cb;
144 * Closure for @e error_cb.
149 * The continuation to call with the results
151 GNUNET_NAMESTORE_RecordMonitor proc;
154 * Closure for @e proc.
159 * Function to call on errors.
161 GNUNET_SCHEDULER_TaskCallback error_cb;
164 * Closure for @e error_cb.
169 * Envelope of the message to send to the service, if not yet
172 struct GNUNET_MQ_Envelope *env;
175 * Private key of the zone.
177 struct GNUNET_CRYPTO_EcdsaPrivateKey zone;
180 * The operation id this zone iteration operation has
187 * Connection to the NAMESTORE service.
189 struct GNUNET_NAMESTORE_Handle
192 * Configuration to use.
194 const struct GNUNET_CONFIGURATION_Handle *cfg;
197 * Connection to the service (if available).
199 struct GNUNET_MQ_Handle *mq;
202 * Head of pending namestore queue entries
204 struct GNUNET_NAMESTORE_QueueEntry *op_head;
207 * Tail of pending namestore queue entries
209 struct GNUNET_NAMESTORE_QueueEntry *op_tail;
212 * Head of pending namestore zone iterator entries
214 struct GNUNET_NAMESTORE_ZoneIterator *z_head;
217 * Tail of pending namestore zone iterator entries
219 struct GNUNET_NAMESTORE_ZoneIterator *z_tail;
224 struct GNUNET_SCHEDULER_Task *reconnect_task;
227 * Delay introduced before we reconnect.
229 struct GNUNET_TIME_Relative reconnect_delay;
232 * Should we reconnect to service due to some serious error?
237 * The last operation id used for a NAMESTORE operation
239 uint32_t last_op_id_used;
244 * Disconnect from service and then reconnect.
246 * @param h our handle
249 force_reconnect (struct GNUNET_NAMESTORE_Handle *h);
253 * Find the queue entry that matches the @a rid
255 * @param h namestore handle
256 * @param rid id to look up
257 * @return NULL if @a rid was not found
259 static struct GNUNET_NAMESTORE_QueueEntry *
260 find_qe (struct GNUNET_NAMESTORE_Handle *h, uint32_t rid)
262 struct GNUNET_NAMESTORE_QueueEntry *qe;
264 for (qe = h->op_head; qe != NULL; qe = qe->next)
265 if (qe->op_id == rid)
272 * Find the zone iteration entry that matches the @a rid
274 * @param h namestore handle
275 * @param rid id to look up
276 * @return NULL if @a rid was not found
278 static struct GNUNET_NAMESTORE_ZoneIterator *
279 find_zi (struct GNUNET_NAMESTORE_Handle *h, uint32_t rid)
281 struct GNUNET_NAMESTORE_ZoneIterator *ze;
283 for (ze = h->z_head; ze != NULL; ze = ze->next)
284 if (ze->op_id == rid)
293 * @param qe entry to free
296 free_qe (struct GNUNET_NAMESTORE_QueueEntry *qe)
298 struct GNUNET_NAMESTORE_Handle *h = qe->h;
300 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, qe);
302 GNUNET_MQ_discard (qe->env);
303 if (NULL != qe->timeout_task)
304 GNUNET_SCHEDULER_cancel (qe->timeout_task);
312 * @param ze entry to free
315 free_ze (struct GNUNET_NAMESTORE_ZoneIterator *ze)
317 struct GNUNET_NAMESTORE_Handle *h = ze->h;
319 GNUNET_CONTAINER_DLL_remove (h->z_head, h->z_tail, ze);
321 GNUNET_MQ_discard (ze->env);
327 * Check that @a rd_buf of lenght @a rd_len contains
328 * @a rd_count records.
330 * @param rd_len length of @a rd_buf
331 * @param rd_buf buffer with serialized records
332 * @param rd_count number of records expected
333 * @return #GNUNET_OK if @a rd_buf is well-formed
336 check_rd (size_t rd_len, const void *rd_buf, unsigned int rd_count)
338 struct GNUNET_GNSRECORD_Data rd[rd_count];
341 GNUNET_GNSRECORD_records_deserialize (rd_len, rd_buf, rd_count, rd))
344 return GNUNET_SYSERR;
351 * Handle an incoming message of type
352 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
355 * @param msg the message we received
358 handle_record_store_response (void *cls,
359 const struct RecordStoreResponseMessage *msg)
361 struct GNUNET_NAMESTORE_Handle *h = cls;
362 struct GNUNET_NAMESTORE_QueueEntry *qe;
366 qe = find_qe (h, ntohl (msg->gns_header.r_id));
367 res = ntohl (msg->op_result);
368 LOG (GNUNET_ERROR_TYPE_DEBUG,
369 "Received RECORD_STORE_RESPONSE with result %d\n",
371 /* TODO: add actual error message from namestore to response... */
372 if (GNUNET_SYSERR == res)
373 emsg = _ ("Namestore failed to store record\n");
376 if (NULL != qe->cont)
377 qe->cont (qe->cont_cls, res, emsg);
383 * Check validity of an incoming message of type
384 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE
387 * @param msg the message we received
388 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
391 check_lookup_result (void *cls, const struct LabelLookupResponseMessage *msg)
400 rd_len = ntohs (msg->rd_len);
401 msg_len = ntohs (msg->gns_header.header.size);
402 name_len = ntohs (msg->name_len);
403 exp_msg_len = sizeof(*msg) + name_len + rd_len;
404 if (msg_len != exp_msg_len)
407 return GNUNET_SYSERR;
409 name = (const char *) &msg[1];
410 if ((name_len > 0) && ('\0' != name[name_len - 1]))
413 return GNUNET_SYSERR;
415 if (GNUNET_NO == ntohs (msg->found))
417 if (0 != ntohs (msg->rd_count))
420 return GNUNET_SYSERR;
424 return check_rd (rd_len, &name[name_len], ntohs (msg->rd_count));
429 * Handle an incoming message of type
430 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE
433 * @param msg the message we received
436 handle_lookup_result (void *cls, const struct LabelLookupResponseMessage *msg)
438 struct GNUNET_NAMESTORE_Handle *h = cls;
439 struct GNUNET_NAMESTORE_QueueEntry *qe;
444 unsigned int rd_count;
446 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_LOOKUP_RESULT\n");
447 qe = find_qe (h, ntohl (msg->gns_header.r_id));
450 rd_len = ntohs (msg->rd_len);
451 rd_count = ntohs (msg->rd_count);
452 name_len = ntohs (msg->name_len);
453 name = (const char *) &msg[1];
454 if (GNUNET_NO == ntohs (msg->found))
456 /* label was not in namestore */
457 if (NULL != qe->proc)
458 qe->proc (qe->proc_cls, &msg->private_key, name, 0, NULL);
463 rd_tmp = &name[name_len];
465 struct GNUNET_GNSRECORD_Data rd[rd_count];
469 GNUNET_GNSRECORD_records_deserialize (rd_len, rd_tmp, rd_count, rd));
472 if (NULL != qe->proc)
473 qe->proc (qe->proc_cls,
477 (rd_count > 0) ? rd : NULL);
484 * Handle an incoming message of type
485 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
488 * @param msg the message we received
489 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
492 check_record_result (void *cls, const struct RecordResultMessage *msg)
494 static struct GNUNET_CRYPTO_EcdsaPrivateKey priv_dummy;
501 rd_len = ntohs (msg->rd_len);
502 msg_len = ntohs (msg->gns_header.header.size);
503 name_len = ntohs (msg->name_len);
504 if (0 != ntohs (msg->reserved))
507 return GNUNET_SYSERR;
509 if (msg_len != sizeof(struct RecordResultMessage) + name_len + rd_len)
512 return GNUNET_SYSERR;
514 name = (const char *) &msg[1];
515 if ((0 == name_len) || ('\0' != name[name_len - 1]))
518 return GNUNET_SYSERR;
520 if (0 == GNUNET_memcmp (&msg->private_key, &priv_dummy))
523 return GNUNET_SYSERR;
525 return check_rd (rd_len, &name[name_len], ntohs (msg->rd_count));
530 * Handle an incoming message of type
531 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
534 * @param msg the message we received
537 handle_record_result (void *cls, const struct RecordResultMessage *msg)
539 struct GNUNET_NAMESTORE_Handle *h = cls;
540 struct GNUNET_NAMESTORE_QueueEntry *qe;
541 struct GNUNET_NAMESTORE_ZoneIterator *ze;
546 unsigned int rd_count;
548 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_RESULT\n");
549 rd_len = ntohs (msg->rd_len);
550 rd_count = ntohs (msg->rd_count);
551 name_len = ntohs (msg->name_len);
552 ze = find_zi (h, ntohl (msg->gns_header.r_id));
553 qe = find_qe (h, ntohl (msg->gns_header.r_id));
554 if ((NULL == ze) && (NULL == qe))
555 return; /* rid not found */
556 if ((NULL != ze) && (NULL != qe))
558 GNUNET_break (0); /* rid ambigous */
562 name = (const char *) &msg[1];
563 rd_tmp = &name[name_len];
565 struct GNUNET_GNSRECORD_Data rd[rd_count];
569 GNUNET_GNSRECORD_records_deserialize (rd_len, rd_tmp, rd_count, rd));
574 if (NULL != qe->proc)
575 qe->proc (qe->proc_cls,
579 (rd_count > 0) ? rd : NULL);
585 if (NULL != ze->proc)
586 ze->proc (ze->proc_cls, &msg->private_key, name, rd_count, rd);
595 * Handle an incoming message of type
596 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT_END
599 * @param msg the message we received
602 handle_record_result_end (void *cls, const struct GNUNET_NAMESTORE_Header *msg)
604 struct GNUNET_NAMESTORE_Handle *h = cls;
605 struct GNUNET_NAMESTORE_QueueEntry *qe;
606 struct GNUNET_NAMESTORE_ZoneIterator *ze;
608 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_RESULT_END\n");
609 ze = find_zi (h, ntohl (msg->r_id));
610 qe = find_qe (h, ntohl (msg->r_id));
611 if ((NULL == ze) && (NULL == qe))
612 return; /* rid not found */
613 if ((NULL != ze) && (NULL != qe))
615 GNUNET_break (0); /* rid ambigous */
619 LOG (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration completed!\n");
626 if (NULL != ze->finish_cb)
627 ze->finish_cb (ze->finish_cb_cls);
633 * Handle an incoming message of type
634 * #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
636 * @param qe the respective entry in the message queue
637 * @param msg the message we received
638 * @return #GNUNET_OK on success, #GNUNET_SYSERR if message malformed
641 check_zone_to_name_response (void *cls,
642 const struct ZoneToNameResponseMessage *msg)
646 const char *name_tmp;
649 if (GNUNET_OK != ntohs (msg->res))
651 name_len = ntohs (msg->name_len);
652 rd_ser_len = ntohs (msg->rd_len);
653 if (ntohs (msg->gns_header.header.size) !=
654 sizeof(struct ZoneToNameResponseMessage) + name_len + rd_ser_len)
657 return GNUNET_SYSERR;
659 name_tmp = (const char *) &msg[1];
660 if ((name_len > 0) && ('\0' != name_tmp[name_len - 1]))
663 return GNUNET_SYSERR;
665 return check_rd (rd_ser_len, &name_tmp[name_len], ntohs (msg->rd_count));
670 * Handle an incoming message of type
671 * #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
674 * @param msg the message we received
677 handle_zone_to_name_response (void *cls,
678 const struct ZoneToNameResponseMessage *msg)
680 struct GNUNET_NAMESTORE_Handle *h = cls;
681 struct GNUNET_NAMESTORE_QueueEntry *qe;
685 unsigned int rd_count;
686 const char *name_tmp;
689 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_TO_NAME_RESPONSE\n");
690 qe = find_qe (h, ntohl (msg->gns_header.r_id));
691 res = ntohs (msg->res);
695 LOG (GNUNET_ERROR_TYPE_DEBUG,
696 "An error occurred during zone to name operation\n");
700 LOG (GNUNET_ERROR_TYPE_DEBUG,
701 "Namestore has no result for zone to name mapping \n");
702 if (NULL != qe->proc)
703 qe->proc (qe->proc_cls, &msg->zone, NULL, 0, NULL);
708 LOG (GNUNET_ERROR_TYPE_DEBUG,
709 "Namestore has result for zone to name mapping \n");
710 name_len = ntohs (msg->name_len);
711 rd_count = ntohs (msg->rd_count);
712 rd_ser_len = ntohs (msg->rd_len);
713 name_tmp = (const char *) &msg[1];
714 rd_tmp = &name_tmp[name_len];
716 struct GNUNET_GNSRECORD_Data rd[rd_count];
718 GNUNET_assert (GNUNET_OK ==
719 GNUNET_GNSRECORD_records_deserialize (rd_ser_len,
723 /* normal end, call continuation with result */
724 if (NULL != qe->proc)
725 qe->proc (qe->proc_cls, &msg->zone, name_tmp, rd_count, rd);
726 /* return is important here: break would call continuation with error! */
736 /* error case, call continuation with error */
737 if (NULL != qe->error_cb)
738 qe->error_cb (qe->error_cb_cls);
744 * Generic error handler, called with the appropriate error code and
745 * the same closure specified at the creation of the message queue.
746 * Not every message queue implementation supports an error handler.
748 * @param cls closure with the `struct GNUNET_NAMESTORE_Handle *`
749 * @param error error code
752 mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
754 struct GNUNET_NAMESTORE_Handle *h = cls;
762 * Reconnect to namestore service.
764 * @param h the handle to the NAMESTORE service
767 reconnect (struct GNUNET_NAMESTORE_Handle *h)
769 struct GNUNET_MQ_MessageHandler handlers[] =
770 { GNUNET_MQ_hd_fixed_size (record_store_response,
771 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE,
772 struct RecordStoreResponseMessage,
774 GNUNET_MQ_hd_var_size (zone_to_name_response,
775 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE,
776 struct ZoneToNameResponseMessage,
778 GNUNET_MQ_hd_var_size (record_result,
779 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT,
780 struct RecordResultMessage,
782 GNUNET_MQ_hd_fixed_size (record_result_end,
783 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT_END,
784 struct GNUNET_NAMESTORE_Header,
786 GNUNET_MQ_hd_var_size (lookup_result,
787 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE,
788 struct LabelLookupResponseMessage,
790 GNUNET_MQ_handler_end () };
791 struct GNUNET_NAMESTORE_ZoneIterator *it;
792 struct GNUNET_NAMESTORE_QueueEntry *qe;
794 GNUNET_assert (NULL == h->mq);
796 GNUNET_CLIENT_connect (h->cfg, "namestore", handlers, &mq_error_handler, h);
799 /* re-transmit pending requests that waited for a reconnect... */
800 for (it = h->z_head; NULL != it; it = it->next)
802 GNUNET_MQ_send (h->mq, it->env);
805 for (qe = h->op_head; NULL != qe; qe = qe->next)
807 GNUNET_MQ_send (h->mq, qe->env);
814 * Re-establish the connection to the service.
816 * @param cls handle to use to re-connect.
819 reconnect_task (void *cls)
821 struct GNUNET_NAMESTORE_Handle *h = cls;
823 h->reconnect_task = NULL;
829 * Disconnect from service and then reconnect.
831 * @param h our handle
834 force_reconnect (struct GNUNET_NAMESTORE_Handle *h)
836 struct GNUNET_NAMESTORE_ZoneIterator *ze;
837 struct GNUNET_NAMESTORE_QueueEntry *qe;
839 GNUNET_MQ_destroy (h->mq);
841 while (NULL != (ze = h->z_head))
843 if (NULL != ze->error_cb)
844 ze->error_cb (ze->error_cb_cls);
847 while (NULL != (qe = h->op_head))
849 if (NULL != qe->error_cb)
850 qe->error_cb (qe->error_cb_cls);
851 if (NULL != qe->cont)
852 qe->cont (qe->cont_cls,
854 "failure in communication with namestore service");
858 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting to namestore\n");
859 h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay);
861 GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect_task, h);
866 * Get a fresh operation id to distinguish between namestore requests
868 * @param h the namestore handle
869 * @return next operation id to use
872 get_op_id (struct GNUNET_NAMESTORE_Handle *h)
874 return h->last_op_id_used++;
879 * Initialize the connection with the NAMESTORE service.
881 * @param cfg configuration to use
882 * @return handle to the GNS service, or NULL on error
884 struct GNUNET_NAMESTORE_Handle *
885 GNUNET_NAMESTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
887 struct GNUNET_NAMESTORE_Handle *h;
889 h = GNUNET_new (struct GNUNET_NAMESTORE_Handle);
902 * Disconnect from the namestore service (and free associated
905 * @param h handle to the namestore
908 GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h)
910 struct GNUNET_NAMESTORE_QueueEntry *q;
911 struct GNUNET_NAMESTORE_ZoneIterator *z;
913 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
914 GNUNET_break (NULL == h->op_head);
915 while (NULL != (q = h->op_head))
917 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, q);
920 GNUNET_break (NULL == h->z_head);
921 while (NULL != (z = h->z_head))
923 GNUNET_CONTAINER_DLL_remove (h->z_head, h->z_tail, z);
928 GNUNET_MQ_destroy (h->mq);
931 if (NULL != h->reconnect_task)
933 GNUNET_SCHEDULER_cancel (h->reconnect_task);
934 h->reconnect_task = NULL;
941 * Task launched to warn the user that the namestore is
942 * excessively slow and that a query was thus dropped.
944 * @param cls a `struct GNUNET_NAMESTORE_QueueEntry *`
947 warn_delay (void *cls)
949 struct GNUNET_NAMESTORE_QueueEntry *qe = cls;
951 qe->timeout_task = NULL;
952 LOG (GNUNET_ERROR_TYPE_WARNING,
953 "Did not receive response from namestore after %s!\n",
954 GNUNET_STRINGS_relative_time_to_string (NAMESTORE_DELAY_TOLERANCE,
956 if (NULL != qe->cont)
958 qe->cont (qe->cont_cls, GNUNET_SYSERR, "timeout");
961 GNUNET_NAMESTORE_cancel (qe);
966 * Store an item in the namestore. If the item is already present,
967 * it is replaced with the new record. Use an empty array to
968 * remove all records under the given name.
970 * @param h handle to the namestore
971 * @param pkey private key of the zone
972 * @param label name that is being mapped (at most 255 characters long)
973 * @param rd_count number of records in the @a rd array
974 * @param rd array of records with data to store
975 * @param cont continuation to call when done
976 * @param cont_cls closure for @a cont
977 * @return handle to abort the request
979 struct GNUNET_NAMESTORE_QueueEntry *
980 GNUNET_NAMESTORE_records_store (
981 struct GNUNET_NAMESTORE_Handle *h,
982 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
984 unsigned int rd_count,
985 const struct GNUNET_GNSRECORD_Data *rd,
986 GNUNET_NAMESTORE_ContinuationWithStatus cont,
989 struct GNUNET_NAMESTORE_QueueEntry *qe;
990 struct GNUNET_MQ_Envelope *env;
996 struct RecordStoreMessage *msg;
999 name_len = strlen (label) + 1;
1000 if (name_len > MAX_NAME_LEN)
1005 rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1011 if (rd_ser_len > UINT16_MAX)
1016 rid = get_op_id (h);
1017 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1020 qe->cont_cls = cont_cls;
1022 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1025 env = GNUNET_MQ_msg_extra (msg,
1026 name_len + rd_ser_len,
1027 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE);
1028 msg->gns_header.r_id = htonl (rid);
1029 msg->name_len = htons (name_len);
1030 msg->rd_count = htons (rd_count);
1031 msg->rd_len = htons (rd_ser_len);
1032 msg->reserved = htons (0);
1033 msg->private_key = *pkey;
1035 name_tmp = (char *) &msg[1];
1036 GNUNET_memcpy (name_tmp, label, name_len);
1037 rd_ser = &name_tmp[name_len];
1038 sret = GNUNET_GNSRECORD_records_serialize (rd_count, rd, rd_ser_len, rd_ser);
1039 if ((0 > sret) || (sret != rd_ser_len))
1045 GNUNET_assert (rd_ser_len == sret);
1046 LOG (GNUNET_ERROR_TYPE_DEBUG,
1047 "Sending NAMESTORE_RECORD_STORE message for name `%s' with %u records\n",
1051 GNUNET_SCHEDULER_add_delayed (NAMESTORE_DELAY_TOLERANCE, &warn_delay, qe);
1055 LOG (GNUNET_ERROR_TYPE_WARNING,
1056 "Delaying NAMESTORE_RECORD_STORE message as namestore is not ready!\n");
1060 GNUNET_MQ_send (h->mq, env);
1067 * Set the desired nick name for a zone
1069 * @param h handle to the namestore
1070 * @param pkey private key of the zone
1071 * @param nick the nick name to set
1072 * @param cont continuation to call when done
1073 * @param cont_cls closure for @a cont
1074 * @return handle to abort the request
1076 struct GNUNET_NAMESTORE_QueueEntry *
1077 GNUNET_NAMESTORE_set_nick (struct GNUNET_NAMESTORE_Handle *h,
1078 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1080 GNUNET_NAMESTORE_ContinuationWithStatus cont,
1083 struct GNUNET_GNSRECORD_Data rd;
1087 memset (&rd, 0, sizeof(rd));
1089 rd.data_size = strlen (nick) + 1;
1090 rd.record_type = GNUNET_GNSRECORD_TYPE_NICK;
1091 rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
1092 rd.flags |= GNUNET_GNSRECORD_RF_PRIVATE;
1093 return GNUNET_NAMESTORE_records_store (h,
1095 GNUNET_GNS_EMPTY_LABEL_AT,
1104 * Lookup an item in the namestore.
1106 * @param h handle to the namestore
1107 * @param pkey private key of the zone
1108 * @param label name that is being mapped (at most 255 characters long)
1109 * @param error_cb function to call on error (i.e. disconnect)
1110 * @param error_cb_cls closure for @a error_cb
1111 * @param rm function to call with the result (with 0 records if we don't have that label)
1112 * @param rm_cls closure for @a rm
1113 * @return handle to abort the request
1115 struct GNUNET_NAMESTORE_QueueEntry *
1116 GNUNET_NAMESTORE_records_lookup (
1117 struct GNUNET_NAMESTORE_Handle *h,
1118 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
1120 GNUNET_SCHEDULER_TaskCallback error_cb,
1122 GNUNET_NAMESTORE_RecordMonitor rm,
1125 struct GNUNET_NAMESTORE_QueueEntry *qe;
1126 struct GNUNET_MQ_Envelope *env;
1127 struct LabelLookupMessage *msg;
1130 if (1 == (label_len = strlen (label) + 1))
1136 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1138 qe->error_cb = error_cb;
1139 qe->error_cb_cls = error_cb_cls;
1141 qe->proc_cls = rm_cls;
1142 qe->op_id = get_op_id (h);
1143 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1145 env = GNUNET_MQ_msg_extra (msg,
1147 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP);
1148 msg->gns_header.r_id = htonl (qe->op_id);
1150 msg->label_len = htonl (label_len);
1151 GNUNET_memcpy (&msg[1], label, label_len);
1155 GNUNET_MQ_send (h->mq, env);
1161 * Look for an existing PKEY delegation record for a given public key.
1162 * Returns at most one result to the processor.
1164 * @param h handle to the namestore
1165 * @param zone public key of the zone to look up in, never NULL
1166 * @param value_zone public key of the target zone (value), never NULL
1167 * @param error_cb function to call on error (i.e. disconnect)
1168 * @param error_cb_cls closure for @a error_cb
1169 * @param proc function to call on the matching records, or with
1170 * NULL (rd_count == 0) if there are no matching records
1171 * @param proc_cls closure for @a proc
1172 * @return a handle that can be used to
1175 struct GNUNET_NAMESTORE_QueueEntry *
1176 GNUNET_NAMESTORE_zone_to_name (
1177 struct GNUNET_NAMESTORE_Handle *h,
1178 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1179 const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone,
1180 GNUNET_SCHEDULER_TaskCallback error_cb,
1182 GNUNET_NAMESTORE_RecordMonitor proc,
1185 struct GNUNET_NAMESTORE_QueueEntry *qe;
1186 struct GNUNET_MQ_Envelope *env;
1187 struct ZoneToNameMessage *msg;
1190 rid = get_op_id (h);
1191 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1193 qe->error_cb = error_cb;
1194 qe->error_cb_cls = error_cb_cls;
1196 qe->proc_cls = proc_cls;
1198 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1200 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME);
1201 msg->gns_header.r_id = htonl (rid);
1203 msg->value_zone = *value_zone;
1207 GNUNET_MQ_send (h->mq, env);
1213 * Starts a new zone iteration (used to periodically PUT all of our
1214 * records into our DHT). This MUST lock the struct GNUNET_NAMESTORE_Handle
1215 * for any other calls than #GNUNET_NAMESTORE_zone_iterator_next and
1216 * #GNUNET_NAMESTORE_zone_iteration_stop. @a proc will be called once
1217 * immediately, and then again after
1218 * #GNUNET_NAMESTORE_zone_iterator_next is invoked.
1220 * @param h handle to the namestore
1221 * @param zone zone to access, NULL for all zones
1222 * @param error_cb function to call on error (i.e. disconnect)
1223 * @param error_cb_cls closure for @a error_cb
1224 * @param proc function to call on each name from the zone; it
1225 * will be called repeatedly with a value (if available)
1226 * @param proc_cls closure for @a proc
1227 * @param finish_cb function to call on completion
1228 * @param finish_cb_cls closure for @a finish_cb
1229 * @return an iterator handle to use for iteration
1231 struct GNUNET_NAMESTORE_ZoneIterator *
1232 GNUNET_NAMESTORE_zone_iteration_start (
1233 struct GNUNET_NAMESTORE_Handle *h,
1234 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1235 GNUNET_SCHEDULER_TaskCallback error_cb,
1237 GNUNET_NAMESTORE_RecordMonitor proc,
1239 GNUNET_SCHEDULER_TaskCallback finish_cb,
1240 void *finish_cb_cls)
1242 struct GNUNET_NAMESTORE_ZoneIterator *it;
1243 struct GNUNET_MQ_Envelope *env;
1244 struct ZoneIterationStartMessage *msg;
1247 LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending ZONE_ITERATION_START message\n");
1248 rid = get_op_id (h);
1249 it = GNUNET_new (struct GNUNET_NAMESTORE_ZoneIterator);
1251 it->error_cb = error_cb;
1252 it->error_cb_cls = error_cb_cls;
1253 it->finish_cb = finish_cb;
1254 it->finish_cb_cls = finish_cb_cls;
1256 it->proc_cls = proc_cls;
1260 GNUNET_CONTAINER_DLL_insert_tail (h->z_head, h->z_tail, it);
1261 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START);
1262 msg->gns_header.r_id = htonl (rid);
1268 GNUNET_MQ_send (h->mq, env);
1274 * Calls the record processor specified in #GNUNET_NAMESTORE_zone_iteration_start
1275 * for the next record.
1277 * @param it the iterator
1278 * @param limit number of records to return to the iterator in one shot
1279 * (before #GNUNET_NAMESTORE_zone_iterator_next is to be called again)
1282 GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it,
1285 struct GNUNET_NAMESTORE_Handle *h = it->h;
1286 struct ZoneIterationNextMessage *msg;
1287 struct GNUNET_MQ_Envelope *env;
1289 LOG (GNUNET_ERROR_TYPE_DEBUG,
1290 "Sending ZONE_ITERATION_NEXT message with limit %llu\n",
1291 (unsigned long long) limit);
1292 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT);
1293 msg->gns_header.r_id = htonl (it->op_id);
1294 msg->limit = GNUNET_htonll (limit);
1295 GNUNET_MQ_send (h->mq, env);
1300 * Stops iteration and releases the namestore handle for further calls.
1302 * @param it the iterator
1305 GNUNET_NAMESTORE_zone_iteration_stop (struct GNUNET_NAMESTORE_ZoneIterator *it)
1307 struct GNUNET_NAMESTORE_Handle *h = it->h;
1308 struct GNUNET_MQ_Envelope *env;
1309 struct ZoneIterationStopMessage *msg;
1311 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ZONE_ITERATION_STOP message\n");
1315 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP);
1316 msg->gns_header.r_id = htonl (it->op_id);
1317 GNUNET_MQ_send (h->mq, env);
1324 * Cancel a namestore operation. The final callback from the
1325 * operation must not have been done yet.
1327 * @param qe operation to cancel
1330 GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe)
1336 /* end of namestore_api.c */