2 This file is part of GNUnet.
3 (C) 2009, 2010 Christian Grothoff (and other contributing authors)
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., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file namestore/namestore_api.c
23 * @brief API to access the NAMESTORE service
24 * @author Martin Schanzenbach
25 * @author Matthias Wachs
29 #include "gnunet_util_lib.h"
30 #include "gnunet_crypto_lib.h"
31 #include "gnunet_constants.h"
32 #include "gnunet_dnsparser_lib.h"
33 #include "gnunet_arm_service.h"
34 #include "gnunet_signatures.h"
35 #include "gnunet_namestore_service.h"
36 #include "namestore.h"
39 #define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__)
42 * An QueueEntry used to store information for a pending
43 * NAMESTORE record operation
45 struct GNUNET_NAMESTORE_QueueEntry
51 struct GNUNET_NAMESTORE_QueueEntry *next;
56 struct GNUNET_NAMESTORE_QueueEntry *prev;
59 * Main handle to access the namestore.
61 struct GNUNET_NAMESTORE_Handle *nsh;
64 * Continuation to call
66 GNUNET_NAMESTORE_ContinuationWithStatus cont;
74 * Function to call with the records we get back; or NULL.
76 GNUNET_NAMESTORE_RecordProcessor proc;
84 * The operation id this zone iteration operation has
92 * Handle for a zone iterator operation
94 struct GNUNET_NAMESTORE_ZoneIterator
100 struct GNUNET_NAMESTORE_ZoneIterator *next;
105 struct GNUNET_NAMESTORE_ZoneIterator *prev;
108 * Main handle to access the namestore.
110 struct GNUNET_NAMESTORE_Handle *h;
113 * The continuation to call with the results
115 GNUNET_NAMESTORE_RecordProcessor proc;
118 * Closure for 'proc'.
123 * If this iterator iterates over a specific zone this value contains the
124 * short hash of the zone
126 struct GNUNET_CRYPTO_ShortHashCode zone;
129 * The operation id this zone iteration operation has
134 * GNUNET_YES if this iterator iterates over a specific zone
135 * GNUNET_NO if this iterator iterates over all zones
137 * Zone is stored GNUNET_CRYPTO_ShortHashCode 'zone';
144 * Message in linked list we should send to the service. The
145 * actual binary message follows this struct.
147 struct PendingMessage
153 struct PendingMessage *next;
158 struct PendingMessage *prev;
161 * Size of the message.
166 * Is this the 'START' message?
173 * Connection to the NAMESTORE service.
175 struct GNUNET_NAMESTORE_Handle
179 * Configuration to use.
181 const struct GNUNET_CONFIGURATION_Handle *cfg;
184 * Socket (if available).
186 struct GNUNET_CLIENT_Connection *client;
189 * Currently pending transmission request (or NULL).
191 struct GNUNET_CLIENT_TransmitHandle *th;
194 * Head of linked list of pending messages to send to the service
196 struct PendingMessage * pending_head;
199 * Tail of linked list of pending messages to send to the service
201 struct PendingMessage * pending_tail;
204 * Head of pending namestore queue entries
206 struct GNUNET_NAMESTORE_QueueEntry * op_head;
209 * Tail of pending namestore queue entries
211 struct GNUNET_NAMESTORE_QueueEntry * op_tail;
214 * Head of pending namestore zone iterator entries
216 struct GNUNET_NAMESTORE_ZoneIterator * z_head;
219 * Tail of pending namestore zone iterator entries
221 struct GNUNET_NAMESTORE_ZoneIterator * z_tail;
226 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
229 * Should we reconnect to service due to some serious error?
234 * The last operation id used for a NAMESTORE operation
236 uint32_t last_op_id_used;
242 * Disconnect from service and then reconnect.
244 * @param h our handle
247 force_reconnect (struct GNUNET_NAMESTORE_Handle *h);
251 * Handle an incoming message of type 'GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE'
253 * @param qe the respective entry in the message queue
254 * @param msg the message we received
255 * @param size the message size
258 handle_lookup_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
259 struct LookupNameResponseMessage * msg,
262 struct GNUNET_NAMESTORE_Handle *h = qe->nsh;
265 struct GNUNET_CRYPTO_RsaSignature *signature = NULL;
266 struct GNUNET_TIME_Absolute expire;
267 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key_tmp;
272 int contains_sig = GNUNET_NO;
275 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' \n",
276 "LOOKUP_NAME_RESPONSE");
277 /* Operation done, remove */
278 GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe);
279 rd_len = ntohs (msg->rd_len);
280 rd_count = ntohs (msg->rd_count);
281 msg_len = ntohs (msg->gns_header.header.size);
282 name_len = ntohs (msg->name_len);
283 contains_sig = ntohs (msg->contains_sig);
284 expire = GNUNET_TIME_absolute_ntoh(msg->expire);
286 exp_msg_len = sizeof (struct LookupNameResponseMessage) +
287 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) +
290 if (msg_len != exp_msg_len)
292 LOG (GNUNET_ERROR_TYPE_DEBUG, "Message size describes with `%u' bytes but calculated size is %u bytes \n",
293 msg_len, exp_msg_len);
298 name = (char *) &msg[1];
301 GNUNET_assert ('\0' == name[name_len -1]);
302 GNUNET_assert ((name_len - 1) == strlen(name));
304 rd_tmp = &name[name_len];
306 /* deserialize records */
308 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
309 if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize(rd_len, rd_tmp, rd_count, rd))
316 /* reset values if values not contained */
317 if (GNUNET_NO == contains_sig)
320 signature = &msg->signature;
325 public_key_tmp = &msg->public_key;
327 public_key_tmp = NULL;
329 if (NULL != qe->proc)
330 qe->proc (qe->proc_cls, public_key_tmp, expire, name, rd_count, (rd_count > 0) ? rd : NULL, signature);
337 * Handle an incoming message of type 'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE'
339 * @param qe the respective entry in the message queue
340 * @param msg the message we received
341 * @param size the message size
344 handle_record_put_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
345 struct RecordPutResponseMessage* msg,
348 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' \n",
349 "RECORD_PUT_RESPONSE");
351 struct GNUNET_NAMESTORE_Handle *h = qe->nsh;
352 /* Operation done, remove */
353 GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe);
355 int res = ntohl (msg->op_result);
357 if (res == GNUNET_OK)
359 if (qe->cont != NULL)
361 qe->cont (qe->cont_cls, res, _("Namestore added record successfully"));
365 else if (res == GNUNET_SYSERR)
367 if (qe->cont != NULL)
369 qe->cont (qe->cont_cls, res, _("Namestore failed to add record"));
383 * Handle an incoming message of type 'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE'
385 * @param qe the respective entry in the message queue
386 * @param msg the message we received
387 * @param size the message size
390 handle_record_create_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
391 struct RecordCreateResponseMessage* msg,
394 struct GNUNET_NAMESTORE_Handle *h = qe->nsh;
396 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' \n",
397 "RECORD_CREATE_RESPONSE");
398 /* Operation done, remove */
399 GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe);
401 int res = ntohl (msg->op_result);
402 if (res == GNUNET_YES)
404 if (qe->cont != NULL)
406 qe->cont (qe->cont_cls, res, _("Namestore added record successfully"));
410 else if (res == GNUNET_NO)
412 if (qe->cont != NULL)
414 qe->cont (qe->cont_cls, res, _("Namestore record already existed"));
419 if (qe->cont != NULL)
421 qe->cont (qe->cont_cls, GNUNET_SYSERR, _("Namestore failed to add record\n"));
430 * Handle an incoming message of type 'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE'
432 * @param qe the respective entry in the message queue
433 * @param msg the message we received
434 * @param size the message size
437 handle_record_remove_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
438 struct RecordRemoveResponseMessage* msg,
442 struct GNUNET_NAMESTORE_Handle *h = qe->nsh;
444 /* Operation done, remove */
445 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' \n",
446 "RECORD_REMOVE_RESPONSE");
447 GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe);
449 int res = ntohl (msg->op_result);
453 * 1 : No records for entry
454 * 2 : Could not find record to remove
455 * 3 : Failed to create new signature
456 * 4 : Failed to put new set of records in database
460 if (qe->cont != NULL)
462 qe->cont (qe->cont_cls, GNUNET_YES, _("Namestore removed record successfully"));
467 if (qe->cont != NULL)
469 qe->cont (qe->cont_cls, GNUNET_NO, _("No records for entry"));
474 if (qe->cont != NULL)
476 qe->cont (qe->cont_cls, GNUNET_NO, _("Could not find record to remove"));
481 if (qe->cont != NULL)
483 qe->cont (qe->cont_cls, GNUNET_SYSERR, _("Failed to create new signature"));
488 if (qe->cont != NULL)
490 qe->cont (qe->cont_cls, GNUNET_SYSERR, _("Failed to put new set of records in database"));
503 * Handle an incoming message of type 'GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE'
505 * @param qe the respective entry in the message queue
506 * @param msg the message we received
507 * @param size the message size
510 handle_zone_to_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
511 struct ZoneToNameResponseMessage* msg,
514 struct GNUNET_NAMESTORE_Handle *h = qe->nsh;
515 int res = ntohs (msg->res);
516 struct GNUNET_TIME_Absolute expire;
519 unsigned int rd_count;
524 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' \n",
525 "ZONE_TO_NAME_RESPONSE");
526 /* Operation done, remove */
527 GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe);
528 if (res == GNUNET_SYSERR)
530 LOG (GNUNET_ERROR_TYPE_DEBUG, "An error occured during zone to name operation\n");
531 if (qe->proc != NULL)
532 qe->proc (qe->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL);
534 else if (res == GNUNET_NO)
536 LOG (GNUNET_ERROR_TYPE_DEBUG, "Namestore has no result for zone to name mapping \n");
537 if (qe->proc != NULL)
538 qe->proc (qe->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL);
540 else if (res == GNUNET_YES)
542 LOG (GNUNET_ERROR_TYPE_DEBUG, "Namestore has result for zone to name mapping \n");
544 name_len = ntohs (msg->name_len);
545 rd_count = ntohs (msg->rd_count);
546 rd_ser_len = ntohs (msg->rd_len);
547 expire = GNUNET_TIME_absolute_ntoh(msg->expire);
549 name_tmp = (char *) &msg[1];
552 GNUNET_assert ('\0' == name_tmp[name_len -1]);
553 GNUNET_assert (name_len -1 == strlen(name_tmp));
555 rd_tmp = &name_tmp[name_len];
557 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
558 if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_tmp, rd_count, rd))
564 if (qe->proc != NULL)
565 qe->proc (qe->proc_cls, &msg->zone_key, expire, name_tmp, rd_count, rd, &msg->signature);
575 * Handle incoming messages for record operations
577 * @param qe the respective zone iteration handle
578 * @param msg the message we received
579 * @param type the message type in HBO
580 * @param size the message size
583 manage_record_operations (struct GNUNET_NAMESTORE_QueueEntry *qe,
584 const struct GNUNET_MessageHeader *msg,
585 int type, size_t size)
588 /* handle different message type */
590 case GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE:
591 if (size < sizeof (struct LookupNameResponseMessage))
596 handle_lookup_name_response (qe, (struct LookupNameResponseMessage *) msg, size);
598 case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE:
599 if (size != sizeof (struct RecordPutResponseMessage))
604 handle_record_put_response (qe, (struct RecordPutResponseMessage *) msg, size);
606 case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE:
607 if (size != sizeof (struct RecordCreateResponseMessage))
612 handle_record_create_response (qe, (struct RecordCreateResponseMessage *) msg, size);
614 case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE:
615 if (size != sizeof (struct RecordRemoveResponseMessage))
620 handle_record_remove_response (qe, (struct RecordRemoveResponseMessage *) msg, size);
622 case GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE:
623 if (size < sizeof (struct ZoneToNameResponseMessage))
628 handle_zone_to_name_response (qe, (struct ZoneToNameResponseMessage *) msg, size);
638 * Handle a response from NAMESTORE service for a zone iteration request
640 * @param ze the respective iterator for this operation
641 * @param msg the message containing the respoonse
642 * @param size the message size
645 handle_zone_iteration_response (struct GNUNET_NAMESTORE_ZoneIterator *ze,
646 struct ZoneIterationResponseMessage *msg,
649 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubdummy;
651 size_t exp_msg_len = 0;
654 unsigned rd_count = 0;
657 struct GNUNET_TIME_Absolute expire;
659 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' \n",
660 "ZONE_ITERATION_RESPONSE");
661 msg_len = ntohs (msg->gns_header.header.size);
662 rd_len = ntohs (msg->rd_len);
663 rd_count = ntohs (msg->rd_count);
664 name_len = ntohs (msg->name_len);
665 expire = GNUNET_TIME_absolute_ntoh (msg->expire);
667 exp_msg_len = sizeof (struct ZoneIterationResponseMessage) + name_len + rd_len;
668 if (msg_len != exp_msg_len)
670 LOG (GNUNET_ERROR_TYPE_DEBUG, "Message size describes with `%u' bytes but calculated size is %u bytes \n",
671 msg_len, exp_msg_len);
675 if (0 != ntohs (msg->reserved))
681 memset (&pubdummy, '\0', sizeof (pubdummy));
682 if ((0 == name_len) && (0 == (memcmp (&msg->public_key, &pubdummy, sizeof (pubdummy)))))
684 LOG (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration is completed!\n");
686 GNUNET_CONTAINER_DLL_remove(ze->h->z_head, ze->h->z_tail, ze);
688 if (ze->proc != NULL)
689 ze->proc(ze->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL , 0, NULL, NULL);
695 name_tmp = (char *) &msg[1];
696 if ((name_tmp[name_len -1] != '\0') || (name_len > 256))
701 rd_ser_tmp = (char *) &name_tmp[name_len];
702 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
703 if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize (rd_len, rd_ser_tmp, rd_count, rd))
709 if (ze->proc != NULL)
710 ze->proc(ze->proc_cls, &msg->public_key, expire, name_tmp, rd_count, rd, &msg->signature);
715 * Handle incoming messages for zone iterations
717 * @param ze the respective zone iteration handle
718 * @param msg the message we received
719 * @param type the message type in HBO
720 * @param size the message size
723 manage_zone_operations (struct GNUNET_NAMESTORE_ZoneIterator *ze,
724 const struct GNUNET_MessageHeader *msg,
725 int type, size_t size)
728 /* handle different message type */
730 case GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE:
731 if (size < sizeof (struct ZoneIterationResponseMessage))
736 handle_zone_iteration_response (ze, (struct ZoneIterationResponseMessage *) msg, size);
746 * Type of a function to call when we receive a message
749 * @param cls the 'struct GNUNET_NAMESTORE_SchedulingHandle'
750 * @param msg message received, NULL on timeout or fatal error
753 process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg)
755 struct GNUNET_NAMESTORE_Handle *h = cls;
756 struct GNUNET_NAMESTORE_Header * gm;
757 struct GNUNET_NAMESTORE_QueueEntry *qe;
758 struct GNUNET_NAMESTORE_ZoneIterator *ze;
761 uint32_t r_id = UINT32_MAX;
769 size = ntohs (msg->size);
770 type = ntohs (msg->type);
772 if (size < sizeof (struct GNUNET_NAMESTORE_Header))
775 GNUNET_CLIENT_receive (h->client, &process_namestore_message, h,
776 GNUNET_TIME_UNIT_FOREVER_REL);
780 gm = (struct GNUNET_NAMESTORE_Header *) msg;
781 r_id = ntohl (gm->r_id);
783 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received message type %i size %i op %u\n", type, size, r_id);
785 /* Find matching operation */
786 if (r_id > h->last_op_id_used)
788 /* No matching pending operation found */
790 GNUNET_CLIENT_receive (h->client, &process_namestore_message, h,
791 GNUNET_TIME_UNIT_FOREVER_REL);
795 /* Is it a record related operation ? */
796 for (qe = h->op_head; qe != NULL; qe = qe->next)
798 if (qe->op_id == r_id)
803 manage_record_operations (qe, msg, type, size);
806 /* Is it a zone iteration operation ? */
807 for (ze = h->z_head; ze != NULL; ze = ze->next)
809 if (ze->op_id == r_id)
814 manage_zone_operations (ze, msg, type, size);
817 GNUNET_CLIENT_receive (h->client, &process_namestore_message, h,
818 GNUNET_TIME_UNIT_FOREVER_REL);
820 if (GNUNET_YES == h->reconnect)
827 * Transmit messages from the message queue to the service
828 * (if there are any, and if we are not already trying).
830 * @param h handle to use
833 do_transmit (struct GNUNET_NAMESTORE_Handle *h);
837 * We can now transmit a message to NAMESTORE. Do it.
839 * @param cls the 'struct GNUNET_NAMESTORE_Handle'
840 * @param size number of bytes we can transmit
841 * @param buf where to copy the messages
842 * @return number of bytes copied into buf
845 transmit_message_to_namestore (void *cls, size_t size, void *buf)
847 struct GNUNET_NAMESTORE_Handle *h = cls;
848 struct PendingMessage *p;
853 if ((size == 0) || (buf == NULL))
860 while ((NULL != (p = h->pending_head)) && (p->size <= size))
862 memcpy (&cbuf[ret], &p[1], p->size);
865 GNUNET_CONTAINER_DLL_remove (h->pending_head, h->pending_tail, p);
866 if (GNUNET_YES == p->is_init)
867 GNUNET_CLIENT_receive (h->client, &process_namestore_message, h,
868 GNUNET_TIME_UNIT_FOREVER_REL);
877 * Transmit messages from the message queue to the service
878 * (if there are any, and if we are not already trying).
880 * @param h handle to use
883 do_transmit (struct GNUNET_NAMESTORE_Handle *h)
885 struct PendingMessage *p;
889 if (NULL == (p = h->pending_head))
891 if (NULL == h->client)
892 return; /* currently reconnecting */
894 h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, p->size,
895 GNUNET_TIME_UNIT_FOREVER_REL,
896 GNUNET_NO, &transmit_message_to_namestore,
902 * Reconnect to namestore service.
904 * @param h the handle to the NAMESTORE service
907 reconnect (struct GNUNET_NAMESTORE_Handle *h)
909 struct PendingMessage *p;
910 struct StartMessage *init;
912 GNUNET_assert (NULL == h->client);
913 h->client = GNUNET_CLIENT_connect ("namestore", h->cfg);
914 GNUNET_assert (NULL != h->client);
916 if ((NULL == (p = h->pending_head)) || (GNUNET_YES != p->is_init))
918 p = GNUNET_malloc (sizeof (struct PendingMessage) +
919 sizeof (struct StartMessage));
920 p->size = sizeof (struct StartMessage);
921 p->is_init = GNUNET_YES;
922 init = (struct StartMessage *) &p[1];
923 init->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_START);
924 init->header.size = htons (sizeof (struct StartMessage));
925 GNUNET_CONTAINER_DLL_insert (h->pending_head, h->pending_tail, p);
931 * Re-establish the connection to the service.
933 * @param cls handle to use to re-connect.
934 * @param tc scheduler context
937 reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
939 struct GNUNET_NAMESTORE_Handle *h = cls;
941 h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
947 * Disconnect from service and then reconnect.
949 * @param h our handle
952 force_reconnect (struct GNUNET_NAMESTORE_Handle *h)
954 h->reconnect = GNUNET_NO;
955 GNUNET_CLIENT_disconnect (h->client);
957 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
964 * Get an unused operation id to distinguish between namestore requests
965 * @param h the namestore handle
966 * @return operation id
969 get_op_id (struct GNUNET_NAMESTORE_Handle *h)
971 uint32_t op_id = h->last_op_id_used;
972 h->last_op_id_used ++;
978 * Initialize the connection with the NAMESTORE service.
980 * @param cfg configuration to use
981 * @return handle to the GNS service, or NULL on error
983 struct GNUNET_NAMESTORE_Handle *
984 GNUNET_NAMESTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
986 struct GNUNET_NAMESTORE_Handle *h;
988 h = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_Handle));
990 h->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect_task, h);
991 h->last_op_id_used = 0;
997 clean_up_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
999 struct GNUNET_NAMESTORE_Handle *h = cls;
1000 struct PendingMessage *p;
1001 struct GNUNET_NAMESTORE_QueueEntry *q;
1002 struct GNUNET_NAMESTORE_ZoneIterator *z;
1004 GNUNET_assert (h != NULL);
1005 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
1006 while (NULL != (p = h->pending_head))
1008 GNUNET_CONTAINER_DLL_remove (h->pending_head, h->pending_tail, p);
1011 while (NULL != (q = h->op_head))
1013 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, q);
1016 while (NULL != (z = h->z_head))
1018 GNUNET_CONTAINER_DLL_remove (h->z_head, h->z_tail, z);
1021 if (NULL != h->client)
1023 GNUNET_CLIENT_disconnect (h->client);
1026 if (GNUNET_SCHEDULER_NO_TASK != h->reconnect_task)
1028 GNUNET_SCHEDULER_cancel (h->reconnect_task);
1029 h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
1037 * Disconnect from the namestore service (and free associated
1040 * @param h handle to the namestore
1043 GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h)
1045 LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from namestore service\n");
1046 GNUNET_SCHEDULER_add_now (&clean_up_task, h);
1051 * Store an item in the namestore. If the item is already present,
1052 * the expiration time is updated to the max of the existing time and
1053 * the new time. This API is used when we cache signatures from other
1056 * @param h handle to the namestore
1057 * @param zone_key public key of the zone
1058 * @param name name that is being mapped (at most 255 characters long)
1059 * @param freshness when does the corresponding block in the DHT expire (until
1060 * when should we never do a DHT lookup for the same name again)?
1061 * @param rd_count number of entries in 'rd' array
1062 * @param rd array of records with data to store
1063 * @param signature signature for all the records in the zone under the given name
1064 * @param cont continuation to call when done
1065 * @param cont_cls closure for cont
1066 * @return handle to abort the request
1068 struct GNUNET_NAMESTORE_QueueEntry *
1069 GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h,
1070 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
1072 struct GNUNET_TIME_Absolute freshness,
1073 unsigned int rd_count,
1074 const struct GNUNET_NAMESTORE_RecordData *rd,
1075 const struct GNUNET_CRYPTO_RsaSignature *signature,
1076 GNUNET_NAMESTORE_ContinuationWithStatus cont,
1079 struct GNUNET_NAMESTORE_QueueEntry *qe;
1080 struct PendingMessage *pe;
1082 /* pointer to elements */
1085 size_t msg_size = 0;
1086 size_t name_len = 0;
1087 size_t rd_ser_len = 0;
1090 GNUNET_assert (NULL != h);
1091 GNUNET_assert (NULL != zone_key);
1092 GNUNET_assert (NULL != name);
1093 GNUNET_assert (NULL != rd);
1094 GNUNET_assert (NULL != signature);
1095 LOG (GNUNET_ERROR_TYPE_DEBUG,
1096 "Storing %u records under name `%s'\n",
1099 name_len = strlen(name) + 1;
1107 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
1110 qe->cont_cls = cont_cls;
1112 GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe);
1115 rd_ser_len = GNUNET_NAMESTORE_records_get_size(rd_count, rd);
1116 char rd_ser[rd_ser_len];
1117 GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser);
1119 struct RecordPutMessage * msg;
1120 msg_size = sizeof (struct RecordPutMessage) + name_len + rd_ser_len;
1122 /* create msg here */
1123 pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
1124 pe->size = msg_size;
1125 pe->is_init = GNUNET_NO;
1126 msg = (struct RecordPutMessage *) &pe[1];
1127 name_tmp = (char *) &msg[1];
1128 rd_tmp = &name_tmp[name_len];
1130 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT);
1131 msg->gns_header.header.size = htons (msg_size);
1132 msg->gns_header.r_id = htonl (rid);
1133 msg->signature = *signature;
1134 msg->name_len = htons (name_len);
1135 msg->expire = GNUNET_TIME_absolute_hton (freshness);
1136 msg->rd_len = htons (rd_ser_len);
1137 msg->rd_count = htons (rd_count);
1139 msg->public_key = *zone_key;
1140 memcpy (name_tmp, name, name_len);
1141 memcpy (rd_tmp, rd_ser, rd_ser_len);
1143 LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s' with size %u\n", "NAMESTORE_RECORD_PUT", name, msg_size);
1145 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1153 * Check if a signature is valid. This API is used by the GNS Block
1154 * to validate signatures received from the network.
1156 * @param public_key public key of the zone
1157 * @param freshness block expiration
1158 * @param name name that is being mapped (at most 255 characters long)
1159 * @param rd_count number of entries in 'rd' array
1160 * @param rd array of records with data to store
1161 * @param signature signature for all the records in the zone under the given name
1162 * @return GNUNET_OK if the signature is valid
1165 GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key,
1166 const struct GNUNET_TIME_Absolute freshness,
1168 unsigned int rd_count,
1169 const struct GNUNET_NAMESTORE_RecordData *rd,
1170 const struct GNUNET_CRYPTO_RsaSignature *signature)
1177 struct GNUNET_CRYPTO_RsaSignaturePurpose *sig_purpose;
1178 struct GNUNET_TIME_AbsoluteNBO *expire_tmp;
1179 struct GNUNET_TIME_AbsoluteNBO expire_nbo = GNUNET_TIME_absolute_hton (freshness);
1182 GNUNET_assert (NULL != public_key);
1183 GNUNET_assert (NULL != name);
1184 GNUNET_assert (NULL != rd);
1185 GNUNET_assert (NULL != signature);
1186 name_len = strlen (name) + 1;
1190 return GNUNET_SYSERR;
1192 rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
1194 char rd_ser[rd_ser_len];
1196 GNUNET_assert (rd_ser_len ==
1197 GNUNET_NAMESTORE_records_serialize (rd_count, rd, rd_ser_len, rd_ser));
1198 sig_len = sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + sizeof (struct GNUNET_TIME_AbsoluteNBO) + rd_ser_len + name_len;
1199 sig_purpose = GNUNET_malloc (sig_len);
1200 sig_purpose->size = htonl (sig_len);
1201 sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
1202 expire_tmp = (struct GNUNET_TIME_AbsoluteNBO *) &sig_purpose[1];
1203 memcpy (expire_tmp, &expire_nbo, sizeof (struct GNUNET_TIME_AbsoluteNBO));
1204 name_tmp = (char *) &expire_tmp[1];
1205 memcpy (name_tmp, name, name_len);
1206 rd_tmp = &name_tmp[name_len];
1207 memcpy (rd_tmp, rd_ser, rd_ser_len);
1208 res = GNUNET_CRYPTO_rsa_verify(GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, sig_purpose, signature, public_key);
1211 GNUNET_free (sig_purpose);
1217 * Store an item in the namestore. If the item is already present,
1218 * the expiration time is updated to the max of the existing time and
1219 * the new time. This API is used by the authority of a zone.
1221 * @param h handle to the namestore
1222 * @param pkey private key of the zone
1223 * @param name name that is being mapped (at most 255 characters long)
1224 * @param rd record data to store
1225 * @param cont continuation to call when done
1226 * @param cont_cls closure for cont
1227 * @return handle to abort the request
1229 struct GNUNET_NAMESTORE_QueueEntry *
1230 GNUNET_NAMESTORE_record_create (struct GNUNET_NAMESTORE_Handle *h,
1231 const struct GNUNET_CRYPTO_RsaPrivateKey *pkey,
1233 const struct GNUNET_NAMESTORE_RecordData *rd,
1234 GNUNET_NAMESTORE_ContinuationWithStatus cont,
1237 struct GNUNET_NAMESTORE_QueueEntry *qe;
1238 struct PendingMessage *pe;
1242 size_t rd_ser_len = 0;
1243 size_t msg_size = 0;
1244 size_t name_len = 0;
1248 GNUNET_assert (NULL != h);
1249 GNUNET_assert (NULL != pkey);
1250 GNUNET_assert (NULL != name);
1251 GNUNET_assert (NULL != rd);
1252 LOG (GNUNET_ERROR_TYPE_DEBUG,
1253 "Creating record of type %u under name `%s'\n",
1256 name_len = strlen(name) + 1;
1264 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
1267 qe->cont_cls = cont_cls;
1269 GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe);
1272 struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded * pkey_enc = GNUNET_CRYPTO_rsa_encode_key (pkey);
1273 GNUNET_assert (pkey_enc != NULL);
1274 key_len = ntohs (pkey_enc->len);
1276 rd_ser_len = GNUNET_NAMESTORE_records_get_size(1, rd);
1277 char rd_ser[rd_ser_len];
1278 GNUNET_NAMESTORE_records_serialize(1, rd, rd_ser_len, rd_ser);
1280 struct RecordCreateMessage * msg;
1281 msg_size = sizeof (struct RecordCreateMessage) + key_len + name_len + rd_ser_len;
1283 /* create msg here */
1284 pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
1285 pe->size = msg_size;
1286 pe->is_init = GNUNET_NO;
1287 msg = (struct RecordCreateMessage *) &pe[1];
1289 pkey_tmp = (char *) &msg[1];
1290 name_tmp = &pkey_tmp[key_len];
1291 rd_tmp = &name_tmp[name_len];
1293 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE);
1294 msg->gns_header.header.size = htons (msg_size);
1295 msg->gns_header.r_id = htonl (rid);
1296 msg->name_len = htons (name_len);
1297 msg->rd_count = htons (1);
1298 msg->rd_len = htons (rd_ser_len);
1299 msg->pkey_len = htons (key_len);
1300 msg->expire = GNUNET_TIME_absolute_hton(GNUNET_TIME_UNIT_FOREVER_ABS);
1301 memcpy (pkey_tmp, pkey_enc, key_len);
1302 memcpy (name_tmp, name, name_len);
1303 memcpy (rd_tmp, rd_ser, rd_ser_len);
1304 GNUNET_free (pkey_enc);
1306 LOG (GNUNET_ERROR_TYPE_DEBUG,
1307 "Sending `%s' message for name `%s' with size %u\n",
1308 "NAMESTORE_RECORD_CREATE", name, msg_size);
1309 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1316 * Explicitly remove some content from the database. The
1317 * "cont"inuation will be called with status "GNUNET_OK" if content
1318 * was removed, "GNUNET_NO" if no matching entry was found and
1319 * "GNUNET_SYSERR" on all other types of errors.
1320 * This API is used by the authority of a zone.
1322 * @param h handle to the namestore
1323 * @param pkey private key of the zone
1324 * @param name name that is being mapped (at most 255 characters long)
1325 * @param rd record data, remove specific record, NULL to remove the name and all records
1326 * @param cont continuation to call when done
1327 * @param cont_cls closure for cont
1328 * @return handle to abort the request
1330 struct GNUNET_NAMESTORE_QueueEntry *
1331 GNUNET_NAMESTORE_record_remove (struct GNUNET_NAMESTORE_Handle *h,
1332 const struct GNUNET_CRYPTO_RsaPrivateKey *pkey,
1334 const struct GNUNET_NAMESTORE_RecordData *rd,
1335 GNUNET_NAMESTORE_ContinuationWithStatus cont,
1338 struct GNUNET_NAMESTORE_QueueEntry *qe;
1339 struct PendingMessage *pe;
1343 size_t rd_ser_len = 0;
1344 size_t msg_size = 0;
1345 size_t name_len = 0;
1348 uint16_t rd_count = 1;
1350 GNUNET_assert (NULL != h);
1352 LOG (GNUNET_ERROR_TYPE_DEBUG,
1353 "Removing record of type %u under name `%s'\n",
1357 LOG (GNUNET_ERROR_TYPE_DEBUG,
1358 "Removing all records under name `%s'\n",
1361 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
1364 qe->cont_cls = cont_cls;
1366 GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe);
1369 struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded * pkey_enc = GNUNET_CRYPTO_rsa_encode_key (pkey);
1370 GNUNET_assert (pkey_enc != NULL);
1371 key_len = ntohs (pkey_enc->len);
1377 rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
1378 char rd_ser[rd_ser_len];
1379 GNUNET_NAMESTORE_records_serialize (rd_count, rd, rd_ser_len, rd_ser);
1381 name_len = strlen (name) + 1;
1383 struct RecordRemoveMessage * msg;
1384 msg_size = sizeof (struct RecordRemoveMessage) + key_len + name_len + rd_ser_len;
1386 /* create msg here */
1387 pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
1388 pe->size = msg_size;
1389 pe->is_init = GNUNET_NO;
1390 msg = (struct RecordRemoveMessage *) &pe[1];
1392 pkey_tmp = (char *) &msg[1];
1393 name_tmp = &pkey_tmp[key_len];
1394 rd_tmp = &name_tmp[name_len];
1396 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE);
1397 msg->gns_header.header.size = htons (msg_size);
1398 msg->gns_header.r_id = htonl (rid);
1399 msg->name_len = htons (name_len);
1400 msg->rd_len = htons (rd_ser_len);
1401 msg->rd_count = htons (rd_count);
1402 msg->pkey_len = htons (key_len);
1403 memcpy (pkey_tmp, pkey_enc, key_len);
1404 memcpy (name_tmp, name, name_len);
1405 memcpy (rd_tmp, rd_ser, rd_ser_len);
1407 GNUNET_free (pkey_enc);
1409 LOG (GNUNET_ERROR_TYPE_DEBUG,
1410 "Sending `%s' message for name `%s' with size %u\n",
1411 "NAMESTORE_RECORD_REMOVE", name, msg_size);
1413 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1420 * Get a result for a particular key from the namestore. The processor
1421 * will only be called once.
1423 * @param h handle to the namestore
1424 * @param zone zone to look up a record from
1425 * @param name name to look up
1426 * @param record_type desired record type, 0 for all
1427 * @param proc function to call on the matching records, or with
1428 * NULL (rd_count == 0) if there are no matching records
1429 * @param proc_cls closure for proc
1430 * @return a handle that can be used to
1433 struct GNUNET_NAMESTORE_QueueEntry *
1434 GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h,
1435 const struct GNUNET_CRYPTO_ShortHashCode *zone,
1437 uint32_t record_type,
1438 GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls)
1440 struct GNUNET_NAMESTORE_QueueEntry *qe;
1441 struct PendingMessage *pe;
1442 size_t msg_size = 0;
1443 size_t name_len = 0;
1446 GNUNET_assert (NULL != h);
1447 GNUNET_assert (NULL != zone);
1448 GNUNET_assert (NULL != name);
1449 LOG (GNUNET_ERROR_TYPE_DEBUG,
1450 "Looking for record of type %u under name `%s'\n",
1454 name_len = strlen (name) + 1;
1455 if ((name_len == 0) || (name_len > 256))
1462 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
1465 qe->proc_cls = proc_cls;
1467 GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe);
1470 msg_size = sizeof (struct LookupNameMessage) + name_len;
1471 pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
1473 /* create msg here */
1474 struct LookupNameMessage * msg;
1475 pe->size = msg_size;
1476 pe->is_init = GNUNET_NO;
1477 msg = (struct LookupNameMessage *) &pe[1];
1478 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME);
1479 msg->gns_header.header.size = htons (msg_size);
1480 msg->gns_header.r_id = htonl (rid);
1481 msg->record_type = htonl (record_type);
1482 msg->name_len = htonl (name_len);
1484 memcpy (&msg[1], name, name_len);
1486 LOG (GNUNET_ERROR_TYPE_DEBUG,
1487 "Sending `%s' message for name `%s'\n", "NAMESTORE_LOOKUP_NAME", name);
1489 /* transmit message */
1490 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1498 * Look for an existing PKEY delegation record for a given public key.
1499 * Returns at most one result to the processor.
1501 * @param h handle to the namestore
1502 * @param zone hash of public key of the zone to look up in, never NULL
1503 * @param value_zone hash of the public key of the target zone (value), never NULL
1504 * @param proc function to call on the matching records, or with
1505 * NULL (rd_count == 0) if there are no matching records
1506 * @param proc_cls closure for proc
1507 * @return a handle that can be used to
1510 struct GNUNET_NAMESTORE_QueueEntry *
1511 GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h,
1512 const struct GNUNET_CRYPTO_ShortHashCode *zone,
1513 const struct GNUNET_CRYPTO_ShortHashCode *value_zone,
1514 GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls)
1516 struct GNUNET_NAMESTORE_QueueEntry *qe;
1517 struct PendingMessage *pe;
1518 size_t msg_size = 0;
1521 GNUNET_assert (NULL != h);
1522 GNUNET_assert (NULL != zone);
1523 GNUNET_assert (NULL != value_zone);
1526 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
1529 qe->proc_cls = proc_cls;
1531 GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe);
1534 msg_size = sizeof (struct ZoneToNameMessage);
1535 pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
1537 /* create msg here */
1538 struct ZoneToNameMessage * msg;
1539 pe->size = msg_size;
1540 pe->is_init = GNUNET_NO;
1541 msg = (struct ZoneToNameMessage *) &pe[1];
1542 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME);
1543 msg->gns_header.header.size = htons (msg_size);
1544 msg->gns_header.r_id = htonl (rid);
1546 msg->value_zone = *value_zone;
1548 char * z_tmp = GNUNET_strdup (GNUNET_short_h2s (zone));
1549 LOG (GNUNET_ERROR_TYPE_DEBUG,
1550 "Sending `%s' message for zone `%s' in zone `%s'\n",
1551 "NAMESTORE_ZONE_TO_NAME",
1553 GNUNET_short_h2s (value_zone));
1554 GNUNET_free (z_tmp);
1556 /* transmit message */
1557 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1566 * Starts a new zone iteration (used to periodically PUT all of our
1567 * records into our DHT). This MUST lock the GNUNET_NAMESTORE_Handle
1568 * for any other calls than GNUNET_NAMESTORE_zone_iterator_next and
1569 * GNUNET_NAMESTORE_zone_iteration_stop. "proc" will be called once
1570 * immediately, and then again after
1571 * "GNUNET_NAMESTORE_zone_iterator_next" is invoked.
1573 * @param h handle to the namestore
1574 * @param zone zone to access, NULL for all zones
1575 * @param must_have_flags flags that must be set for the record to be returned
1576 * @param must_not_have_flags flags that must NOT be set for the record to be returned
1577 * @param proc function to call on each name from the zone; it
1578 * will be called repeatedly with a value (if available)
1579 * and always once at the end with a name of NULL.
1580 * @param proc_cls closure for proc
1581 * @return an iterator handle to use for iteration
1583 struct GNUNET_NAMESTORE_ZoneIterator *
1584 GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h,
1585 const struct GNUNET_CRYPTO_ShortHashCode *zone,
1586 enum GNUNET_NAMESTORE_RecordFlags must_have_flags,
1587 enum GNUNET_NAMESTORE_RecordFlags must_not_have_flags,
1588 GNUNET_NAMESTORE_RecordProcessor proc,
1591 struct GNUNET_NAMESTORE_ZoneIterator *it;
1592 struct PendingMessage *pe;
1593 size_t msg_size = 0;
1596 GNUNET_assert (NULL != h);
1598 it = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_ZoneIterator));
1601 it->proc_cls = proc_cls;
1607 it->has_zone = GNUNET_YES;
1611 memset (&it->zone, '\0', sizeof (it->zone));
1612 it->has_zone = GNUNET_NO;
1614 GNUNET_CONTAINER_DLL_insert_tail(h->z_head, h->z_tail, it);
1617 msg_size = sizeof (struct ZoneIterationStartMessage);
1618 pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
1620 /* create msg here */
1621 struct ZoneIterationStartMessage * msg;
1622 pe->size = msg_size;
1623 pe->is_init = GNUNET_NO;
1624 msg = (struct ZoneIterationStartMessage *) &pe[1];
1625 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START);
1626 msg->gns_header.header.size = htons (msg_size);
1627 msg->gns_header.r_id = htonl (rid);
1630 LOG (GNUNET_ERROR_TYPE_DEBUG,
1631 "Sending `%s' message for zone `%s'\n",
1632 "ZONE_ITERATION_START", GNUNET_short_h2s(zone));
1637 LOG (GNUNET_ERROR_TYPE_DEBUG,
1638 "Sending `%s' message for all zones\n", "ZONE_ITERATION_START");
1639 memset (&msg->zone, '\0', sizeof (msg->zone));
1641 msg->must_have_flags = ntohs (must_have_flags);
1642 msg->must_not_have_flags = ntohs (must_not_have_flags);
1644 /* transmit message */
1645 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1653 * Calls the record processor specified in GNUNET_NAMESTORE_zone_iteration_start
1654 * for the next record.
1656 * @param it the iterator
1659 GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it)
1661 struct GNUNET_NAMESTORE_Handle *h;
1662 struct PendingMessage *pe;
1663 size_t msg_size = 0;
1665 GNUNET_assert (NULL != it);
1667 struct GNUNET_NAMESTORE_ZoneIterator *tmp = it->h->z_head;
1675 GNUNET_assert (NULL != tmp);
1678 msg_size = sizeof (struct ZoneIterationNextMessage);
1679 pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
1681 /* create msg here */
1682 struct ZoneIterationNextMessage * msg;
1683 pe->size = msg_size;
1684 pe->is_init = GNUNET_NO;
1685 msg = (struct ZoneIterationNextMessage *) &pe[1];
1686 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT);
1687 msg->gns_header.header.size = htons (msg_size);
1688 msg->gns_header.r_id = htonl (it->op_id);
1690 LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "ZONE_ITERATION_NEXT");
1692 /* transmit message */
1693 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1699 * Stops iteration and releases the namestore handle for further calls.
1701 * @param it the iterator
1704 GNUNET_NAMESTORE_zone_iteration_stop (struct GNUNET_NAMESTORE_ZoneIterator *it)
1706 GNUNET_assert (NULL != it);
1707 struct PendingMessage *pe;
1708 size_t msg_size = 0;
1709 struct GNUNET_NAMESTORE_Handle *h = it->h;
1710 struct GNUNET_NAMESTORE_ZoneIterator *tmp = it->h->z_head;
1718 GNUNET_assert (NULL != tmp);
1721 msg_size = sizeof (struct ZoneIterationStopMessage);
1722 pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
1724 /* create msg here */
1725 struct ZoneIterationStopMessage * msg;
1726 pe->size = msg_size;
1727 pe->is_init = GNUNET_NO;
1728 msg = (struct ZoneIterationStopMessage *) &pe[1];
1729 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP);
1730 msg->gns_header.header.size = htons (msg_size);
1731 msg->gns_header.r_id = htonl (it->op_id);
1733 if (GNUNET_YES == it->has_zone)
1734 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for zone `%s'\n", "ZONE_ITERATION_STOP", GNUNET_short_h2s(&it->zone));
1736 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for all zones\n", "ZONE_ITERATION_STOP");
1738 /* transmit message */
1739 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1745 * Cancel a namestore operation. The final callback from the
1746 * operation must not have been done yet.
1748 * @param qe operation to cancel
1751 GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe)
1753 struct GNUNET_NAMESTORE_Handle *h = qe->nsh;
1755 GNUNET_assert (qe != NULL);
1756 GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe);
1760 /* end of namestore_api.c */