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