- cleanup dead code
[oweals/gnunet.git] / src / namestore / namestore_api.c
1 /*
2      This file is part of GNUnet.
3      (C) 2010-2013 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file namestore/namestore_api.c
23  * @brief API to access the NAMESTORE service
24  * @author Martin Schanzenbach
25  * @author Matthias Wachs
26  * @author Christian Grothoff
27  */
28
29 #include "platform.h"
30 #include "gnunet_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_namestore_service.h"
37 #include "namestore.h"
38
39
40 #define LOG(kind,...) GNUNET_log_from (kind, "namestore-api",__VA_ARGS__)
41
42
43 /**
44  * An QueueEntry used to store information for a pending
45  * NAMESTORE record operation
46  */
47 struct GNUNET_NAMESTORE_QueueEntry
48 {
49
50   /**
51    * Kept in a DLL.
52    */
53   struct GNUNET_NAMESTORE_QueueEntry *next;
54
55   /**
56    * Kept in a DLL.
57    */
58   struct GNUNET_NAMESTORE_QueueEntry *prev;
59
60   /**
61    * Main handle to access the namestore.
62    */
63   struct GNUNET_NAMESTORE_Handle *nsh;
64
65   /**
66    * Continuation to call
67    */
68   GNUNET_NAMESTORE_ContinuationWithStatus cont;
69
70   /**
71    * Closure for 'cont'.
72    */
73   void *cont_cls;
74
75   /**
76    * Function to call with the records we get back; or NULL.
77    */
78   GNUNET_NAMESTORE_RecordMonitor proc;
79
80   /**
81    * Closure for @e proc.
82    */
83   void *proc_cls;
84
85   /**
86    * Function to call with the blocks we get back; or NULL.
87    */
88   GNUNET_NAMESTORE_BlockProcessor block_proc;
89
90   /**
91    * Closure for @e block_proc.
92    */
93   void *block_proc_cls;
94
95   /**
96    * The operation id this zone iteration operation has
97    */
98   uint32_t op_id;
99
100 };
101
102
103 /**
104  * Handle for a zone iterator operation
105  */
106 struct GNUNET_NAMESTORE_ZoneIterator
107 {
108
109   /**
110    * Kept in a DLL.
111    */
112   struct GNUNET_NAMESTORE_ZoneIterator *next;
113
114   /**
115    * Kept in a DLL.
116    */
117   struct GNUNET_NAMESTORE_ZoneIterator *prev;
118
119   /**
120    * Main handle to access the namestore.
121    */
122   struct GNUNET_NAMESTORE_Handle *h;
123
124   /**
125    * The continuation to call with the results
126    */
127   GNUNET_NAMESTORE_RecordMonitor proc;
128
129   /**
130    * Closure for @e proc.
131    */
132   void* proc_cls;
133
134   /**
135    * Private key of the zone.
136    */
137   struct GNUNET_CRYPTO_EccPrivateKey zone;
138
139   /**
140    * The operation id this zone iteration operation has
141    */
142   uint32_t op_id;
143
144 };
145
146
147 /**
148  * Message in linked list we should send to the service.  The
149  * actual binary message follows this struct.
150  */
151 struct PendingMessage
152 {
153
154   /**
155    * Kept in a DLL.
156    */
157   struct PendingMessage *next;
158
159   /**
160    * Kept in a DLL.
161    */
162   struct PendingMessage *prev;
163
164   /**
165    * Size of the message.
166    */
167   size_t size;
168
169 };
170
171
172 /**
173  * Connection to the NAMESTORE service.
174  */
175 struct GNUNET_NAMESTORE_Handle
176 {
177
178   /**
179    * Configuration to use.
180    */
181   const struct GNUNET_CONFIGURATION_Handle *cfg;
182
183   /**
184    * Socket (if available).
185    */
186   struct GNUNET_CLIENT_Connection *client;
187
188   /**
189    * Currently pending transmission request (or NULL).
190    */
191   struct GNUNET_CLIENT_TransmitHandle *th;
192
193   /**
194    * Head of linked list of pending messages to send to the service
195    */
196   struct PendingMessage *pending_head;
197
198   /**
199    * Tail of linked list of pending messages to send to the service
200    */
201   struct PendingMessage *pending_tail;
202
203   /**
204    * Head of pending namestore queue entries
205    */
206   struct GNUNET_NAMESTORE_QueueEntry *op_head;
207
208   /**
209    * Tail of pending namestore queue entries
210    */
211   struct GNUNET_NAMESTORE_QueueEntry *op_tail;
212
213   /**
214    * Head of pending namestore zone iterator entries
215    */
216   struct GNUNET_NAMESTORE_ZoneIterator *z_head;
217
218   /**
219    * Tail of pending namestore zone iterator entries
220    */
221   struct GNUNET_NAMESTORE_ZoneIterator *z_tail;
222
223   /**
224    * Reconnect task
225    */
226   GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
227
228   /**
229    * Delay introduced before we reconnect.
230    */
231   struct GNUNET_TIME_Relative reconnect_delay;
232
233   /**
234    * Should we reconnect to service due to some serious error?
235    */
236   int reconnect;
237
238   /**
239    * Did we start to receive yet?
240    */
241   int is_receiving;
242
243   /**
244    * The last operation id used for a NAMESTORE operation
245    */
246   uint32_t last_op_id_used;
247
248 };
249
250
251 /**
252  * Disconnect from service and then reconnect.
253  *
254  * @param h our handle
255  */
256 static void
257 force_reconnect (struct GNUNET_NAMESTORE_Handle *h);
258
259
260 /**
261  * Handle an incoming message of type
262  * #GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK_RESPONSE.
263  *
264  * @param qe the respective entry in the message queue
265  * @param msg the message we received
266  * @param size the message size
267  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error and we did NOT notify the client
268  */
269 static int
270 handle_lookup_block_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
271                               const struct LookupBlockResponseMessage *msg,
272                               size_t size)
273 {
274   struct GNUNET_NAMESTORE_Block *block;
275   char buf[size + sizeof (struct GNUNET_NAMESTORE_Block)
276            - sizeof (struct LookupBlockResponseMessage)];
277
278   LOG (GNUNET_ERROR_TYPE_DEBUG,
279        "Received `%s'\n",
280        "LOOKUP_BLOCK_RESPONSE");
281   if (0 == GNUNET_TIME_absolute_ntoh (msg->expire).abs_value_us)
282   {
283     /* no match found */
284     if (NULL != qe->block_proc)
285       qe->block_proc (qe->block_proc_cls, NULL);
286     return GNUNET_OK;
287   }
288
289   block = (struct GNUNET_NAMESTORE_Block *) buf;
290   block->signature = msg->signature;
291   block->derived_key = msg->derived_key;
292   block->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
293   block->purpose.size = htonl (size - sizeof (struct LookupBlockResponseMessage) +
294                                sizeof (struct GNUNET_TIME_AbsoluteNBO) +
295                                sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose));
296   block->expiration_time = msg->expire;
297   memcpy (&block[1],
298           &msg[1],
299           size - sizeof (struct LookupBlockResponseMessage));
300   if (GNUNET_OK !=
301       GNUNET_NAMESTORE_block_verify (block))
302   {
303     GNUNET_break (0);
304     return GNUNET_SYSERR;
305   }
306   if (NULL != qe->block_proc)
307     qe->block_proc (qe->block_proc_cls, block);
308   else
309     GNUNET_break (0);
310   return GNUNET_OK;
311 }
312
313
314 /**
315  * Handle an incoming message of type
316  * #GNUNET_MESSAGE_TYPE_NAMESTORE_BLOCK_CACHE_RESPONSE
317  *
318  * @param qe the respective entry in the message queue
319  * @param msg the message we received
320  * @param size the message size
321  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error and we did NOT notify the client
322  */
323 static int
324 handle_block_cache_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
325                             const struct BlockCacheResponseMessage *msg,
326                             size_t size)
327 {
328   int res;
329
330   LOG (GNUNET_ERROR_TYPE_DEBUG,
331        "Received `%s'\n",
332        "BLOCK_CACHE_RESPONSE");
333   res = ntohl (msg->op_result);
334   /* TODO: add actual error message from namestore to response... */
335   if (NULL != qe->cont)
336     qe->cont (qe->cont_cls,
337               res,
338               (GNUNET_OK == res) ?
339               NULL
340               : _("Namestore failed to cache block"));
341   return GNUNET_OK;
342 }
343
344
345 /**
346  * Handle an incoming message of type
347  * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
348  *
349  * @param qe the respective entry in the message queue
350  * @param msg the message we received
351  * @param size the message size
352  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error and we did NOT notify the client
353  */
354 static int
355 handle_record_store_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
356                               const struct RecordStoreResponseMessage* msg,
357                               size_t size)
358 {
359   int res;
360   const char *emsg;
361
362   LOG (GNUNET_ERROR_TYPE_DEBUG,
363        "Received `%s'\n",
364        "RECORD_STORE_RESPONSE");
365   /* TODO: add actual error message from namestore to response... */
366   res = ntohl (msg->op_result);
367   if (GNUNET_SYSERR == res)
368     emsg = _("Namestore failed to store record\n");
369   else
370     emsg = NULL;
371   if (NULL != qe->cont)
372     qe->cont (qe->cont_cls, res, emsg);
373   return GNUNET_OK;
374 }
375
376
377 /**
378  * Handle an incoming message of type
379  * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
380  *
381  * @param qe the respective entry in the message queue
382  * @param msg the message we received
383  * @param size the message size
384  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error and we did NOT notify the client
385  */
386 static int
387 handle_record_result (struct GNUNET_NAMESTORE_QueueEntry *qe,
388                       const struct RecordResultMessage *msg,
389                       size_t size)
390 {
391   const char *name;
392   const char *rd_tmp;
393   size_t exp_msg_len;
394   size_t msg_len;
395   size_t name_len;
396   size_t rd_len;
397   unsigned int rd_count;
398
399   LOG (GNUNET_ERROR_TYPE_DEBUG,
400        "Received `%s'\n",
401        "RECORD_RESULT");
402   rd_len = ntohs (msg->rd_len);
403   rd_count = ntohs (msg->rd_count);
404   msg_len = ntohs (msg->gns_header.header.size);
405   name_len = ntohs (msg->name_len);
406   GNUNET_break (0 == ntohs (msg->reserved));
407   exp_msg_len = sizeof (struct RecordResultMessage) + name_len + rd_len;
408   if (msg_len != exp_msg_len)
409   {
410     GNUNET_break (0);
411     return GNUNET_SYSERR;
412   }
413   name = (const char *) &msg[1];
414   if ( (name_len > 0) &&
415        ('\0' != name[name_len -1]) )
416   {
417     GNUNET_break (0);
418     return GNUNET_SYSERR;
419   }
420   rd_tmp = &name[name_len];
421   {
422     struct GNUNET_NAMESTORE_RecordData rd[rd_count];
423
424     if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize(rd_len, rd_tmp, rd_count, rd))
425     {
426       GNUNET_break (0);
427       return GNUNET_SYSERR;
428     }
429     if (0 == name_len)
430       name = NULL;
431     if (NULL != qe->proc)
432       qe->proc (qe->proc_cls,
433                 &msg->private_key,
434                 name,
435                 rd_count,
436                 (rd_count > 0) ? rd : NULL);
437   }
438   return GNUNET_OK;
439 }
440
441
442 /**
443  * Handle an incoming message of type
444  * #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
445  *
446  * @param qe the respective entry in the message queue
447  * @param msg the message we received
448  * @param size the message size
449  * @return #GNUNET_OK on success, #GNUNET_NO if we notified the client about
450  *         the error, #GNUNET_SYSERR on error and we did NOT notify the client
451  */
452 static int
453 handle_zone_to_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
454                               const struct ZoneToNameResponseMessage *msg,
455                               size_t size)
456 {
457   int res;
458   size_t name_len;
459   size_t rd_ser_len;
460   unsigned int rd_count;
461   const char *name_tmp;
462   const char *rd_tmp;
463
464   LOG (GNUNET_ERROR_TYPE_DEBUG,
465        "Received `%s'\n",
466        "ZONE_TO_NAME_RESPONSE");
467   res = ntohs (msg->res);
468   switch (res)
469   {
470   case GNUNET_SYSERR:
471     LOG (GNUNET_ERROR_TYPE_DEBUG,
472          "An error occured during zone to name operation\n");
473     break;
474   case GNUNET_NO:
475     LOG (GNUNET_ERROR_TYPE_DEBUG,
476          "Namestore has no result for zone to name mapping \n");
477     break;
478   case GNUNET_YES:
479     LOG (GNUNET_ERROR_TYPE_DEBUG,
480          "Namestore has result for zone to name mapping \n");
481     name_len = ntohs (msg->name_len);
482     rd_count = ntohs (msg->rd_count);
483     rd_ser_len = ntohs (msg->rd_len);
484     name_tmp = (const char *) &msg[1];
485     if ( (name_len > 0) &&
486          ('\0' != name_tmp[name_len -1]) )
487     {
488       GNUNET_break (0);
489       return GNUNET_SYSERR;
490     }
491     rd_tmp = &name_tmp[name_len];
492     {
493       struct GNUNET_NAMESTORE_RecordData rd[rd_count];
494
495       if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_tmp, rd_count, rd))
496       {
497         GNUNET_break (0);
498         return GNUNET_SYSERR;
499       }
500       /* normal end, call continuation with result */
501       if (NULL != qe->proc)
502         qe->proc (qe->proc_cls,
503                   &msg->zone,
504                   name_tmp,
505                   rd_count, rd);
506       /* return is important here: break would call continuation with error! */
507       return GNUNET_OK;
508     }
509   default:
510     GNUNET_break (0);
511     return GNUNET_SYSERR;
512   }
513   /* error case, call continuation with error */
514   if (NULL != qe->proc)
515     qe->proc (qe->proc_cls, NULL, NULL, 0, NULL);
516   return GNUNET_NO;
517 }
518
519
520 /**
521  * Handle incoming messages for record operations
522  *
523  * @param qe the respective zone iteration handle
524  * @param msg the message we received
525  * @param type the message type in host byte order
526  * @param size the message size
527  * @return #GNUNET_OK on success, #GNUNET_NO if we notified the client about
528  *         the error, #GNUNET_SYSERR on error and we did NOT notify the client
529  */
530 static int
531 manage_record_operations (struct GNUNET_NAMESTORE_QueueEntry *qe,
532                           const struct GNUNET_MessageHeader *msg,
533                           uint16_t type,
534                           size_t size)
535 {
536   /* handle different message type */
537   switch (type)
538   {
539   case GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK_RESPONSE:
540     if (size < sizeof (struct LookupBlockResponseMessage))
541     {
542       GNUNET_break (0);
543       return GNUNET_SYSERR;
544     }
545     return handle_lookup_block_response (qe, (const struct LookupBlockResponseMessage *) msg, size);
546   case GNUNET_MESSAGE_TYPE_NAMESTORE_BLOCK_CACHE_RESPONSE:
547     if (size != sizeof (struct BlockCacheResponseMessage))
548     {
549       GNUNET_break (0);
550       return GNUNET_SYSERR;
551     }
552     return handle_block_cache_response (qe, (const struct BlockCacheResponseMessage *) msg, size);
553   case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE:
554     if (size != sizeof (struct RecordStoreResponseMessage))
555     {
556       GNUNET_break (0);
557       return GNUNET_SYSERR;
558     }
559     return handle_record_store_response (qe, (const struct RecordStoreResponseMessage *) msg, size);
560   case GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE:
561     if (size < sizeof (struct ZoneToNameResponseMessage))
562     {
563       GNUNET_break (0);
564       return GNUNET_SYSERR;
565     }
566     return handle_zone_to_name_response (qe, (const struct ZoneToNameResponseMessage *) msg, size);
567   case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT:
568     if (size < sizeof (struct RecordResultMessage))
569     {
570       GNUNET_break (0);
571       return GNUNET_SYSERR;
572     }
573     return handle_record_result (qe, (const struct RecordResultMessage *) msg, size);
574   default:
575     GNUNET_break (0);
576     return GNUNET_SYSERR;
577   }
578 }
579
580
581 /**
582  * Handle a response from NAMESTORE service for a zone iteration request
583  *
584  * @param ze the respective iterator for this operation
585  * @param msg the message containing the respoonse
586  * @param size the message size
587  * @return #GNUNET_YES on success, @a ze should be kept, #GNUNET_NO on success if @a ze should
588  *         not be kept any longer, #GNUNET_SYSERR on error (disconnect) and @a ze should be kept
589  */
590 static int
591 handle_zone_iteration_response (struct GNUNET_NAMESTORE_ZoneIterator *ze,
592                                 const struct RecordResultMessage *msg,
593                                 size_t size)
594 {
595   static struct GNUNET_CRYPTO_EccPrivateKey priv_dummy;
596   size_t msg_len;
597   size_t exp_msg_len;
598   size_t name_len;
599   size_t rd_len;
600   unsigned rd_count;
601   const char *name_tmp;
602   const char *rd_ser_tmp;
603
604   LOG (GNUNET_ERROR_TYPE_DEBUG,
605        "Received `%s'\n",
606        "ZONE_ITERATION_RESPONSE");
607   msg_len = ntohs (msg->gns_header.header.size);
608   rd_len = ntohs (msg->rd_len);
609   rd_count = ntohs (msg->rd_count);
610   name_len = ntohs (msg->name_len);
611   exp_msg_len = sizeof (struct RecordResultMessage) + name_len + rd_len;
612   if (msg_len != exp_msg_len)
613   {
614     GNUNET_break (0);
615     return GNUNET_SYSERR;
616   }
617   if ( (0 == name_len) &&
618        (0 == (memcmp (&msg->private_key,
619                       &priv_dummy,
620                       sizeof (priv_dummy)))) )
621   {
622     LOG (GNUNET_ERROR_TYPE_DEBUG,
623          "Zone iteration completed!\n");
624     if (NULL != ze->proc)
625       ze->proc (ze->proc_cls, NULL, NULL, 0, NULL);
626     return GNUNET_NO;
627   }
628   name_tmp = (const char *) &msg[1];
629   if ((name_tmp[name_len -1] != '\0') || (name_len > MAX_NAME_LEN))
630   {
631     GNUNET_break (0);
632     return GNUNET_SYSERR;
633   }
634   rd_ser_tmp = (const char *) &name_tmp[name_len];
635   {
636     struct GNUNET_NAMESTORE_RecordData rd[rd_count];
637
638     if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize (rd_len,
639                                                            rd_ser_tmp,
640                                                            rd_count,
641                                                            rd))
642     {
643       GNUNET_break (0);
644       return GNUNET_SYSERR;
645     }
646     if (NULL != ze->proc)
647       ze->proc (ze->proc_cls,
648                 &msg->private_key,
649                 name_tmp,
650                 rd_count, rd);
651     return GNUNET_YES;
652   }
653 }
654
655
656 /**
657  * Handle incoming messages for zone iterations
658  *
659  * @param ze the respective zone iteration handle
660  * @param msg the message we received
661  * @param type the message type in HBO
662  * @param size the message size
663  * @return #GNUNET_YES on success, @a ze should be kept, #GNUNET_NO on success if @a ze should
664  *         not be kept any longer, #GNUNET_SYSERR on error (disconnect) and @a ze should be kept
665  */
666 static int
667 manage_zone_operations (struct GNUNET_NAMESTORE_ZoneIterator *ze,
668                         const struct GNUNET_MessageHeader *msg,
669                         int type, size_t size)
670 {
671   /* handle different message type */
672   switch (type)
673   {
674   case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT:
675     if (size < sizeof (struct RecordResultMessage))
676     {
677       GNUNET_break (0);
678       return GNUNET_SYSERR;
679     }
680     return handle_zone_iteration_response (ze,
681                                            (const struct RecordResultMessage *) msg,
682                                            size);
683   default:
684     GNUNET_break (0);
685     return GNUNET_SYSERR;
686   }
687 }
688
689
690 /**
691  * Type of a function to call when we receive a message
692  * from the service.
693  *
694  * @param cls the `struct GNUNET_NAMESTORE_SchedulingHandle`
695  * @param msg message received, NULL on timeout or fatal error
696  */
697 static void
698 process_namestore_message (void *cls,
699                            const struct GNUNET_MessageHeader *msg)
700 {
701   struct GNUNET_NAMESTORE_Handle *h = cls;
702   const struct GNUNET_NAMESTORE_Header *gm;
703   struct GNUNET_NAMESTORE_QueueEntry *qe;
704   struct GNUNET_NAMESTORE_ZoneIterator *ze;
705   uint16_t size;
706   uint16_t type;
707   uint32_t r_id;
708   int ret;
709
710   if (NULL == msg)
711   {
712     force_reconnect (h);
713     return;
714   }
715   size = ntohs (msg->size);
716   type = ntohs (msg->type);
717   if (size < sizeof (struct GNUNET_NAMESTORE_Header))
718   {
719     GNUNET_break_op (0);
720     GNUNET_CLIENT_receive (h->client,
721                            &process_namestore_message, h,
722                            GNUNET_TIME_UNIT_FOREVER_REL);
723     return;
724   }
725   gm = (const struct GNUNET_NAMESTORE_Header *) msg;
726   r_id = ntohl (gm->r_id);
727
728   LOG (GNUNET_ERROR_TYPE_DEBUG,
729        "Received message type %u size %u op %u\n",
730        (unsigned int) type,
731        (unsigned int) size,
732        (unsigned int) r_id);
733
734   /* Is it a record related operation ? */
735   for (qe = h->op_head; qe != NULL; qe = qe->next)
736     if (qe->op_id == r_id)
737       break;
738   if (NULL != qe)
739   {
740     ret = manage_record_operations (qe, msg, type, size);
741     if (GNUNET_SYSERR == ret)
742     {
743       /* protocol error, need to reconnect */
744       h->reconnect = GNUNET_YES;
745     }
746     else
747     {
748       /* client was notified about success or failure, clean up 'qe' */
749       GNUNET_CONTAINER_DLL_remove (h->op_head,
750                                    h->op_tail,
751                                    qe);
752       GNUNET_free (qe);
753     }
754   }
755   /* Is it a zone iteration operation? */
756   for (ze = h->z_head; ze != NULL; ze = ze->next)
757     if (ze->op_id == r_id)
758       break;
759   if (NULL != ze)
760   {
761     ret = manage_zone_operations (ze, msg, type, size);
762     if (GNUNET_NO == ret)
763     {
764       /* end of iteration, clean up 'ze' */
765       GNUNET_CONTAINER_DLL_remove (h->z_head,
766                                    h->z_tail,
767                                    ze);
768       GNUNET_free (ze);
769     }
770     if (GNUNET_SYSERR == ret)
771     {
772       /* protocol error, need to reconnect */
773       h->reconnect = GNUNET_YES;
774     }
775   }
776   if (GNUNET_YES == h->reconnect)
777   {
778     force_reconnect (h);
779     return;
780   }
781   GNUNET_CLIENT_receive (h->client, &process_namestore_message, h,
782                          GNUNET_TIME_UNIT_FOREVER_REL);
783 }
784
785
786 /**
787  * Transmit messages from the message queue to the service
788  * (if there are any, and if we are not already trying).
789  *
790  * @param h handle to use
791  */
792 static void
793 do_transmit (struct GNUNET_NAMESTORE_Handle *h);
794
795
796 /**
797  * We can now transmit a message to NAMESTORE. Do it.
798  *
799  * @param cls the `struct GNUNET_NAMESTORE_Handle`
800  * @param size number of bytes we can transmit
801  * @param buf where to copy the messages
802  * @return number of bytes copied into @a buf
803  */
804 static size_t
805 transmit_message_to_namestore (void *cls,
806                                size_t size,
807                                void *buf)
808 {
809   struct GNUNET_NAMESTORE_Handle *h = cls;
810   struct PendingMessage *p;
811   size_t ret;
812   char *cbuf;
813
814   h->th = NULL;
815   if ((0 == size) || (NULL == buf))
816   {
817     force_reconnect (h);
818     return 0;
819   }
820   ret = 0;
821   cbuf = buf;
822   while ( (NULL != (p = h->pending_head)) &&
823           (p->size <= size) )
824   {
825     memcpy (&cbuf[ret], &p[1], p->size);
826     ret += p->size;
827     size -= p->size;
828     GNUNET_CONTAINER_DLL_remove (h->pending_head,
829                                  h->pending_tail,
830                                  p);
831     if (GNUNET_NO == h->is_receiving)
832     {
833       h->is_receiving = GNUNET_YES;
834       GNUNET_CLIENT_receive (h->client,
835                              &process_namestore_message, h,
836                              GNUNET_TIME_UNIT_FOREVER_REL);
837     }
838     GNUNET_free (p);
839   }
840   do_transmit (h);
841   return ret;
842 }
843
844
845 /**
846  * Transmit messages from the message queue to the service
847  * (if there are any, and if we are not already trying).
848  *
849  * @param h handle to use
850  */
851 static void
852 do_transmit (struct GNUNET_NAMESTORE_Handle *h)
853 {
854   struct PendingMessage *p;
855
856   if (NULL != h->th)
857     return; /* transmission request already pending */
858   if (NULL == (p = h->pending_head))
859     return; /* transmission queue empty */
860   if (NULL == h->client)
861     return;                     /* currently reconnecting */
862   h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, p->size,
863                                                GNUNET_TIME_UNIT_FOREVER_REL,
864                                                GNUNET_NO, &transmit_message_to_namestore,
865                                                h);
866   GNUNET_break (NULL != h->th);
867 }
868
869
870 /**
871  * Reconnect to namestore service.
872  *
873  * @param h the handle to the NAMESTORE service
874  */
875 static void
876 reconnect (struct GNUNET_NAMESTORE_Handle *h)
877 {
878   GNUNET_assert (NULL == h->client);
879   h->client = GNUNET_CLIENT_connect ("namestore", h->cfg);
880   GNUNET_assert (NULL != h->client);
881   do_transmit (h);
882 }
883
884
885 /**
886  * Re-establish the connection to the service.
887  *
888  * @param cls handle to use to re-connect.
889  * @param tc scheduler context
890  */
891 static void
892 reconnect_task (void *cls,
893                 const struct GNUNET_SCHEDULER_TaskContext *tc)
894 {
895   struct GNUNET_NAMESTORE_Handle *h = cls;
896
897   h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
898   reconnect (h);
899 }
900
901
902 /**
903  * Disconnect from service and then reconnect.
904  *
905  * @param h our handle
906  */
907 static void
908 force_reconnect (struct GNUNET_NAMESTORE_Handle *h)
909 {
910   if (NULL != h->th)
911   {
912     GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
913     h->th = NULL;
914   }
915   h->reconnect = GNUNET_NO;
916   GNUNET_CLIENT_disconnect (h->client);
917   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
918               "Reconnecting to namestore\n");
919   h->is_receiving = GNUNET_NO;
920   h->client = NULL;
921   h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay);
922   h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_delay,
923                                                     &reconnect_task,
924                                                     h);
925 }
926
927
928 /**
929  * Get a fresh operation id to distinguish between namestore requests
930  *
931  * @param h the namestore handle
932  * @return next operation id to use
933  */
934 static uint32_t
935 get_op_id (struct GNUNET_NAMESTORE_Handle *h)
936 {
937   return h->last_op_id_used++;
938 }
939
940
941 /**
942  * Initialize the connection with the NAMESTORE service.
943  *
944  * @param cfg configuration to use
945  * @return handle to the GNS service, or NULL on error
946  */
947 struct GNUNET_NAMESTORE_Handle *
948 GNUNET_NAMESTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
949 {
950   struct GNUNET_NAMESTORE_Handle *h;
951
952   h = GNUNET_new (struct GNUNET_NAMESTORE_Handle);
953   h->cfg = cfg;
954   h->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect_task, h);
955   h->last_op_id_used = 0;
956   return h;
957 }
958
959
960 /**
961  * Disconnect from the namestore service (and free associated
962  * resources).
963  *
964  * @param h handle to the namestore
965  */
966 void
967 GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h)
968 {
969   struct PendingMessage *p;
970   struct GNUNET_NAMESTORE_QueueEntry *q;
971   struct GNUNET_NAMESTORE_ZoneIterator *z;
972
973   LOG (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
974   GNUNET_assert (NULL != h);
975   if (NULL != h->th)
976   {
977     GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
978     h->th = NULL;
979   }
980   while (NULL != (p = h->pending_head))
981   {
982     GNUNET_CONTAINER_DLL_remove (h->pending_head, h->pending_tail, p);
983     GNUNET_free (p);
984   }
985   GNUNET_break (NULL == h->op_head);
986   while (NULL != (q = h->op_head))
987   {
988     GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, q);
989     GNUNET_free (q);
990   }
991   GNUNET_break (NULL == h->z_head);
992   while (NULL != (z = h->z_head))
993   {
994     GNUNET_CONTAINER_DLL_remove (h->z_head, h->z_tail, z);
995     GNUNET_free (z);
996   }
997   if (NULL != h->client)
998   {
999     GNUNET_CLIENT_disconnect (h->client);
1000     h->client = NULL;
1001   }
1002   if (GNUNET_SCHEDULER_NO_TASK != h->reconnect_task)
1003   {
1004     GNUNET_SCHEDULER_cancel (h->reconnect_task);
1005     h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
1006   }
1007   GNUNET_free (h);
1008 }
1009
1010
1011 /**
1012  * Store an item in the namestore.  If the item is already present,
1013  * it is replaced with the new record.
1014  *
1015  * @param h handle to the namestore
1016  * @param block block to store
1017  * @param cont continuation to call when done
1018  * @param cont_cls closure for cont
1019  * @return handle to abort the request
1020  */
1021 struct GNUNET_NAMESTORE_QueueEntry *
1022 GNUNET_NAMESTORE_block_cache (struct GNUNET_NAMESTORE_Handle *h,
1023                               const struct GNUNET_NAMESTORE_Block *block,
1024                               GNUNET_NAMESTORE_ContinuationWithStatus cont,
1025                               void *cont_cls)
1026 {
1027   struct GNUNET_NAMESTORE_QueueEntry *qe;
1028   struct PendingMessage *pe;
1029   struct BlockCacheMessage *msg;
1030   uint32_t rid;
1031   size_t blen;
1032   size_t msg_size;
1033
1034   GNUNET_assert (NULL != h);
1035   blen = ntohl (block->purpose.size)
1036     - sizeof (struct GNUNET_TIME_AbsoluteNBO)
1037     - sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose);
1038   rid = get_op_id (h);
1039   qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1040   qe->nsh = h;
1041   qe->cont = cont;
1042   qe->cont_cls = cont_cls;
1043   qe->op_id = rid;
1044   GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1045
1046   /* setup msg */
1047   msg_size = sizeof (struct BlockCacheMessage) + blen;
1048   pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1049   pe->size = msg_size;
1050   msg = (struct BlockCacheMessage *) &pe[1];
1051   msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_BLOCK_CACHE);
1052   msg->gns_header.header.size = htons (msg_size);
1053   msg->gns_header.r_id = htonl (rid);
1054   msg->expire = block->expiration_time;
1055   msg->signature = block->signature;
1056   msg->derived_key = block->derived_key;
1057   memcpy (&msg[1], &block[1], blen);
1058   LOG (GNUNET_ERROR_TYPE_DEBUG,
1059        "Sending `%s' message with size %u and expiration %s\n",
1060        "NAMESTORE_BLOCK_CACHE",
1061        (unsigned int) msg_size,
1062        GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (msg->expire)));
1063   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1064   do_transmit (h);
1065   return qe;
1066 }
1067
1068
1069 /**
1070  * Store an item in the namestore.  If the item is already present,
1071  * it is replaced with the new record.  Use an empty array to
1072  * remove all records under the given name.
1073  *
1074  * @param h handle to the namestore
1075  * @param pkey private key of the zone
1076  * @param label name that is being mapped (at most 255 characters long)
1077  * @param rd_count number of records in the 'rd' array
1078  * @param rd array of records with data to store
1079  * @param cont continuation to call when done
1080  * @param cont_cls closure for 'cont'
1081  * @return handle to abort the request
1082  */
1083 struct GNUNET_NAMESTORE_QueueEntry *
1084 GNUNET_NAMESTORE_records_store (struct GNUNET_NAMESTORE_Handle *h,
1085                                 const struct GNUNET_CRYPTO_EccPrivateKey *pkey,
1086                                 const char *label,
1087                                 unsigned int rd_count,
1088                                 const struct GNUNET_NAMESTORE_RecordData *rd,
1089                                 GNUNET_NAMESTORE_ContinuationWithStatus cont,
1090                                 void *cont_cls)
1091 {
1092   struct GNUNET_NAMESTORE_QueueEntry *qe;
1093   struct PendingMessage *pe;
1094   char *name_tmp;
1095   char *rd_ser;
1096   size_t rd_ser_len;
1097   size_t msg_size;
1098   size_t name_len;
1099   uint32_t rid;
1100   struct RecordStoreMessage *msg;
1101
1102   GNUNET_assert (NULL != h);
1103   GNUNET_assert (NULL != pkey);
1104   GNUNET_assert (NULL != label);
1105   name_len = strlen (label) + 1;
1106   if (name_len > MAX_NAME_LEN)
1107   {
1108     GNUNET_break (0);
1109     return NULL;
1110   }
1111   rid = get_op_id (h);
1112   qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1113   qe->nsh = h;
1114   qe->cont = cont;
1115   qe->cont_cls = cont_cls;
1116   qe->op_id = rid;
1117   GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1118
1119   /* setup msg */
1120   rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
1121   msg_size = sizeof (struct RecordStoreMessage) + name_len + rd_ser_len;
1122   pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1123   pe->size = msg_size;
1124   msg = (struct RecordStoreMessage *) &pe[1];
1125   msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE);
1126   msg->gns_header.header.size = htons (msg_size);
1127   msg->gns_header.r_id = htonl (rid);
1128   msg->name_len = htons (name_len);
1129   msg->rd_count = htons (rd_count);
1130   msg->rd_len = htons (rd_ser_len);
1131   msg->reserved = htons (0);
1132   msg->private_key = *pkey;
1133
1134   name_tmp = (char *) &msg[1];
1135   memcpy (name_tmp, label, name_len);
1136   rd_ser = &name_tmp[name_len];
1137   GNUNET_break (rd_ser_len ==
1138                 GNUNET_NAMESTORE_records_serialize (rd_count, rd,
1139                                                     rd_ser_len,
1140                                                     rd_ser));
1141   LOG (GNUNET_ERROR_TYPE_DEBUG,
1142        "Sending `%s' message for name `%s' with size %u and %u records\n",
1143        "NAMESTORE_RECORD_STORE", label, msg_size,
1144        rd_count);
1145   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1146   do_transmit (h);
1147   return qe;
1148 }
1149
1150
1151 /**
1152  * Get a result for a particular key from the namestore.  The processor
1153  * will only be called once.
1154  *
1155  * @param h handle to the namestore
1156  * @param derived_hash hash of zone key combined with name to lookup
1157  * @param proc function to call on the matching block, or with
1158  *        NULL if there is no matching block
1159  * @param proc_cls closure for proc
1160  * @return a handle that can be used to cancel
1161  */
1162 struct GNUNET_NAMESTORE_QueueEntry *
1163 GNUNET_NAMESTORE_lookup_block (struct GNUNET_NAMESTORE_Handle *h,
1164                                const struct GNUNET_HashCode *derived_hash,
1165                                GNUNET_NAMESTORE_BlockProcessor proc, void *proc_cls)
1166 {
1167   struct GNUNET_NAMESTORE_QueueEntry *qe;
1168   struct PendingMessage *pe;
1169   struct LookupBlockMessage *msg;
1170   size_t msg_size;
1171   uint32_t rid;
1172
1173   GNUNET_assert (NULL != h);
1174   GNUNET_assert (NULL != derived_hash);
1175   LOG (GNUNET_ERROR_TYPE_DEBUG,
1176        "Looking for block under %s\n",
1177        GNUNET_h2s (derived_hash));
1178   rid = get_op_id(h);
1179   qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1180   qe->nsh = h;
1181   qe->block_proc = proc;
1182   qe->block_proc_cls = proc_cls;
1183   qe->op_id = rid;
1184   GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1185
1186   msg_size = sizeof (struct LookupBlockMessage);
1187   pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1188   pe->size = msg_size;
1189   msg = (struct LookupBlockMessage *) &pe[1];
1190   msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK);
1191   msg->gns_header.header.size = htons (msg_size);
1192   msg->gns_header.r_id = htonl (rid);
1193   msg->query = *derived_hash;
1194   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1195   do_transmit (h);
1196   return qe;
1197 }
1198
1199
1200 /**
1201  * Look for an existing PKEY delegation record for a given public key.
1202  * Returns at most one result to the processor.
1203  *
1204  * @param h handle to the namestore
1205  * @param zone public key of the zone to look up in, never NULL
1206  * @param value_zone public key of the target zone (value), never NULL
1207  * @param proc function to call on the matching records, or with
1208  *        NULL (rd_count == 0) if there are no matching records
1209  * @param proc_cls closure for @a proc
1210  * @return a handle that can be used to
1211  *         cancel
1212  */
1213 struct GNUNET_NAMESTORE_QueueEntry *
1214 GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h,
1215                                const struct GNUNET_CRYPTO_EccPrivateKey *zone,
1216                                const struct GNUNET_CRYPTO_EccPublicSignKey *value_zone,
1217                                GNUNET_NAMESTORE_RecordMonitor proc, void *proc_cls)
1218 {
1219   struct GNUNET_NAMESTORE_QueueEntry *qe;
1220   struct PendingMessage *pe;
1221   struct ZoneToNameMessage * msg;
1222   size_t msg_size;
1223   uint32_t rid;
1224
1225   GNUNET_assert (NULL != h);
1226   GNUNET_assert (NULL != zone);
1227   GNUNET_assert (NULL != value_zone);
1228   rid = get_op_id(h);
1229   qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1230   qe->nsh = h;
1231   qe->proc = proc;
1232   qe->proc_cls = proc_cls;
1233   qe->op_id = rid;
1234   GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1235
1236   msg_size = sizeof (struct ZoneToNameMessage);
1237   pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1238   pe->size = msg_size;
1239   msg = (struct ZoneToNameMessage *) &pe[1];
1240   msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME);
1241   msg->gns_header.header.size = htons (msg_size);
1242   msg->gns_header.r_id = htonl (rid);
1243   msg->zone = *zone;
1244   msg->value_zone = *value_zone;
1245
1246   /* transmit message */
1247   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1248   do_transmit (h);
1249   return qe;
1250 }
1251
1252
1253 /**
1254  * Starts a new zone iteration (used to periodically PUT all of our
1255  * records into our DHT). This MUST lock the struct GNUNET_NAMESTORE_Handle
1256  * for any other calls than #GNUNET_NAMESTORE_zone_iterator_next and
1257  * #GNUNET_NAMESTORE_zone_iteration_stop. @a proc will be called once
1258  * immediately, and then again after
1259  * #GNUNET_NAMESTORE_zone_iterator_next is invoked.
1260  *
1261  * @param h handle to the namestore
1262  * @param zone zone to access, NULL for all zones
1263  * @param proc function to call on each name from the zone; it
1264  *        will be called repeatedly with a value (if available)
1265  *        and always once at the end with a name of NULL.
1266  * @param proc_cls closure for @a proc
1267  * @return an iterator handle to use for iteration
1268  */
1269 struct GNUNET_NAMESTORE_ZoneIterator *
1270 GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h,
1271                                        const struct GNUNET_CRYPTO_EccPrivateKey *zone,
1272                                        GNUNET_NAMESTORE_RecordMonitor proc,
1273                                        void *proc_cls)
1274 {
1275   struct GNUNET_NAMESTORE_ZoneIterator *it;
1276   struct PendingMessage *pe;
1277   struct ZoneIterationStartMessage * msg;
1278   size_t msg_size;
1279   uint32_t rid;
1280
1281   GNUNET_assert (NULL != h);
1282   rid = get_op_id(h);
1283   it = GNUNET_new (struct GNUNET_NAMESTORE_ZoneIterator);
1284   it->h = h;
1285   it->proc = proc;
1286   it->proc_cls = proc_cls;
1287   it->op_id = rid;
1288   if (NULL != zone)
1289     it->zone = *zone;
1290   GNUNET_CONTAINER_DLL_insert_tail (h->z_head, h->z_tail, it);
1291
1292   msg_size = sizeof (struct ZoneIterationStartMessage);
1293   pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1294   pe->size = msg_size;
1295   msg = (struct ZoneIterationStartMessage *) &pe[1];
1296   msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START);
1297   msg->gns_header.header.size = htons (msg_size);
1298   msg->gns_header.r_id = htonl (rid);
1299   if (NULL != zone)
1300     msg->zone = *zone;
1301   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1302   do_transmit (h);
1303   return it;
1304 }
1305
1306
1307 /**
1308  * Calls the record processor specified in #GNUNET_NAMESTORE_zone_iteration_start
1309  * for the next record.
1310  *
1311  * @param it the iterator
1312  */
1313 void
1314 GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it)
1315 {
1316   struct GNUNET_NAMESTORE_Handle *h;
1317   struct ZoneIterationNextMessage * msg;
1318   struct PendingMessage *pe;
1319   size_t msg_size;
1320
1321   GNUNET_assert (NULL != it);
1322   h = it->h;
1323   msg_size = sizeof (struct ZoneIterationNextMessage);
1324   pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1325   pe->size = msg_size;
1326   msg = (struct ZoneIterationNextMessage *) &pe[1];
1327   msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT);
1328   msg->gns_header.header.size = htons (msg_size);
1329   msg->gns_header.r_id = htonl (it->op_id);
1330   LOG (GNUNET_ERROR_TYPE_DEBUG,
1331        "Sending `%s' message\n",
1332        "ZONE_ITERATION_NEXT");
1333   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1334   do_transmit (h);
1335 }
1336
1337
1338 /**
1339  * Stops iteration and releases the namestore handle for further calls.
1340  *
1341  * @param it the iterator
1342  */
1343 void
1344 GNUNET_NAMESTORE_zone_iteration_stop (struct GNUNET_NAMESTORE_ZoneIterator *it)
1345 {
1346   struct GNUNET_NAMESTORE_Handle *h;
1347   struct PendingMessage *pe;
1348   size_t msg_size;
1349   struct ZoneIterationStopMessage * msg;
1350
1351   GNUNET_assert (NULL != it);
1352   h = it->h;
1353   GNUNET_CONTAINER_DLL_remove (h->z_head,
1354                                h->z_tail,
1355                                it);
1356   msg_size = sizeof (struct ZoneIterationStopMessage);
1357   pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1358   pe->size = msg_size;
1359   msg = (struct ZoneIterationStopMessage *) &pe[1];
1360   msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP);
1361   msg->gns_header.header.size = htons (msg_size);
1362   msg->gns_header.r_id = htonl (it->op_id);
1363   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1364               "Sending `%s' message\n",
1365               "ZONE_ITERATION_STOP");
1366   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1367   do_transmit (h);
1368   GNUNET_free (it);
1369 }
1370
1371
1372 /**
1373  * Cancel a namestore operation.  The final callback from the
1374  * operation must not have been done yet.
1375  *
1376  * @param qe operation to cancel
1377  */
1378 void
1379 GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe)
1380 {
1381   struct GNUNET_NAMESTORE_Handle *h = qe->nsh;
1382
1383   GNUNET_assert (NULL != qe);
1384   GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, qe);
1385   GNUNET_free(qe);
1386 }
1387
1388
1389 /* end of namestore_api.c */