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