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