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