fix type
[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\n", 
1060        "NAMESTORE_BLOCK_CACHE", 
1061        (unsigned int) msg_size);
1062   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1063   do_transmit (h);
1064   return qe;
1065 }
1066
1067
1068 /**
1069  * Store an item in the namestore.  If the item is already present,
1070  * it is replaced with the new record.  Use an empty array to
1071  * remove all records under the given name.
1072  *
1073  * @param h handle to the namestore
1074  * @param pkey private key of the zone
1075  * @param label name that is being mapped (at most 255 characters long)
1076  * @param rd_count number of records in the 'rd' array
1077  * @param rd array of records with data to store
1078  * @param cont continuation to call when done
1079  * @param cont_cls closure for 'cont'
1080  * @return handle to abort the request
1081  */
1082 struct GNUNET_NAMESTORE_QueueEntry *
1083 GNUNET_NAMESTORE_records_store (struct GNUNET_NAMESTORE_Handle *h,
1084                                 const struct GNUNET_CRYPTO_EccPrivateKey *pkey,
1085                                 const char *label,
1086                                 unsigned int rd_count,
1087                                 const struct GNUNET_NAMESTORE_RecordData *rd,
1088                                 GNUNET_NAMESTORE_ContinuationWithStatus cont,
1089                                 void *cont_cls)
1090 {
1091   struct GNUNET_NAMESTORE_QueueEntry *qe;
1092   struct PendingMessage *pe;
1093   char *name_tmp;
1094   char *rd_ser;
1095   size_t rd_ser_len;
1096   size_t msg_size;
1097   size_t name_len;
1098   uint32_t rid;
1099   struct RecordStoreMessage *msg;
1100
1101   GNUNET_assert (NULL != h);
1102   GNUNET_assert (NULL != pkey);
1103   GNUNET_assert (NULL != label);
1104   name_len = strlen (label) + 1;
1105   if (name_len > MAX_NAME_LEN)
1106   {
1107     GNUNET_break (0);
1108     return NULL;
1109   }
1110   rid = get_op_id (h);
1111   qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1112   qe->nsh = h;
1113   qe->cont = cont;
1114   qe->cont_cls = cont_cls;
1115   qe->op_id = rid;
1116   GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1117
1118   /* setup msg */
1119   rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
1120   msg_size = sizeof (struct RecordStoreMessage) + name_len + rd_ser_len;
1121   pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1122   pe->size = msg_size;
1123   msg = (struct RecordStoreMessage *) &pe[1];
1124   msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE);
1125   msg->gns_header.header.size = htons (msg_size);
1126   msg->gns_header.r_id = htonl (rid);
1127   msg->name_len = htons (name_len);
1128   msg->rd_count = htons (rd_count);
1129   msg->rd_len = htons (rd_ser_len);
1130   msg->reserved = htons (0);
1131   msg->private_key = *pkey;
1132
1133   name_tmp = (char *) &msg[1];
1134   memcpy (name_tmp, label, name_len);
1135   rd_ser = &name_tmp[name_len];
1136   GNUNET_break (rd_ser_len == 
1137                 GNUNET_NAMESTORE_records_serialize (rd_count, rd, 
1138                                                     rd_ser_len, 
1139                                                     rd_ser));
1140   LOG (GNUNET_ERROR_TYPE_DEBUG, 
1141        "Sending `%s' message for name `%s' with size %u and %u records\n", 
1142        "NAMESTORE_RECORD_STORE", label, msg_size,
1143        rd_count);
1144   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1145   do_transmit (h);
1146   return qe;
1147 }
1148
1149
1150 /**
1151  * Get a result for a particular key from the namestore.  The processor
1152  * will only be called once.  
1153  *
1154  * @param h handle to the namestore
1155  * @param derived_hash hash of zone key combined with name to lookup
1156  * @param proc function to call on the matching block, or with
1157  *        NULL if there is no matching block
1158  * @param proc_cls closure for proc
1159  * @return a handle that can be used to cancel
1160  */
1161 struct GNUNET_NAMESTORE_QueueEntry *
1162 GNUNET_NAMESTORE_lookup_block (struct GNUNET_NAMESTORE_Handle *h, 
1163                                const struct GNUNET_HashCode *derived_hash,
1164                                GNUNET_NAMESTORE_BlockProcessor proc, void *proc_cls)
1165 {
1166   struct GNUNET_NAMESTORE_QueueEntry *qe;
1167   struct PendingMessage *pe;
1168   struct LookupBlockMessage *msg;
1169   size_t msg_size;
1170   uint32_t rid;
1171
1172   GNUNET_assert (NULL != h);
1173   GNUNET_assert (NULL != derived_hash);
1174   LOG (GNUNET_ERROR_TYPE_DEBUG,
1175        "Looking for block under %s\n",
1176        GNUNET_h2s (derived_hash));
1177   rid = get_op_id(h);
1178   qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1179   qe->nsh = h;
1180   qe->block_proc = proc;
1181   qe->block_proc_cls = proc_cls;
1182   qe->op_id = rid;
1183   GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1184
1185   msg_size = sizeof (struct LookupBlockMessage);
1186   pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1187   pe->size = msg_size;
1188   msg = (struct LookupBlockMessage *) &pe[1];
1189   msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK);
1190   msg->gns_header.header.size = htons (msg_size);
1191   msg->gns_header.r_id = htonl (rid);
1192   msg->query = *derived_hash;
1193   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1194   do_transmit (h);
1195   return qe;
1196 }
1197
1198
1199 /**
1200  * Look for an existing PKEY delegation record for a given public key.
1201  * Returns at most one result to the processor.
1202  *
1203  * @param h handle to the namestore
1204  * @param zone public key of the zone to look up in, never NULL
1205  * @param value_zone public key of the target zone (value), never NULL
1206  * @param proc function to call on the matching records, or with
1207  *        NULL (rd_count == 0) if there are no matching records
1208  * @param proc_cls closure for @a proc
1209  * @return a handle that can be used to
1210  *         cancel
1211  */
1212 struct GNUNET_NAMESTORE_QueueEntry *
1213 GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h,
1214                                const struct GNUNET_CRYPTO_EccPrivateKey *zone,
1215                                const struct GNUNET_CRYPTO_EccPublicSignKey *value_zone,
1216                                GNUNET_NAMESTORE_RecordMonitor proc, void *proc_cls)
1217 {
1218   struct GNUNET_NAMESTORE_QueueEntry *qe;
1219   struct PendingMessage *pe;
1220   struct ZoneToNameMessage * msg;
1221   size_t msg_size;
1222   uint32_t rid;
1223
1224   GNUNET_assert (NULL != h);
1225   GNUNET_assert (NULL != zone);
1226   GNUNET_assert (NULL != value_zone);
1227   rid = get_op_id(h);
1228   qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1229   qe->nsh = h;
1230   qe->proc = proc;
1231   qe->proc_cls = proc_cls;
1232   qe->op_id = rid;
1233   GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1234
1235   msg_size = sizeof (struct ZoneToNameMessage);
1236   pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1237   pe->size = msg_size;
1238   msg = (struct ZoneToNameMessage *) &pe[1];
1239   msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME);
1240   msg->gns_header.header.size = htons (msg_size);
1241   msg->gns_header.r_id = htonl (rid);
1242   msg->zone = *zone;
1243   msg->value_zone = *value_zone;
1244
1245   /* transmit message */
1246   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1247   do_transmit (h);
1248   return qe;
1249 }
1250
1251
1252 /**
1253  * Starts a new zone iteration (used to periodically PUT all of our
1254  * records into our DHT). This MUST lock the struct GNUNET_NAMESTORE_Handle
1255  * for any other calls than #GNUNET_NAMESTORE_zone_iterator_next and
1256  * #GNUNET_NAMESTORE_zone_iteration_stop. @a proc will be called once
1257  * immediately, and then again after
1258  * #GNUNET_NAMESTORE_zone_iterator_next is invoked.
1259  *
1260  * @param h handle to the namestore
1261  * @param zone zone to access, NULL for all zones
1262  * @param proc function to call on each name from the zone; it
1263  *        will be called repeatedly with a value (if available)
1264  *        and always once at the end with a name of NULL.
1265  * @param proc_cls closure for @a proc
1266  * @return an iterator handle to use for iteration
1267  */
1268 struct GNUNET_NAMESTORE_ZoneIterator *
1269 GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h,
1270                                        const struct GNUNET_CRYPTO_EccPrivateKey *zone,
1271                                        GNUNET_NAMESTORE_RecordMonitor proc,
1272                                        void *proc_cls)
1273 {
1274   struct GNUNET_NAMESTORE_ZoneIterator *it;
1275   struct PendingMessage *pe;
1276   struct ZoneIterationStartMessage * msg;
1277   size_t msg_size;
1278   uint32_t rid;
1279
1280   GNUNET_assert (NULL != h);
1281   rid = get_op_id(h);
1282   it = GNUNET_new (struct GNUNET_NAMESTORE_ZoneIterator);
1283   it->h = h;
1284   it->proc = proc;
1285   it->proc_cls = proc_cls;
1286   it->op_id = rid;
1287   if (NULL != zone)
1288     it->zone = *zone;
1289   GNUNET_CONTAINER_DLL_insert_tail (h->z_head, h->z_tail, it);
1290
1291   msg_size = sizeof (struct ZoneIterationStartMessage);
1292   pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1293   pe->size = msg_size;
1294   msg = (struct ZoneIterationStartMessage *) &pe[1];
1295   msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START);
1296   msg->gns_header.header.size = htons (msg_size);
1297   msg->gns_header.r_id = htonl (rid);
1298   if (NULL != zone)
1299     msg->zone = *zone;
1300   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1301   do_transmit (h);
1302   return it;
1303 }
1304
1305
1306 /**
1307  * Calls the record processor specified in #GNUNET_NAMESTORE_zone_iteration_start
1308  * for the next record.
1309  *
1310  * @param it the iterator
1311  */
1312 void
1313 GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it)
1314 {
1315   struct GNUNET_NAMESTORE_Handle *h;
1316   struct ZoneIterationNextMessage * msg;
1317   struct PendingMessage *pe;
1318   size_t msg_size;
1319
1320   GNUNET_assert (NULL != it);
1321   h = it->h;
1322   msg_size = sizeof (struct ZoneIterationNextMessage);
1323   pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1324   pe->size = msg_size;
1325   msg = (struct ZoneIterationNextMessage *) &pe[1];
1326   msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT);
1327   msg->gns_header.header.size = htons (msg_size);
1328   msg->gns_header.r_id = htonl (it->op_id);
1329   LOG (GNUNET_ERROR_TYPE_DEBUG,
1330        "Sending `%s' message\n", 
1331        "ZONE_ITERATION_NEXT");
1332   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1333   do_transmit (h);
1334 }
1335
1336
1337 /**
1338  * Stops iteration and releases the namestore handle for further calls.
1339  *
1340  * @param it the iterator
1341  */
1342 void
1343 GNUNET_NAMESTORE_zone_iteration_stop (struct GNUNET_NAMESTORE_ZoneIterator *it)
1344 {
1345   struct GNUNET_NAMESTORE_Handle *h;
1346   struct PendingMessage *pe;
1347   size_t msg_size;
1348   struct ZoneIterationStopMessage * msg;
1349
1350   GNUNET_assert (NULL != it);
1351   h = it->h;
1352   GNUNET_CONTAINER_DLL_remove (h->z_head,
1353                                h->z_tail,
1354                                it);
1355   msg_size = sizeof (struct ZoneIterationStopMessage);
1356   pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1357   pe->size = msg_size;
1358   msg = (struct ZoneIterationStopMessage *) &pe[1];
1359   msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP);
1360   msg->gns_header.header.size = htons (msg_size);
1361   msg->gns_header.r_id = htonl (it->op_id);
1362   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
1363               "Sending `%s' message\n", 
1364               "ZONE_ITERATION_STOP");
1365   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1366   do_transmit (h);
1367   GNUNET_free (it);
1368 }
1369
1370
1371 /**
1372  * Cancel a namestore operation.  The final callback from the
1373  * operation must not have been done yet.
1374  *
1375  * @param qe operation to cancel
1376  */
1377 void
1378 GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe)
1379 {
1380   struct GNUNET_NAMESTORE_Handle *h = qe->nsh;
1381
1382   GNUNET_assert (NULL != qe);
1383   GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, qe);
1384   GNUNET_free(qe);
1385 }
1386
1387
1388 /* end of namestore_api.c */