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