fixing compiler warnings
[oweals/gnunet.git] / src / cadet / cadet_api.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2011 GNUnet e.V.
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., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20 /**
21  * @file cadet/cadet_api.c
22  * @brief cadet api: client implementation of new cadet service
23  * @author Bartlomiej Polot
24  */
25
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_cadet_service.h"
29 #include "cadet.h"
30 #include "cadet_protocol.h"
31
32 #define LOG(kind,...) GNUNET_log_from (kind, "cadet-api",__VA_ARGS__)
33 #define DATA_OVERHEAD sizeof(struct GNUNET_CADET_LocalData)
34
35 /******************************************************************************/
36 /************************      DATA STRUCTURES     ****************************/
37 /******************************************************************************/
38
39 /**
40  * Transmission queue to the service
41  */
42 struct GNUNET_CADET_TransmitHandle
43 {
44
45     /**
46      * Double Linked list
47      */
48   struct GNUNET_CADET_TransmitHandle *next;
49
50     /**
51      * Double Linked list
52      */
53   struct GNUNET_CADET_TransmitHandle *prev;
54
55     /**
56      * Channel this message is sent on / for (may be NULL for control messages).
57      */
58   struct GNUNET_CADET_Channel *channel;
59
60     /**
61      * Callback to obtain the message to transmit, or NULL if we
62      * got the message in 'data'.  Notice that messages built
63      * by 'notify' need to be encapsulated with information about
64      * the 'target'.
65      */
66   GNUNET_CONNECTION_TransmitReadyNotify notify;
67
68     /**
69      * Closure for 'notify'
70      */
71   void *notify_cls;
72
73     /**
74      * How long is this message valid.  Once the timeout has been
75      * reached, the message must no longer be sent.  If this
76      * is a message with a 'notify' callback set, the 'notify'
77      * function should be called with 'buf' NULL and size 0.
78      */
79   struct GNUNET_TIME_Absolute timeout;
80
81     /**
82      * Task triggering a timeout, can be NO_TASK if the timeout is FOREVER.
83      */
84   struct GNUNET_SCHEDULER_Task * timeout_task;
85
86     /**
87      * Size of 'data' -- or the desired size of 'notify' if 'data' is NULL.
88      */
89   size_t size;
90 };
91
92 union CadetInfoCB {
93
94   /**
95    * Channel callback.
96    */
97   GNUNET_CADET_ChannelCB channel_cb;
98
99   /**
100    * Monitor callback
101    */
102   GNUNET_CADET_PeersCB peers_cb;
103
104   /**
105    * Monitor callback
106    */
107   GNUNET_CADET_PeerCB peer_cb;
108
109   /**
110    * Monitor callback
111    */
112   GNUNET_CADET_TunnelsCB tunnels_cb;
113
114   /**
115    * Tunnel callback.
116    */
117   GNUNET_CADET_TunnelCB tunnel_cb;
118 };
119
120
121 /**
122  * Opaque handle to the service.
123  */
124 struct GNUNET_CADET_Handle
125 {
126
127     /**
128      * Handle to the server connection, to send messages later
129      */
130   struct GNUNET_CLIENT_Connection *client;
131
132     /**
133      * Set of handlers used for processing incoming messages in the channels
134      */
135   const struct GNUNET_CADET_MessageHandler *message_handlers;
136
137   /**
138    * Number of handlers in the handlers array.
139    */
140   unsigned int n_handlers;
141
142   /**
143    * Ports open.
144    */
145   const uint32_t *ports;
146
147   /**
148    * Number of ports.
149    */
150   unsigned int n_ports;
151
152     /**
153      * Double linked list of the channels this client is connected to, head.
154      */
155   struct GNUNET_CADET_Channel *channels_head;
156
157     /**
158      * Double linked list of the channels this client is connected to, tail.
159      */
160   struct GNUNET_CADET_Channel *channels_tail;
161
162     /**
163      * Callback for inbound channel creation
164      */
165   GNUNET_CADET_InboundChannelNotificationHandler *new_channel;
166
167     /**
168      * Callback for inbound channel disconnection
169      */
170   GNUNET_CADET_ChannelEndHandler *cleaner;
171
172     /**
173      * Handle to cancel pending transmissions in case of disconnection
174      */
175   struct GNUNET_CLIENT_TransmitHandle *th;
176
177     /**
178      * Closure for all the handlers given by the client
179      */
180   void *cls;
181
182     /**
183      * Messages to send to the service, head.
184      */
185   struct GNUNET_CADET_TransmitHandle *th_head;
186
187     /**
188      * Messages to send to the service, tail.
189      */
190   struct GNUNET_CADET_TransmitHandle *th_tail;
191
192     /**
193      * chid of the next channel to create (to avoid reusing IDs often)
194      */
195   CADET_ChannelNumber next_chid;
196
197     /**
198      * Have we started the task to receive messages from the service
199      * yet? We do this after we send the 'CADET_LOCAL_CONNECT' message.
200      */
201   int in_receive;
202
203   /**
204    * Configuration given by the client, in case of reconnection
205    */
206   const struct GNUNET_CONFIGURATION_Handle *cfg;
207
208   /**
209    * Time to the next reconnect in case one reconnect fails
210    */
211   struct GNUNET_TIME_Relative reconnect_time;
212
213   /**
214    * Task for trying to reconnect.
215    */
216   struct GNUNET_SCHEDULER_Task * reconnect_task;
217
218   /**
219    * Callback for an info task (only one active at a time).
220    */
221   union CadetInfoCB info_cb;
222
223   /**
224    * Info callback closure for @c info_cb.
225    */
226   void *info_cls;
227 };
228
229
230 /**
231  * Description of a peer
232  */
233 struct GNUNET_CADET_Peer
234 {
235     /**
236      * ID of the peer in short form
237      */
238   GNUNET_PEER_Id id;
239
240   /**
241    * Channel this peer belongs to
242    */
243   struct GNUNET_CADET_Channel *t;
244 };
245
246
247 /**
248  * Opaque handle to a channel.
249  */
250 struct GNUNET_CADET_Channel
251 {
252
253     /**
254      * DLL next
255      */
256   struct GNUNET_CADET_Channel *next;
257
258     /**
259      * DLL prev
260      */
261   struct GNUNET_CADET_Channel *prev;
262
263     /**
264      * Handle to the cadet this channel belongs to
265      */
266   struct GNUNET_CADET_Handle *cadet;
267
268     /**
269      * Local ID of the channel
270      */
271   CADET_ChannelNumber chid;
272
273     /**
274      * Port number.
275      */
276   uint32_t port;
277
278     /**
279      * Other end of the channel.
280      */
281   GNUNET_PEER_Id peer;
282
283   /**
284    * Any data the caller wants to put in here
285    */
286   void *ctx;
287
288     /**
289      * Size of packet queued in this channel
290      */
291   unsigned int packet_size;
292
293     /**
294      * Channel options: reliability, etc.
295      */
296   enum GNUNET_CADET_ChannelOption options;
297
298     /**
299      * Are we allowed to send to the service?
300      */
301   int allow_send;
302
303 };
304
305
306 /**
307  * Implementation state for cadet's message queue.
308  */
309 struct CadetMQState
310 {
311   /**
312    * The current transmit handle, or NULL
313    * if no transmit is active.
314    */
315   struct GNUNET_CADET_TransmitHandle *th;
316
317   /**
318    * Channel to send the data over.
319    */
320   struct GNUNET_CADET_Channel *channel;
321 };
322
323
324 /******************************************************************************/
325 /***********************         DECLARATIONS         *************************/
326 /******************************************************************************/
327
328 /**
329  * Function called to send a message to the service.
330  * "buf" will be NULL and "size" zero if the socket was closed for writing in
331  * the meantime.
332  *
333  * @param cls closure, the cadet handle
334  * @param size number of bytes available in buf
335  * @param buf where the callee should write the connect message
336  * @return number of bytes written to buf
337  */
338 static size_t
339 send_callback (void *cls, size_t size, void *buf);
340
341
342 /******************************************************************************/
343 /***********************     AUXILIARY FUNCTIONS      *************************/
344 /******************************************************************************/
345
346 /**
347  * Check if transmission is a payload packet.
348  *
349  * @param th Transmission handle.
350  *
351  * @return #GNUNET_YES if it is a payload packet,
352  *         #GNUNET_NO if it is a cadet management packet.
353  */
354 static int
355 th_is_payload (struct GNUNET_CADET_TransmitHandle *th)
356 {
357   return (th->notify != NULL) ? GNUNET_YES : GNUNET_NO;
358 }
359
360
361 /**
362  * Check whether there is any message ready in the queue and find the size.
363  *
364  * @param h Cadet handle.
365  *
366  * @return The size of the first ready message in the queue, including overhead.
367  *         0 if there is none.
368  */
369 static size_t
370 message_ready_size (struct GNUNET_CADET_Handle *h)
371 {
372   struct GNUNET_CADET_TransmitHandle *th;
373   struct GNUNET_CADET_Channel *ch;
374
375   for (th = h->th_head; NULL != th; th = th->next)
376   {
377     ch = th->channel;
378     if (GNUNET_NO == th_is_payload (th) || GNUNET_YES == ch->allow_send)
379       return th->size;
380   }
381   return 0;
382 }
383
384
385 /**
386  * Get the channel handler for the channel specified by id from the given handle
387  * @param h Cadet handle
388  * @param chid ID of the wanted channel
389  * @return handle to the required channel or NULL if not found
390  */
391 static struct GNUNET_CADET_Channel *
392 retrieve_channel (struct GNUNET_CADET_Handle *h, CADET_ChannelNumber chid)
393 {
394   struct GNUNET_CADET_Channel *ch;
395
396   ch = h->channels_head;
397   while (ch != NULL)
398   {
399     if (ch->chid == chid)
400       return ch;
401     ch = ch->next;
402   }
403   return NULL;
404 }
405
406
407 /**
408  * Create a new channel and insert it in the channel list of the cadet handle
409  *
410  * @param h Cadet handle
411  * @param chid Desired chid of the channel, 0 to assign one automatically.
412  *
413  * @return Handle to the created channel.
414  */
415 static struct GNUNET_CADET_Channel *
416 create_channel (struct GNUNET_CADET_Handle *h, CADET_ChannelNumber chid)
417 {
418   struct GNUNET_CADET_Channel *ch;
419
420   ch = GNUNET_new (struct GNUNET_CADET_Channel);
421   GNUNET_CONTAINER_DLL_insert (h->channels_head, h->channels_tail, ch);
422   ch->cadet = h;
423   if (0 == chid)
424   {
425     ch->chid = h->next_chid;
426     while (NULL != retrieve_channel (h, h->next_chid))
427     {
428       h->next_chid++;
429       h->next_chid &= ~GNUNET_CADET_LOCAL_CHANNEL_ID_SERV;
430       h->next_chid |= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
431     }
432   }
433   else
434   {
435     ch->chid = chid;
436   }
437   ch->allow_send = GNUNET_NO;
438   return ch;
439 }
440
441
442 /**
443  * Destroy the specified channel.
444  * - Destroys all peers, calling the disconnect callback on each if needed
445  * - Cancels all outgoing traffic for that channel, calling respective notifys
446  * - Calls cleaner if channel was inbound
447  * - Frees all memory used
448  *
449  * @param ch Pointer to the channel.
450  * @param call_cleaner Whether to call the cleaner handler.
451  *
452  * @return Handle to the required channel or NULL if not found.
453  */
454 static void
455 destroy_channel (struct GNUNET_CADET_Channel *ch, int call_cleaner)
456 {
457   struct GNUNET_CADET_Handle *h;
458   struct GNUNET_CADET_TransmitHandle *th;
459   struct GNUNET_CADET_TransmitHandle *next;
460
461   LOG (GNUNET_ERROR_TYPE_DEBUG, " destroy_channel %X\n", ch->chid);
462
463   if (NULL == ch)
464   {
465     GNUNET_break (0);
466     return;
467   }
468   h = ch->cadet;
469
470   GNUNET_CONTAINER_DLL_remove (h->channels_head, h->channels_tail, ch);
471
472   /* signal channel destruction */
473   if ( (NULL != h->cleaner) && (0 != ch->peer) && (GNUNET_YES == call_cleaner) )
474   {
475     LOG (GNUNET_ERROR_TYPE_DEBUG, " calling cleaner\n");
476     h->cleaner (h->cls, ch, ch->ctx);
477   }
478
479   /* check that clients did not leave messages behind in the queue */
480   for (th = h->th_head; NULL != th; th = next)
481   {
482     next = th->next;
483     if (th->channel != ch)
484       continue;
485     /* Clients should have aborted their requests already.
486      * Management traffic should be ok, as clients can't cancel that.
487      * If the service crashed and we are reconnecting, it's ok.
488      */
489     GNUNET_break (GNUNET_NO == th_is_payload (th)
490                   || GNUNET_NO == h->in_receive);
491     GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th);
492
493     /* clean up request */
494     if (NULL != th->timeout_task)
495       GNUNET_SCHEDULER_cancel (th->timeout_task);
496     GNUNET_free (th);
497   }
498
499   /* if there are no more pending requests with cadet service, cancel active request */
500   /* Note: this should be unnecessary... */
501   if ((0 == message_ready_size (h)) && (NULL != h->th))
502   {
503     GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
504     h->th = NULL;
505   }
506
507   if (0 != ch->peer)
508     GNUNET_PEER_change_rc (ch->peer, -1);
509   GNUNET_free (ch);
510   return;
511 }
512
513
514 /**
515  * Notify client that the transmission has timed out
516  *
517  * @param cls closure
518  */
519 static void
520 timeout_transmission (void *cls)
521 {
522   struct GNUNET_CADET_TransmitHandle *th = cls;
523   struct GNUNET_CADET_Handle *cadet = th->channel->cadet;
524
525   th->timeout_task = NULL;
526   th->channel->packet_size = 0;
527   GNUNET_CONTAINER_DLL_remove (cadet->th_head, cadet->th_tail, th);
528   if (GNUNET_YES == th_is_payload (th))
529     GNUNET_break (0 == th->notify (th->notify_cls, 0, NULL));
530   GNUNET_free (th);
531   if ((0 == message_ready_size (cadet)) && (NULL != cadet->th))
532   {
533     /* nothing ready to transmit, no point in asking for transmission */
534     GNUNET_CLIENT_notify_transmit_ready_cancel (cadet->th);
535     cadet->th = NULL;
536   }
537 }
538
539
540 /**
541  * Add a transmit handle to the transmission queue and set the
542  * timeout if needed.
543  *
544  * @param h cadet handle with the queue head and tail
545  * @param th handle to the packet to be transmitted
546  */
547 static void
548 add_to_queue (struct GNUNET_CADET_Handle *h,
549               struct GNUNET_CADET_TransmitHandle *th)
550 {
551   GNUNET_CONTAINER_DLL_insert_tail (h->th_head, h->th_tail, th);
552   if (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us == th->timeout.abs_value_us)
553     return;
554   th->timeout_task =
555       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining
556                                     (th->timeout), &timeout_transmission, th);
557 }
558
559
560 /**
561  * Auxiliary function to send an already constructed packet to the service.
562  * Takes care of creating a new queue element, copying the message and
563  * calling the tmt_rdy function if necessary.
564  *
565  * @param h cadet handle
566  * @param msg message to transmit
567  * @param channel channel this send is related to (NULL if N/A)
568  */
569 static void
570 send_packet (struct GNUNET_CADET_Handle *h,
571              const struct GNUNET_MessageHeader *msg,
572              struct GNUNET_CADET_Channel *channel);
573
574
575 /**
576  * Send an ack on the channel to confirm the processing of a message.
577  *
578  * @param ch Channel on which to send the ACK.
579  */
580 static void
581 send_ack (struct GNUNET_CADET_Channel *ch)
582 {
583   struct GNUNET_CADET_LocalAck msg;
584
585   LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending ACK on channel %X\n", ch->chid);
586   msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
587   msg.header.size = htons (sizeof (msg));
588   msg.channel_id = htonl (ch->chid);
589
590   send_packet (ch->cadet, &msg.header, ch);
591   return;
592 }
593
594
595
596 /**
597  * Reconnect callback: tries to reconnect again after a failer previous
598  * reconnection.
599  *
600  * @param cls closure (cadet handle)
601  */
602 static void
603 reconnect_cbk (void *cls);
604
605
606 /**
607  * Send a connect packet to the service with the applications and types
608  * requested by the user.
609  *
610  * @param h The cadet handle.
611  *
612  */
613 static void
614 send_connect (struct GNUNET_CADET_Handle *h)
615 {
616   size_t size;
617
618   size = sizeof (struct GNUNET_CADET_ClientConnect);
619   size += h->n_ports * sizeof (uint32_t);
620   {
621     char buf[size] GNUNET_ALIGN;
622     struct GNUNET_CADET_ClientConnect *msg;
623     uint32_t *ports;
624     uint16_t i;
625
626     /* build connection packet */
627     msg = (struct GNUNET_CADET_ClientConnect *) buf;
628     msg->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_CONNECT);
629     msg->header.size = htons (size);
630     ports = (uint32_t *) &msg[1];
631     for (i = 0; i < h->n_ports; i++)
632     {
633       ports[i] = htonl (h->ports[i]);
634       LOG (GNUNET_ERROR_TYPE_DEBUG, " port %u\n",
635            h->ports[i]);
636     }
637     LOG (GNUNET_ERROR_TYPE_DEBUG,
638          "Sending %lu bytes long message with %u ports\n",
639          ntohs (msg->header.size), h->n_ports);
640     send_packet (h, &msg->header, NULL);
641   }
642 }
643
644
645 /**
646  * Reconnect to the service, retransmit all infomation to try to restore the
647  * original state.
648  *
649  * @param h handle to the cadet
650  *
651  * @return GNUNET_YES in case of sucess, GNUNET_NO otherwise (service down...)
652  */
653 static int
654 do_reconnect (struct GNUNET_CADET_Handle *h)
655 {
656   LOG (GNUNET_ERROR_TYPE_DEBUG, "*****************************\n");
657   LOG (GNUNET_ERROR_TYPE_DEBUG, "*******   RECONNECT   *******\n");
658   LOG (GNUNET_ERROR_TYPE_DEBUG, "*****************************\n");
659   LOG (GNUNET_ERROR_TYPE_DEBUG, "******** on %p *******\n", h);
660   LOG (GNUNET_ERROR_TYPE_DEBUG, "*****************************\n");
661
662   /* disconnect */
663   if (NULL != h->th)
664   {
665     GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
666     h->th = NULL;
667   }
668   if (NULL != h->client)
669   {
670     GNUNET_CLIENT_disconnect (h->client);
671   }
672
673   /* connect again */
674   h->client = GNUNET_CLIENT_connect ("cadet", h->cfg);
675   if (h->client == NULL)
676   {
677     h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
678                                                       &reconnect_cbk, h);
679     h->reconnect_time =
680         GNUNET_TIME_relative_min (GNUNET_TIME_UNIT_SECONDS,
681                                   GNUNET_TIME_relative_multiply
682                                   (h->reconnect_time, 2));
683     LOG (GNUNET_ERROR_TYPE_DEBUG, "Next retry in %s\n",
684          GNUNET_STRINGS_relative_time_to_string (h->reconnect_time,
685                                                  GNUNET_NO));
686     GNUNET_break (0);
687     return GNUNET_NO;
688   }
689   else
690   {
691     h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
692   }
693   send_connect (h);
694   return GNUNET_YES;
695 }
696
697 /**
698  * Reconnect callback: tries to reconnect again after a failer previous
699  * reconnecttion
700  *
701  * @param cls closure (cadet handle)
702  */
703 static void
704 reconnect_cbk (void *cls)
705 {
706   struct GNUNET_CADET_Handle *h = cls;
707
708   h->reconnect_task = NULL;
709   do_reconnect (h);
710 }
711
712
713 /**
714  * Reconnect to the service, retransmit all infomation to try to restore the
715  * original state.
716  *
717  * @param h handle to the cadet
718  *
719  * @return #GNUNET_YES in case of sucess, #GNUNET_NO otherwise (service down...)
720  */
721 static void
722 reconnect (struct GNUNET_CADET_Handle *h)
723 {
724   struct GNUNET_CADET_Channel *ch;
725
726   LOG (GNUNET_ERROR_TYPE_DEBUG,
727        "Requested RECONNECT, destroying all channels\n");
728   h->in_receive = GNUNET_NO;
729   for (ch = h->channels_head; NULL != ch; ch = h->channels_head)
730     destroy_channel (ch, GNUNET_YES);
731   if (NULL == h->reconnect_task)
732     h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
733                                                       &reconnect_cbk, h);
734 }
735
736
737 /******************************************************************************/
738 /***********************      RECEIVE HANDLERS     ****************************/
739 /******************************************************************************/
740
741 /**
742  * Process the new channel notification and add it to the channels in the handle
743  *
744  * @param h     The cadet handle
745  * @param msg   A message with the details of the new incoming channel
746  */
747 static void
748 process_channel_created (struct GNUNET_CADET_Handle *h,
749                          const struct GNUNET_CADET_ChannelMessage *msg)
750 {
751   struct GNUNET_CADET_Channel *ch;
752   CADET_ChannelNumber chid;
753   uint32_t port;
754
755   chid = ntohl (msg->channel_id);
756   port = ntohl (msg->port);
757   LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating incoming channel %X:%u\n", chid, port);
758   if (chid < GNUNET_CADET_LOCAL_CHANNEL_ID_SERV)
759   {
760     GNUNET_break (0);
761     return;
762   }
763   if (NULL != h->new_channel)
764   {
765     void *ctx;
766
767     ch = create_channel (h, chid);
768     ch->allow_send = GNUNET_NO;
769     ch->peer = GNUNET_PEER_intern (&msg->peer);
770     ch->cadet = h;
771     ch->chid = chid;
772     ch->port = port;
773     ch->options = ntohl (msg->opt);
774
775     LOG (GNUNET_ERROR_TYPE_DEBUG, "  created channel %p\n", ch);
776     ctx = h->new_channel (h->cls, ch, &msg->peer, ch->port, ch->options);
777     if (NULL != ctx)
778       ch->ctx = ctx;
779     LOG (GNUNET_ERROR_TYPE_DEBUG, "User notified\n");
780   }
781   else
782   {
783     struct GNUNET_CADET_ChannelMessage d_msg;
784
785     LOG (GNUNET_ERROR_TYPE_DEBUG, "No handler for incoming channels\n");
786
787     d_msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY);
788     d_msg.header.size = htons (sizeof (struct GNUNET_CADET_ChannelMessage));
789     d_msg.channel_id = msg->channel_id;
790     memset (&d_msg.peer, 0, sizeof (struct GNUNET_PeerIdentity));
791     d_msg.port = 0;
792     d_msg.opt = 0;
793
794     send_packet (h, &d_msg.header, NULL);
795   }
796   return;
797 }
798
799
800 /**
801  * Process the channel destroy notification and free associated resources
802  *
803  * @param h     The cadet handle
804  * @param msg   A message with the details of the channel being destroyed
805  */
806 static void
807 process_channel_destroy (struct GNUNET_CADET_Handle *h,
808                          const struct GNUNET_CADET_ChannelMessage *msg)
809 {
810   struct GNUNET_CADET_Channel *ch;
811   CADET_ChannelNumber chid;
812
813   chid = ntohl (msg->channel_id);
814   LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %X Destroy from service\n", chid);
815   ch = retrieve_channel (h, chid);
816
817   if (NULL == ch)
818   {
819     LOG (GNUNET_ERROR_TYPE_DEBUG, "channel %X unknown\n", chid);
820     return;
821   }
822   destroy_channel (ch, GNUNET_YES);
823 }
824
825
826 /**
827  * Process the incoming data packets, call appropriate handlers.
828  *
829  * @param h         The cadet handle
830  * @param message   A message encapsulating the data
831  */
832 static void
833 process_incoming_data (struct GNUNET_CADET_Handle *h,
834                        const struct GNUNET_MessageHeader *message)
835 {
836   const struct GNUNET_MessageHeader *payload;
837   const struct GNUNET_CADET_MessageHandler *handler;
838   struct GNUNET_CADET_LocalData *dmsg;
839   struct GNUNET_CADET_Channel *ch;
840   size_t size;
841   unsigned int i;
842   uint16_t type;
843
844   LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a data message!\n");
845   dmsg = (struct GNUNET_CADET_LocalData *) message;
846   ch = retrieve_channel (h, ntohl (dmsg->id));
847   if (NULL == ch)
848   {
849     GNUNET_break (0);
850     return;
851   }
852
853   payload = (struct GNUNET_MessageHeader *) &dmsg[1];
854   LOG (GNUNET_ERROR_TYPE_DEBUG, "  %s data on channel %s [%X]\n",
855        GC_f2s (ch->chid >= GNUNET_CADET_LOCAL_CHANNEL_ID_SERV),
856        GNUNET_i2s (GNUNET_PEER_resolve2 (ch->peer)), ntohl (dmsg->id));
857
858   size = ntohs (message->size);
859   LOG (GNUNET_ERROR_TYPE_DEBUG, "  %u bytes\n", size);
860
861   type = ntohs (payload->type);
862   size = ntohs (payload->size);
863   LOG (GNUNET_ERROR_TYPE_DEBUG, "  payload type %s\n", GC_m2s (type));
864   for (i = 0; i < h->n_handlers; i++)
865   {
866     handler = &h->message_handlers[i];
867     LOG (GNUNET_ERROR_TYPE_DEBUG, "    checking handler for type %u\n",
868          handler->type);
869     if (handler->type == type)
870     {
871       if (GNUNET_OK !=
872           handler->callback (h->cls, ch, &ch->ctx, payload))
873       {
874         LOG (GNUNET_ERROR_TYPE_DEBUG, "callback caused disconnection\n");
875         GNUNET_CADET_channel_destroy (ch);
876         return;
877       }
878       else
879       {
880         LOG (GNUNET_ERROR_TYPE_DEBUG,
881              "callback completed successfully\n");
882         return;
883       }
884     }
885   }
886 }
887
888
889 /**
890  * Process a local ACK message, enabling the client to send
891  * more data to the service.
892  *
893  * @param h Cadet handle.
894  * @param message Message itself.
895  */
896 static void
897 process_ack (struct GNUNET_CADET_Handle *h,
898              const struct GNUNET_MessageHeader *message)
899 {
900   struct GNUNET_CADET_LocalAck *msg;
901   struct GNUNET_CADET_Channel *ch;
902   CADET_ChannelNumber chid;
903
904   LOG (GNUNET_ERROR_TYPE_DEBUG, "Got an ACK!\n");
905   msg = (struct GNUNET_CADET_LocalAck *) message;
906   chid = ntohl (msg->channel_id);
907   ch = retrieve_channel (h, chid);
908   if (NULL == ch)
909   {
910     LOG (GNUNET_ERROR_TYPE_DEBUG, "ACK on unknown channel %X\n", chid);
911     return;
912   }
913   LOG (GNUNET_ERROR_TYPE_DEBUG, "  on channel %X!\n", ch->chid);
914   ch->allow_send = GNUNET_YES;
915   if (NULL == h->th && 0 < ch->packet_size)
916   {
917     LOG (GNUNET_ERROR_TYPE_DEBUG, "  tmt rdy was NULL, requesting!\n");
918     h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, ch->packet_size,
919                                                  GNUNET_TIME_UNIT_FOREVER_REL,
920                                                  GNUNET_YES, &send_callback, h);
921   }
922 }
923
924
925 /*
926  * Process a local reply about info on all channels, pass info to the user.
927  *
928  * @param h Cadet handle.
929  * @param message Message itself.
930  */
931 // static void
932 // process_get_channels (struct GNUNET_CADET_Handle *h,
933 //                      const struct GNUNET_MessageHeader *message)
934 // {
935 //   struct GNUNET_CADET_LocalInfo *msg;
936 //
937 //   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Get Channels messasge received\n");
938 //
939 //   if (NULL == h->channels_cb)
940 //   {
941 //     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "  ignored\n");
942 //     return;
943 //   }
944 //
945 //   msg = (struct GNUNET_CADET_LocalInfo *) message;
946 //   if (ntohs (message->size) !=
947 //       (sizeof (struct GNUNET_CADET_LocalInfo) +
948 //        sizeof (struct GNUNET_PeerIdentity)))
949 //   {
950 //     GNUNET_break_op (0);
951 //     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
952 //                 "Get channels message: size %hu - expected %u\n",
953 //                 ntohs (message->size),
954 //                 sizeof (struct GNUNET_CADET_LocalInfo));
955 //     return;
956 //   }
957 //   h->channels_cb (h->channels_cls,
958 //                   ntohl (msg->channel_id),
959 //                   &msg->owner,
960 //                   &msg->destination);
961 // }
962
963
964
965 /*
966  * Process a local monitor_channel reply, pass info to the user.
967  *
968  * @param h Cadet handle.
969  * @param message Message itself.
970  */
971 // static void
972 // process_show_channel (struct GNUNET_CADET_Handle *h,
973 //                      const struct GNUNET_MessageHeader *message)
974 // {
975 //   struct GNUNET_CADET_LocalInfo *msg;
976 //   size_t esize;
977 //
978 //   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Show Channel messasge received\n");
979 //
980 //   if (NULL == h->channel_cb)
981 //   {
982 //     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "  ignored\n");
983 //     return;
984 //   }
985 //
986 //   /* Verify message sanity */
987 //   msg = (struct GNUNET_CADET_LocalInfo *) message;
988 //   esize = sizeof (struct GNUNET_CADET_LocalInfo);
989 //   if (ntohs (message->size) != esize)
990 //   {
991 //     GNUNET_break_op (0);
992 //     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
993 //                 "Show channel message: size %hu - expected %u\n",
994 //                 ntohs (message->size),
995 //                 esize);
996 //
997 //     h->channel_cb (h->channel_cls, NULL, NULL);
998 //     h->channel_cb = NULL;
999 //     h->channel_cls = NULL;
1000 //
1001 //     return;
1002 //   }
1003 //
1004 //   h->channel_cb (h->channel_cls,
1005 //                  &msg->destination,
1006 //                  &msg->owner);
1007 // }
1008
1009
1010
1011 /**
1012  * Process a local reply about info on all tunnels, pass info to the user.
1013  *
1014  * @param h Cadet handle.
1015  * @param message Message itself.
1016  */
1017 static void
1018 process_get_peers (struct GNUNET_CADET_Handle *h,
1019                      const struct GNUNET_MessageHeader *message)
1020 {
1021   struct GNUNET_CADET_LocalInfoPeer *msg;
1022   uint16_t size;
1023
1024   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Get Peer messasge received\n");
1025
1026   if (NULL == h->info_cb.peers_cb)
1027   {
1028     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ignored\n");
1029     return;
1030   }
1031
1032   size = ntohs (message->size);
1033   if (sizeof (struct GNUNET_CADET_LocalInfoPeer) > size)
1034   {
1035     h->info_cb.peers_cb (h->info_cls, NULL, -1, 0, 0);
1036     h->info_cb.peers_cb = NULL;
1037     h->info_cls = NULL;
1038     return;
1039   }
1040
1041   msg = (struct GNUNET_CADET_LocalInfoPeer *) message;
1042   h->info_cb.peers_cb (h->info_cls, &msg->destination,
1043                        (int) ntohs (msg->tunnel),
1044                        (unsigned int ) ntohs (msg->paths),
1045                        0);
1046 }
1047
1048
1049 /**
1050  * Process a local peer info reply, pass info to the user.
1051  *
1052  * @param h Cadet handle.
1053  * @param message Message itself.
1054  */
1055 static void
1056 process_get_peer (struct GNUNET_CADET_Handle *h,
1057                   const struct GNUNET_MessageHeader *message)
1058 {
1059   struct GNUNET_CADET_LocalInfoPeer *msg;
1060   struct GNUNET_PeerIdentity *id;
1061   unsigned int epaths;
1062   unsigned int paths;
1063   unsigned int path_length;
1064   unsigned int i;
1065   int neighbor;
1066   size_t esize;
1067   size_t msize;
1068
1069   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Info Peer messasge received\n");
1070   if (NULL == h->info_cb.peer_cb)
1071   {
1072     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ignored\n");
1073     return;
1074   }
1075
1076   /* Verify message sanity */
1077   msg = (struct GNUNET_CADET_LocalInfoPeer *) message;
1078   esize = ntohs (message->size);
1079   msize = sizeof (struct GNUNET_CADET_LocalInfoPeer);
1080   if (esize < msize)
1081   {
1082     GNUNET_break_op (0);
1083     h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL);
1084     goto clean_cls;
1085   }
1086   epaths = (unsigned int) ntohs (msg->paths);
1087   paths = 0;
1088   path_length = 0;
1089   neighbor = GNUNET_NO;
1090   id = (struct GNUNET_PeerIdentity *) &msg[1];
1091   for (i = 0; msize < esize; i++)
1092   {
1093     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", GNUNET_i2s (&id[i]));
1094     msize += sizeof (struct GNUNET_PeerIdentity);
1095     path_length++;
1096     if (0 == memcmp (&id[i], &msg->destination,
1097                      sizeof (struct GNUNET_PeerIdentity)))
1098     {
1099       if (1 == path_length)
1100         neighbor = GNUNET_YES;
1101       path_length = 0;
1102       paths++;
1103     }
1104   }
1105   if (msize != esize)
1106   {
1107     GNUNET_break_op (0);
1108     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1109                 "m:%u, e: %u\n",
1110                 (unsigned int) msize,
1111                 (unsigned int) esize);
1112     h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL);
1113     goto clean_cls;
1114   }
1115   if (paths != epaths)
1116   {
1117     GNUNET_break_op (0);
1118     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "p:%u, e: %u\n", paths, epaths);
1119     h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL);
1120     goto clean_cls;
1121   }
1122
1123   /* Call Callback with tunnel info. */
1124   id = (struct GNUNET_PeerIdentity *) &msg[1];
1125   h->info_cb.peer_cb (h->info_cls,
1126                       &msg->destination,
1127                       (int) ntohs (msg->tunnel),
1128                       neighbor,
1129                       paths,
1130                       id);
1131
1132   clean_cls:
1133   h->info_cb.peer_cb = NULL;
1134   h->info_cls = NULL;
1135 }
1136
1137
1138 /**
1139  * Process a local reply about info on all tunnels, pass info to the user.
1140  *
1141  * @param h Cadet handle.
1142  * @param message Message itself.
1143  */
1144 static void
1145 process_get_tunnels (struct GNUNET_CADET_Handle *h,
1146                      const struct GNUNET_MessageHeader *message)
1147 {
1148   struct GNUNET_CADET_LocalInfoTunnel *msg;
1149   uint16_t size;
1150
1151   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Get Tunnels messasge received\n");
1152
1153   if (NULL == h->info_cb.tunnels_cb)
1154   {
1155     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ignored\n");
1156     return;
1157   }
1158
1159   size = ntohs (message->size);
1160   if (sizeof (struct GNUNET_CADET_LocalInfoTunnel) > size)
1161   {
1162     h->info_cb.tunnels_cb (h->info_cls, NULL, 0, 0, 0, 0);
1163     h->info_cb.tunnels_cb = NULL;
1164     h->info_cls = NULL;
1165     return;
1166   }
1167
1168   msg = (struct GNUNET_CADET_LocalInfoTunnel *) message;
1169   h->info_cb.tunnels_cb (h->info_cls, &msg->destination,
1170                          ntohl (msg->channels), ntohl (msg->connections),
1171                          ntohs (msg->estate), ntohs (msg->cstate));
1172
1173 }
1174
1175
1176 /**
1177  * Process a local tunnel info reply, pass info to the user.
1178  *
1179  * @param h Cadet handle.
1180  * @param message Message itself.
1181  */
1182 static void
1183 process_get_tunnel (struct GNUNET_CADET_Handle *h,
1184                     const struct GNUNET_MessageHeader *message)
1185 {
1186   struct GNUNET_CADET_LocalInfoTunnel *msg;
1187   size_t esize;
1188   size_t msize;
1189   unsigned int ch_n;
1190   unsigned int c_n;
1191   struct GNUNET_CADET_Hash *conns;
1192   CADET_ChannelNumber *chns;
1193
1194   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Get Tunnel messasge received\n");
1195   if (NULL == h->info_cb.tunnel_cb)
1196   {
1197     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ignored\n");
1198     return;
1199   }
1200
1201   /* Verify message sanity */
1202   msg = (struct GNUNET_CADET_LocalInfoTunnel *) message;
1203   msize = ntohs (message->size);
1204   esize = sizeof (struct GNUNET_CADET_LocalInfoTunnel);
1205   if (esize > msize)
1206   {
1207     GNUNET_break_op (0);
1208     h->info_cb.tunnel_cb (h->info_cls, NULL, 0, 0, NULL, NULL, 0, 0);
1209     goto clean_cls;
1210   }
1211   ch_n = ntohl (msg->channels);
1212   c_n = ntohl (msg->connections);
1213   esize += ch_n * sizeof (CADET_ChannelNumber);
1214   esize += c_n * sizeof (struct GNUNET_CADET_Hash);
1215   if (msize != esize)
1216   {
1217     GNUNET_break_op (0);
1218     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1219                 "m:%u, e: %u (%u ch, %u conn)\n",
1220                 (unsigned int) msize,
1221                 (unsigned int) esize,
1222                 ch_n,
1223                 c_n);
1224     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1225                 "%u (%u ch, %u conn)\n",
1226                 (unsigned int) sizeof (struct GNUNET_CADET_LocalInfoTunnel),
1227                 (unsigned int) sizeof (CADET_ChannelNumber),
1228                 (unsigned int) sizeof (struct GNUNET_HashCode));
1229     h->info_cb.tunnel_cb (h->info_cls, NULL, 0, 0, NULL, NULL, 0, 0);
1230     goto clean_cls;
1231   }
1232
1233   /* Call Callback with tunnel info. */
1234   conns = (struct GNUNET_CADET_Hash *) &msg[1];
1235   chns = (CADET_ChannelNumber *) &conns[c_n];
1236   h->info_cb.tunnel_cb (h->info_cls, &msg->destination,
1237                 ch_n, c_n, chns, conns,
1238                 ntohs (msg->estate), ntohs (msg->cstate));
1239
1240 clean_cls:
1241   h->info_cb.tunnel_cb = NULL;
1242   h->info_cls = NULL;
1243 }
1244
1245
1246 /**
1247  * Function to process all messages received from the service
1248  *
1249  * @param cls closure
1250  * @param msg message received, NULL on timeout or fatal error
1251  */
1252 static void
1253 msg_received (void *cls, const struct GNUNET_MessageHeader *msg)
1254 {
1255   struct GNUNET_CADET_Handle *h = cls;
1256   uint16_t type;
1257
1258   if (msg == NULL)
1259   {
1260     LOG (GNUNET_ERROR_TYPE_DEBUG,
1261          "Cadet service disconnected, reconnecting\n", h);
1262     reconnect (h);
1263     return;
1264   }
1265   type = ntohs (msg->type);
1266   LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
1267   LOG (GNUNET_ERROR_TYPE_DEBUG, "Received a message: %s\n",
1268        GC_m2s (type));
1269   switch (type)
1270   {
1271     /* Notify of a new incoming channel */
1272   case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE:
1273     process_channel_created (h, (struct GNUNET_CADET_ChannelMessage *) msg);
1274     break;
1275     /* Notify of a channel disconnection */
1276   case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY: /* TODO separate(gid problem)*/
1277   case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_NACK:
1278     process_channel_destroy (h, (struct GNUNET_CADET_ChannelMessage *) msg);
1279     break;
1280   case GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA:
1281     process_incoming_data (h, msg);
1282     break;
1283   case GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK:
1284     process_ack (h, msg);
1285     break;
1286 //   case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNELS:
1287 //     process_get_channels (h, msg);
1288 //     break;
1289 //   case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL:
1290 //     process_show_channel (h, msg);
1291 //     break;
1292   case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS:
1293     process_get_peers (h, msg);
1294     break;
1295   case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER:
1296     process_get_peer (h, msg);
1297     break;
1298   case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS:
1299     process_get_tunnels (h, msg);
1300     break;
1301   case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL:
1302     process_get_tunnel (h, msg);
1303     break;
1304 //   case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL:
1305 //     process_show_channel (h, msg);
1306 //     break;
1307   default:
1308     /* We shouldn't get any other packages, log and ignore */
1309     LOG (GNUNET_ERROR_TYPE_WARNING,
1310          "unsolicited message form service (type %s)\n",
1311          GC_m2s (ntohs (msg->type)));
1312   }
1313   LOG (GNUNET_ERROR_TYPE_DEBUG, "message processed\n");
1314   if (GNUNET_YES == h->in_receive)
1315   {
1316     GNUNET_CLIENT_receive (h->client, &msg_received, h,
1317                            GNUNET_TIME_UNIT_FOREVER_REL);
1318   }
1319   else
1320   {
1321     LOG (GNUNET_ERROR_TYPE_DEBUG,
1322          "in receive off, not calling CLIENT_receive\n");
1323   }
1324 }
1325
1326
1327 /******************************************************************************/
1328 /************************       SEND FUNCTIONS     ****************************/
1329 /******************************************************************************/
1330
1331 /**
1332  * Function called to send a message to the service.
1333  * "buf" will be NULL and "size" zero if the socket was closed for writing in
1334  * the meantime.
1335  *
1336  * @param cls closure, the cadet handle
1337  * @param size number of bytes available in buf
1338  * @param buf where the callee should write the connect message
1339  * @return number of bytes written to buf
1340  */
1341 static size_t
1342 send_callback (void *cls, size_t size, void *buf)
1343 {
1344   struct GNUNET_CADET_Handle *h = cls;
1345   struct GNUNET_CADET_TransmitHandle *th;
1346   struct GNUNET_CADET_TransmitHandle *next;
1347   struct GNUNET_CADET_Channel *ch;
1348   char *cbuf = buf;
1349   size_t tsize;
1350   size_t psize;
1351   size_t nsize;
1352
1353   LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
1354   LOG (GNUNET_ERROR_TYPE_DEBUG, "# Send callback, buffer %u\n", size);
1355   if ((0 == size) || (NULL == buf))
1356   {
1357     LOG (GNUNET_ERROR_TYPE_DEBUG, "# Received NULL send callback on %p\n", h);
1358     reconnect (h);
1359     h->th = NULL;
1360     return 0;
1361   }
1362   tsize = 0;
1363   next = h->th_head;
1364   nsize = message_ready_size (h);
1365   while ((NULL != (th = next)) && (0 < nsize) && (size >= nsize))
1366   {
1367     ch = th->channel;
1368     if (GNUNET_YES == th_is_payload (th))
1369     {
1370       struct GNUNET_CADET_LocalData *dmsg;
1371       struct GNUNET_MessageHeader *mh;
1372
1373       LOG (GNUNET_ERROR_TYPE_DEBUG, "#  payload, %u bytes on %X (%p)\n",
1374            th->size, ch->chid, ch);
1375       if (GNUNET_NO == ch->allow_send)
1376       {
1377         /* This channel is not ready to transmit yet, Try the next message */
1378         next = th->next;
1379         continue;
1380       }
1381       ch->packet_size = 0;
1382       GNUNET_assert (size >= th->size);
1383       dmsg = (struct GNUNET_CADET_LocalData *) cbuf;
1384       mh = (struct GNUNET_MessageHeader *) &dmsg[1];
1385       psize = th->notify (th->notify_cls, size - DATA_OVERHEAD, mh);
1386
1387       if (psize > 0)
1388       {
1389         GNUNET_assert (sizeof (struct GNUNET_MessageHeader) <= psize);
1390         psize += DATA_OVERHEAD;
1391         GNUNET_assert (size >= psize);
1392         dmsg->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
1393         dmsg->header.size = htons (psize);
1394         dmsg->id = htonl (ch->chid);
1395         LOG (GNUNET_ERROR_TYPE_DEBUG, "#  sending, type %s\n",
1396              GC_m2s (ntohs (mh->type)));
1397         ch->allow_send = GNUNET_NO;
1398       }
1399       else
1400       {
1401         LOG (GNUNET_ERROR_TYPE_DEBUG,
1402              "#  callback returned size 0, "
1403              "application canceled transmission\n");
1404       }
1405     }
1406     else
1407     {
1408       const struct GNUNET_MessageHeader *mh;
1409
1410       mh = (const struct GNUNET_MessageHeader *) &th[1];
1411       LOG (GNUNET_ERROR_TYPE_DEBUG, "#  cadet internal traffic, type %s\n",
1412            GC_m2s (ntohs (mh->type)));
1413       memcpy (cbuf, &th[1], th->size);
1414       psize = th->size;
1415     }
1416     GNUNET_assert (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE >= psize);
1417     if (th->timeout_task != NULL)
1418       GNUNET_SCHEDULER_cancel (th->timeout_task);
1419     next = th->next;
1420     GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th);
1421     GNUNET_free (th);
1422     nsize = message_ready_size (h);
1423     cbuf += psize;
1424     size -= psize;
1425     tsize += psize;
1426   }
1427   LOG (GNUNET_ERROR_TYPE_DEBUG, "#  total size: %u\n", tsize);
1428   h->th = NULL;
1429   size = message_ready_size (h);
1430   if (0 != size)
1431   {
1432     LOG (GNUNET_ERROR_TYPE_DEBUG, "#  next size: %u\n", size);
1433     h->th =
1434         GNUNET_CLIENT_notify_transmit_ready (h->client, size,
1435                                              GNUNET_TIME_UNIT_FOREVER_REL,
1436                                              GNUNET_YES, &send_callback, h);
1437   }
1438   else
1439   {
1440     if (NULL != h->th_head)
1441       LOG (GNUNET_ERROR_TYPE_DEBUG, "#  nothing ready to transmit\n");
1442     else
1443       LOG (GNUNET_ERROR_TYPE_DEBUG, "#  nothing left to transmit\n");
1444   }
1445   if (GNUNET_NO == h->in_receive)
1446   {
1447     LOG (GNUNET_ERROR_TYPE_DEBUG, "# start receiving from service\n");
1448     h->in_receive = GNUNET_YES;
1449     GNUNET_CLIENT_receive (h->client, &msg_received, h,
1450                            GNUNET_TIME_UNIT_FOREVER_REL);
1451   }
1452   LOG (GNUNET_ERROR_TYPE_DEBUG, "# Send callback() END\n");
1453   return tsize;
1454 }
1455
1456
1457 /**
1458  * Auxiliary function to send an already constructed packet to the service.
1459  * Takes care of creating a new queue element, copying the message and
1460  * calling the tmt_rdy function if necessary.
1461  *
1462  * @param h cadet handle
1463  * @param msg message to transmit
1464  * @param channel channel this send is related to (NULL if N/A)
1465  */
1466 static void
1467 send_packet (struct GNUNET_CADET_Handle *h,
1468              const struct GNUNET_MessageHeader *msg,
1469              struct GNUNET_CADET_Channel *channel)
1470 {
1471   struct GNUNET_CADET_TransmitHandle *th;
1472   size_t msize;
1473
1474   LOG (GNUNET_ERROR_TYPE_DEBUG, " Sending message to service: %s\n",
1475        GC_m2s(ntohs(msg->type)));
1476   msize = ntohs (msg->size);
1477   th = GNUNET_malloc (sizeof (struct GNUNET_CADET_TransmitHandle) + msize);
1478   th->timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
1479   th->size = msize;
1480   th->channel = channel;
1481   memcpy (&th[1], msg, msize);
1482   add_to_queue (h, th);
1483   if (NULL != h->th)
1484     return;
1485   LOG (GNUNET_ERROR_TYPE_DEBUG, "  calling ntfy tmt rdy for %u bytes\n", msize);
1486   h->th =
1487       GNUNET_CLIENT_notify_transmit_ready (h->client, msize,
1488                                            GNUNET_TIME_UNIT_FOREVER_REL,
1489                                            GNUNET_YES, &send_callback, h);
1490 }
1491
1492
1493 /******************************************************************************/
1494 /**********************      API CALL DEFINITIONS     *************************/
1495 /******************************************************************************/
1496
1497 struct GNUNET_CADET_Handle *
1498 GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls,
1499                      GNUNET_CADET_InboundChannelNotificationHandler new_channel,
1500                      GNUNET_CADET_ChannelEndHandler cleaner,
1501                      const struct GNUNET_CADET_MessageHandler *handlers,
1502                      const uint32_t *ports)
1503 {
1504   struct GNUNET_CADET_Handle *h;
1505
1506   LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_CADET_connect()\n");
1507   h = GNUNET_new (struct GNUNET_CADET_Handle);
1508   LOG (GNUNET_ERROR_TYPE_DEBUG, " addr %p\n", h);
1509   h->cfg = cfg;
1510   h->new_channel = new_channel;
1511   h->cleaner = cleaner;
1512   h->client = GNUNET_CLIENT_connect ("cadet", cfg);
1513   if (h->client == NULL)
1514   {
1515     GNUNET_break (0);
1516     GNUNET_free (h);
1517     return NULL;
1518   }
1519   h->cls = cls;
1520   h->message_handlers = handlers;
1521   h->ports = ports;
1522   h->next_chid = GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
1523   h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1524   h->reconnect_task = NULL;
1525
1526   if (NULL != ports && ports[0] != 0 && NULL == new_channel)
1527   {
1528     GNUNET_break (0);
1529     LOG (GNUNET_ERROR_TYPE_DEBUG,
1530          "no new channel handler given, ports parameter is useless!!\n");
1531   }
1532   if ((NULL == ports || ports[0] == 0) && NULL != new_channel)
1533   {
1534     GNUNET_break (0);
1535     LOG (GNUNET_ERROR_TYPE_DEBUG,
1536          "no ports given, new channel handler will never be called!!\n");
1537   }
1538   /* count handlers */
1539   for (h->n_handlers = 0;
1540        handlers && handlers[h->n_handlers].type;
1541        h->n_handlers++) ;
1542   for (h->n_ports = 0;
1543        ports && ports[h->n_ports];
1544        h->n_ports++) ;
1545   send_connect (h);
1546   LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_CADET_connect() END\n");
1547   return h;
1548 }
1549
1550
1551 void
1552 GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle)
1553 {
1554   struct GNUNET_CADET_Channel *ch;
1555   struct GNUNET_CADET_Channel *aux;
1556   struct GNUNET_CADET_TransmitHandle *th;
1557
1558   LOG (GNUNET_ERROR_TYPE_DEBUG, "CADET DISCONNECT\n");
1559
1560   ch = handle->channels_head;
1561   while (NULL != ch)
1562   {
1563     aux = ch->next;
1564     if (ch->chid < GNUNET_CADET_LOCAL_CHANNEL_ID_SERV)
1565     {
1566       GNUNET_break (0);
1567       LOG (GNUNET_ERROR_TYPE_DEBUG, "channel %X not destroyed\n", ch->chid);
1568     }
1569     destroy_channel (ch, GNUNET_YES);
1570     ch = aux;
1571   }
1572   while ( (th = handle->th_head) != NULL)
1573   {
1574     struct GNUNET_MessageHeader *msg;
1575
1576     /* Make sure it is an allowed packet (everything else should have been
1577      * already canceled).
1578      */
1579     GNUNET_break (GNUNET_NO == th_is_payload (th));
1580     msg = (struct GNUNET_MessageHeader *) &th[1];
1581     switch (ntohs(msg->type))
1582     {
1583       case GNUNET_MESSAGE_TYPE_CADET_LOCAL_CONNECT:
1584       case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE:
1585       case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY:
1586       case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNELS:
1587       case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL:
1588       case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER:
1589       case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS:
1590       case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL:
1591       case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS:
1592         break;
1593       default:
1594         GNUNET_break (0);
1595         LOG (GNUNET_ERROR_TYPE_ERROR, "unexpected unsent msg %s\n",
1596              GC_m2s (ntohs(msg->type)));
1597     }
1598
1599     GNUNET_CONTAINER_DLL_remove (handle->th_head, handle->th_tail, th);
1600     GNUNET_free (th);
1601   }
1602
1603   if (NULL != handle->th)
1604   {
1605     GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th);
1606     handle->th = NULL;
1607   }
1608   if (NULL != handle->client)
1609   {
1610     GNUNET_CLIENT_disconnect (handle->client);
1611     handle->client = NULL;
1612   }
1613   if (NULL != handle->reconnect_task)
1614   {
1615     GNUNET_SCHEDULER_cancel(handle->reconnect_task);
1616     handle->reconnect_task = NULL;
1617   }
1618   GNUNET_free (handle);
1619 }
1620
1621
1622 /**
1623  * Create a new channel towards a remote peer.
1624  *
1625  * If the destination port is not open by any peer or the destination peer
1626  * does not accept the channel, #GNUNET_CADET_ChannelEndHandler will be called
1627  * for this channel.
1628  *
1629  * @param h cadet handle
1630  * @param channel_ctx client's channel context to associate with the channel
1631  * @param peer peer identity the channel should go to
1632  * @param port Port number.
1633  * @param options CadetOption flag field, with all desired option bits set to 1.
1634  *
1635  * @return handle to the channel
1636  */
1637 struct GNUNET_CADET_Channel *
1638 GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle *h,
1639                             void *channel_ctx,
1640                             const struct GNUNET_PeerIdentity *peer,
1641                             uint32_t port,
1642                             enum GNUNET_CADET_ChannelOption options)
1643 {
1644   struct GNUNET_CADET_Channel *ch;
1645   struct GNUNET_CADET_ChannelMessage msg;
1646
1647   LOG (GNUNET_ERROR_TYPE_DEBUG,
1648        "Creating new channel to %s:%u\n",
1649        GNUNET_i2s (peer), port);
1650   ch = create_channel (h, 0);
1651   LOG (GNUNET_ERROR_TYPE_DEBUG, "  at %p\n", ch);
1652   LOG (GNUNET_ERROR_TYPE_DEBUG, "  number %X\n", ch->chid);
1653   ch->ctx = channel_ctx;
1654   ch->peer = GNUNET_PEER_intern (peer);
1655   msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE);
1656   msg.header.size = htons (sizeof (struct GNUNET_CADET_ChannelMessage));
1657   msg.channel_id = htonl (ch->chid);
1658   msg.port = htonl (port);
1659   msg.peer = *peer;
1660   msg.opt = htonl (options);
1661   ch->allow_send = GNUNET_NO;
1662   send_packet (h, &msg.header, ch);
1663   return ch;
1664 }
1665
1666
1667 void
1668 GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel)
1669 {
1670   struct GNUNET_CADET_Handle *h;
1671   struct GNUNET_CADET_ChannelMessage msg;
1672   struct GNUNET_CADET_TransmitHandle *th;
1673
1674   LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying channel\n");
1675   h = channel->cadet;
1676
1677   msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY);
1678   msg.header.size = htons (sizeof (struct GNUNET_CADET_ChannelMessage));
1679   msg.channel_id = htonl (channel->chid);
1680   memset (&msg.peer, 0, sizeof (struct GNUNET_PeerIdentity));
1681   msg.port = 0;
1682   msg.opt = 0;
1683   th = h->th_head;
1684   while (th != NULL)
1685   {
1686     struct GNUNET_CADET_TransmitHandle *aux;
1687     if (th->channel == channel)
1688     {
1689       aux = th->next;
1690       if (GNUNET_YES == th_is_payload (th))
1691       {
1692         /* applications should cancel before destroying channel */
1693         GNUNET_break (0);
1694         LOG (GNUNET_ERROR_TYPE_WARNING,
1695              "Channel destroyed without cancelling transmission requests\n");
1696         th->notify (th->notify_cls, 0, NULL);
1697       }
1698       GNUNET_CADET_notify_transmit_ready_cancel (th);
1699       th = aux;
1700     }
1701     else
1702       th = th->next;
1703   }
1704
1705   destroy_channel (channel, GNUNET_YES);
1706   send_packet (h, &msg.header, NULL);
1707 }
1708
1709
1710 /**
1711  * Get information about a channel.
1712  *
1713  * @param channel Channel handle.
1714  * @param option Query (GNUNET_CADET_OPTION_*).
1715  * @param ... dependant on option, currently not used
1716  *
1717  * @return Union with an answer to the query.
1718  */
1719 const union GNUNET_CADET_ChannelInfo *
1720 GNUNET_CADET_channel_get_info (struct GNUNET_CADET_Channel *channel,
1721                               enum GNUNET_CADET_ChannelOption option, ...)
1722 {
1723   static int bool_flag;
1724   const union GNUNET_CADET_ChannelInfo *ret;
1725
1726   switch (option)
1727   {
1728     case GNUNET_CADET_OPTION_NOBUFFER:
1729     case GNUNET_CADET_OPTION_RELIABLE:
1730     case GNUNET_CADET_OPTION_OOORDER:
1731       if (0 != (option & channel->options))
1732         bool_flag = GNUNET_YES;
1733       else
1734         bool_flag = GNUNET_NO;
1735       ret = (const union GNUNET_CADET_ChannelInfo *) &bool_flag;
1736       break;
1737     case GNUNET_CADET_OPTION_PEER:
1738       ret = (const union GNUNET_CADET_ChannelInfo *) GNUNET_PEER_resolve2 (channel->peer);
1739       break;
1740     default:
1741       GNUNET_break (0);
1742       return NULL;
1743   }
1744
1745   return ret;
1746 }
1747
1748 struct GNUNET_CADET_TransmitHandle *
1749 GNUNET_CADET_notify_transmit_ready (struct GNUNET_CADET_Channel *channel, int cork,
1750                                     struct GNUNET_TIME_Relative maxdelay,
1751                                     size_t notify_size,
1752                                     GNUNET_CONNECTION_TransmitReadyNotify notify,
1753                                     void *notify_cls)
1754 {
1755   struct GNUNET_CADET_TransmitHandle *th;
1756
1757   GNUNET_assert (NULL != channel);
1758   GNUNET_assert (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE >= notify_size);
1759   LOG (GNUNET_ERROR_TYPE_DEBUG, "CADET NOTIFY TRANSMIT READY\n");
1760   LOG (GNUNET_ERROR_TYPE_DEBUG, "    on channel %X\n", channel->chid);
1761   LOG (GNUNET_ERROR_TYPE_DEBUG, "    allow_send %d\n", channel->allow_send);
1762   if (channel->chid >= GNUNET_CADET_LOCAL_CHANNEL_ID_SERV)
1763     LOG (GNUNET_ERROR_TYPE_DEBUG, "    to origin\n");
1764   else
1765     LOG (GNUNET_ERROR_TYPE_DEBUG, "    to destination\n");
1766   LOG (GNUNET_ERROR_TYPE_DEBUG, "    payload size %u\n", notify_size);
1767   GNUNET_assert (NULL != notify);
1768   GNUNET_assert (0 == channel->packet_size); // Only one data packet allowed
1769   th = GNUNET_new (struct GNUNET_CADET_TransmitHandle);
1770   th->channel = channel;
1771   th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay);
1772   th->size = notify_size + DATA_OVERHEAD;
1773   channel->packet_size = th->size;
1774   LOG (GNUNET_ERROR_TYPE_DEBUG, "    total size %u\n", th->size);
1775   th->notify = notify;
1776   th->notify_cls = notify_cls;
1777   add_to_queue (channel->cadet, th);
1778   if (NULL != channel->cadet->th)
1779     return th;
1780   if (GNUNET_NO == channel->allow_send)
1781     return th;
1782   LOG (GNUNET_ERROR_TYPE_DEBUG, "    call client notify tmt rdy\n");
1783   channel->cadet->th =
1784       GNUNET_CLIENT_notify_transmit_ready (channel->cadet->client, th->size,
1785                                            GNUNET_TIME_UNIT_FOREVER_REL,
1786                                            GNUNET_YES, &send_callback,
1787                                            channel->cadet);
1788   LOG (GNUNET_ERROR_TYPE_DEBUG, "CADET NOTIFY TRANSMIT READY END\n");
1789   return th;
1790 }
1791
1792
1793 void
1794 GNUNET_CADET_notify_transmit_ready_cancel (struct GNUNET_CADET_TransmitHandle *th)
1795 {
1796   struct GNUNET_CADET_Handle *cadet;
1797
1798   LOG (GNUNET_ERROR_TYPE_DEBUG, "CADET NOTIFY TRANSMIT READY CANCEL\n");
1799   LOG (GNUNET_ERROR_TYPE_DEBUG, "    on channel %X (%p)\n",
1800        th->channel->chid, th->channel);
1801   LOG (GNUNET_ERROR_TYPE_DEBUG, "    size %u bytes\n", th->size);
1802   th->channel->packet_size = 0;
1803   cadet = th->channel->cadet;
1804   if (th->timeout_task != NULL)
1805     GNUNET_SCHEDULER_cancel (th->timeout_task);
1806   GNUNET_CONTAINER_DLL_remove (cadet->th_head, cadet->th_tail, th);
1807   GNUNET_free (th);
1808   if ((0 == message_ready_size (cadet)) && (NULL != cadet->th))
1809   {
1810     /* queue empty, no point in asking for transmission */
1811     GNUNET_CLIENT_notify_transmit_ready_cancel (cadet->th);
1812     cadet->th = NULL;
1813   }
1814   LOG (GNUNET_ERROR_TYPE_DEBUG, "CADET NOTIFY TRANSMIT READY CANCEL END\n");
1815 }
1816
1817
1818 void
1819 GNUNET_CADET_receive_done (struct GNUNET_CADET_Channel *channel)
1820 {
1821   send_ack (channel);
1822 }
1823
1824
1825 static void
1826 send_info_request (struct GNUNET_CADET_Handle *h, uint16_t type)
1827 {
1828   struct GNUNET_MessageHeader msg;
1829
1830   msg.size = htons (sizeof (msg));
1831   msg.type = htons (type);
1832   send_packet (h, &msg, NULL);
1833 }
1834
1835
1836 /**
1837  * Request a debug dump on the service's STDERR.
1838  *
1839  * WARNING: unstable API, likely to change in the future!
1840  *
1841  * @param h cadet handle
1842  */
1843 void
1844 GNUNET_CADET_request_dump (struct GNUNET_CADET_Handle *h)
1845 {
1846   LOG (GNUNET_ERROR_TYPE_DEBUG, "requesting dump\n");
1847   send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP);
1848 }
1849
1850
1851 /**
1852  * Request information about peers known to the running cadet service.
1853  * The callback will be called for every peer known to the service.
1854  * Only one info request (of any kind) can be active at once.
1855  *
1856  *
1857  * WARNING: unstable API, likely to change in the future!
1858  *
1859  * @param h Handle to the cadet peer.
1860  * @param callback Function to call with the requested data.
1861  * @param callback_cls Closure for @c callback.
1862  *
1863  * @return #GNUNET_OK / #GNUNET_SYSERR
1864  */
1865 int
1866 GNUNET_CADET_get_peers (struct GNUNET_CADET_Handle *h,
1867                        GNUNET_CADET_PeersCB callback,
1868                        void *callback_cls)
1869 {
1870   if (NULL != h->info_cb.peers_cb)
1871   {
1872     GNUNET_break (0);
1873     return GNUNET_SYSERR;
1874   }
1875   send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
1876   h->info_cb.peers_cb = callback;
1877   h->info_cls = callback_cls;
1878   return GNUNET_OK;
1879 }
1880
1881
1882 /**
1883  * Cancel a peer info request. The callback will not be called (anymore).
1884  *
1885  * WARNING: unstable API, likely to change in the future!
1886  *
1887  * @param h Cadet handle.
1888  *
1889  * @return Closure given to GNUNET_CADET_get_peers.
1890  */
1891 void *
1892 GNUNET_CADET_get_peers_cancel (struct GNUNET_CADET_Handle *h)
1893 {
1894   void *cls;
1895
1896   cls = h->info_cls;
1897   h->info_cb.peers_cb = NULL;
1898   h->info_cls = NULL;
1899   return cls;
1900 }
1901
1902
1903 /**
1904  * Request information about a peer known to the running cadet peer.
1905  * The callback will be called for the tunnel once.
1906  * Only one info request (of any kind) can be active at once.
1907  *
1908  * WARNING: unstable API, likely to change in the future!
1909  *
1910  * @param h Handle to the cadet peer.
1911  * @param id Peer whose tunnel to examine.
1912  * @param callback Function to call with the requested data.
1913  * @param callback_cls Closure for @c callback.
1914  *
1915  * @return #GNUNET_OK / #GNUNET_SYSERR
1916  */
1917 int
1918 GNUNET_CADET_get_peer (struct GNUNET_CADET_Handle *h,
1919                       const struct GNUNET_PeerIdentity *id,
1920                       GNUNET_CADET_PeerCB callback,
1921                       void *callback_cls)
1922 {
1923   struct GNUNET_CADET_LocalInfo msg;
1924
1925   if (NULL != h->info_cb.peer_cb)
1926   {
1927     GNUNET_break (0);
1928     return GNUNET_SYSERR;
1929   }
1930
1931   memset (&msg, 0, sizeof (msg));
1932   msg.header.size = htons (sizeof (msg));
1933   msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
1934   msg.peer = *id;
1935   send_packet (h, &msg.header, NULL);
1936   h->info_cb.peer_cb = callback;
1937   h->info_cls = callback_cls;
1938   return GNUNET_OK;
1939 }
1940
1941
1942 /**
1943  * Request information about tunnels of the running cadet peer.
1944  * The callback will be called for every tunnel of the service.
1945  * Only one info request (of any kind) can be active at once.
1946  *
1947  * WARNING: unstable API, likely to change in the future!
1948  *
1949  * @param h Handle to the cadet peer.
1950  * @param callback Function to call with the requested data.
1951  * @param callback_cls Closure for @c callback.
1952  *
1953  * @return #GNUNET_OK / #GNUNET_SYSERR
1954  */
1955 int
1956 GNUNET_CADET_get_tunnels (struct GNUNET_CADET_Handle *h,
1957                          GNUNET_CADET_TunnelsCB callback,
1958                          void *callback_cls)
1959 {
1960   if (NULL != h->info_cb.tunnels_cb)
1961   {
1962     GNUNET_break (0);
1963     return GNUNET_SYSERR;
1964   }
1965   send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
1966   h->info_cb.tunnels_cb = callback;
1967   h->info_cls = callback_cls;
1968   return GNUNET_OK;
1969 }
1970
1971
1972 /**
1973  * Cancel a monitor request. The monitor callback will not be called.
1974  *
1975  * @param h Cadet handle.
1976  *
1977  * @return Closure given to GNUNET_CADET_get_tunnels.
1978  */
1979 void *
1980 GNUNET_CADET_get_tunnels_cancel (struct GNUNET_CADET_Handle *h)
1981 {
1982   void *cls;
1983
1984   h->info_cb.tunnels_cb = NULL;
1985   cls = h->info_cls;
1986   h->info_cls = NULL;
1987
1988   return cls;
1989 }
1990
1991
1992
1993 /**
1994  * Request information about a tunnel of the running cadet peer.
1995  * The callback will be called for the tunnel once.
1996  * Only one info request (of any kind) can be active at once.
1997  *
1998  * WARNING: unstable API, likely to change in the future!
1999  *
2000  * @param h Handle to the cadet peer.
2001  * @param id Peer whose tunnel to examine.
2002  * @param callback Function to call with the requested data.
2003  * @param callback_cls Closure for @c callback.
2004  *
2005  * @return #GNUNET_OK / #GNUNET_SYSERR
2006  */
2007 int
2008 GNUNET_CADET_get_tunnel (struct GNUNET_CADET_Handle *h,
2009                         const struct GNUNET_PeerIdentity *id,
2010                         GNUNET_CADET_TunnelCB callback,
2011                         void *callback_cls)
2012 {
2013   struct GNUNET_CADET_LocalInfo msg;
2014
2015   if (NULL != h->info_cb.tunnel_cb)
2016   {
2017     GNUNET_break (0);
2018     return GNUNET_SYSERR;
2019   }
2020
2021   memset (&msg, 0, sizeof (msg));
2022   msg.header.size = htons (sizeof (msg));
2023   msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
2024   msg.peer = *id;
2025   send_packet (h, &msg.header, NULL);
2026   h->info_cb.tunnel_cb = callback;
2027   h->info_cls = callback_cls;
2028   return GNUNET_OK;
2029 }
2030
2031
2032 /**
2033  * Request information about a specific channel of the running cadet peer.
2034  *
2035  * WARNING: unstable API, likely to change in the future!
2036  * FIXME Add destination option.
2037  *
2038  * @param h Handle to the cadet peer.
2039  * @param initiator ID of the owner of the channel.
2040  * @param channel_number Channel number.
2041  * @param callback Function to call with the requested data.
2042  * @param callback_cls Closure for @c callback.
2043  *
2044  * @return #GNUNET_OK / #GNUNET_SYSERR
2045  */
2046 int
2047 GNUNET_CADET_show_channel (struct GNUNET_CADET_Handle *h,
2048                          struct GNUNET_PeerIdentity *initiator,
2049                          unsigned int channel_number,
2050                          GNUNET_CADET_ChannelCB callback,
2051                          void *callback_cls)
2052 {
2053   struct GNUNET_CADET_LocalInfo msg;
2054
2055   if (NULL != h->info_cb.channel_cb)
2056   {
2057     GNUNET_break (0);
2058     return GNUNET_SYSERR;
2059   }
2060
2061   msg.header.size = htons (sizeof (msg));
2062   msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL);
2063   msg.peer = *initiator;
2064   msg.channel_id = htonl (channel_number);
2065 //   msg.reserved = 0;
2066   send_packet (h, &msg.header, NULL);
2067   h->info_cb.channel_cb = callback;
2068   h->info_cls = callback_cls;
2069   return GNUNET_OK;
2070 }
2071
2072
2073 /**
2074  * Function called to notify a client about the connection
2075  * begin ready to queue more data.  "buf" will be
2076  * NULL and "size" zero if the connection was closed for
2077  * writing in the meantime.
2078  *
2079  * @param cls closure
2080  * @param size number of bytes available in buf
2081  * @param buf where the callee should write the message
2082  * @return number of bytes written to buf
2083  */
2084 static size_t
2085 cadet_mq_ntr (void *cls, size_t size,
2086              void *buf)
2087 {
2088   struct GNUNET_MQ_Handle *mq = cls;
2089   struct CadetMQState *state = GNUNET_MQ_impl_state (mq);
2090   const struct GNUNET_MessageHeader *msg = GNUNET_MQ_impl_current (mq);
2091   uint16_t msize;
2092
2093   state->th = NULL;
2094   if (NULL == buf)
2095   {
2096     GNUNET_MQ_inject_error (mq, GNUNET_MQ_ERROR_WRITE);
2097     return 0;
2098   }
2099   msize = ntohs (msg->size);
2100   GNUNET_assert (msize <= size);
2101   memcpy (buf, msg, msize);
2102   GNUNET_MQ_impl_send_continue (mq);
2103   return msize;
2104 }
2105
2106
2107 /**
2108  * Signature of functions implementing the
2109  * sending functionality of a message queue.
2110  *
2111  * @param mq the message queue
2112  * @param msg the message to send
2113  * @param impl_state state of the implementation
2114  */
2115 static void
2116 cadet_mq_send_impl (struct GNUNET_MQ_Handle *mq,
2117                     const struct GNUNET_MessageHeader *msg,
2118                     void *impl_state)
2119 {
2120   struct CadetMQState *state = impl_state;
2121
2122   GNUNET_assert (NULL == state->th);
2123   state->th =
2124       GNUNET_CADET_notify_transmit_ready (state->channel,
2125                                          /* FIXME: add option for corking */
2126                                          GNUNET_NO,
2127                                          GNUNET_TIME_UNIT_FOREVER_REL,
2128                                          ntohs (msg->size),
2129                                          &cadet_mq_ntr, mq);
2130
2131 }
2132
2133
2134 /**
2135  * Signature of functions implementing the
2136  * destruction of a message queue.
2137  * Implementations must not free 'mq', but should
2138  * take care of 'impl_state'.
2139  *
2140  * @param mq the message queue to destroy
2141  * @param impl_state state of the implementation
2142  */
2143 static void
2144 cadet_mq_destroy_impl (struct GNUNET_MQ_Handle *mq,
2145                        void *impl_state)
2146 {
2147   struct CadetMQState *state = impl_state;
2148
2149   if (NULL != state->th)
2150     GNUNET_CADET_notify_transmit_ready_cancel (state->th);
2151
2152   GNUNET_free (state);
2153 }
2154
2155
2156 /**
2157  * Create a message queue for a cadet channel.
2158  * The message queue can only be used to transmit messages,
2159  * not to receive them.
2160  *
2161  * @param channel the channel to create the message qeue for
2162  * @return a message queue to messages over the channel
2163  */
2164 struct GNUNET_MQ_Handle *
2165 GNUNET_CADET_mq_create (struct GNUNET_CADET_Channel *channel)
2166 {
2167   struct GNUNET_MQ_Handle *mq;
2168   struct CadetMQState *state;
2169
2170   state = GNUNET_new (struct CadetMQState);
2171   state->channel = channel;
2172
2173   mq = GNUNET_MQ_queue_for_callbacks (&cadet_mq_send_impl,
2174                                       &cadet_mq_destroy_impl,
2175                                       NULL, /* FIXME: cancel impl. */
2176                                       state,
2177                                       NULL, /* no msg handlers */
2178                                       NULL, /* no err handlers */
2179                                       NULL); /* no handler cls */
2180   return mq;
2181 }