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