- Add monitor API to MQ
[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         GNUNET_assert (NULL == th->request_data_task);
753         th->request_data_task = GNUNET_SCHEDULER_add_now (&request_data, 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  * Process a local reply about info on all channels, pass info to the user.
807  *
808  * @param h Cadet handle.
809  * @param message Message itself.
810  */
811 // static void
812 // process_get_channels (struct GNUNET_CADET_Handle *h,
813 //                      const struct GNUNET_MessageHeader *message)
814 // {
815 //   struct GNUNET_CADET_LocalInfo *msg;
816 //
817 //   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Get Channels messasge received\n");
818 //
819 //   if (NULL == h->channels_cb)
820 //   {
821 //     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "  ignored\n");
822 //     return;
823 //   }
824 //
825 //   msg = (struct GNUNET_CADET_LocalInfo *) message;
826 //   if (ntohs (message->size) !=
827 //       (sizeof (struct GNUNET_CADET_LocalInfo) +
828 //        sizeof (struct GNUNET_PeerIdentity)))
829 //   {
830 //     GNUNET_break_op (0);
831 //     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
832 //                 "Get channels message: size %hu - expected %u\n",
833 //                 ntohs (message->size),
834 //                 sizeof (struct GNUNET_CADET_LocalInfo));
835 //     return;
836 //   }
837 //   h->channels_cb (h->channels_cls,
838 //                   ntohl (msg->channel_id),
839 //                   &msg->owner,
840 //                   &msg->destination);
841 // }
842
843
844
845 /*
846  * Process a local monitor_channel reply, pass info to the user.
847  *
848  * @param h Cadet handle.
849  * @param message Message itself.
850  */
851 // static void
852 // process_show_channel (struct GNUNET_CADET_Handle *h,
853 //                      const struct GNUNET_MessageHeader *message)
854 // {
855 //   struct GNUNET_CADET_LocalInfo *msg;
856 //   size_t esize;
857 //
858 //   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Show Channel messasge received\n");
859 //
860 //   if (NULL == h->channel_cb)
861 //   {
862 //     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "  ignored\n");
863 //     return;
864 //   }
865 //
866 //   /* Verify message sanity */
867 //   msg = (struct GNUNET_CADET_LocalInfo *) message;
868 //   esize = sizeof (struct GNUNET_CADET_LocalInfo);
869 //   if (ntohs (message->size) != esize)
870 //   {
871 //     GNUNET_break_op (0);
872 //     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
873 //                 "Show channel message: size %hu - expected %u\n",
874 //                 ntohs (message->size),
875 //                 esize);
876 //
877 //     h->channel_cb (h->channel_cls, NULL, NULL);
878 //     h->channel_cb = NULL;
879 //     h->channel_cls = NULL;
880 //
881 //     return;
882 //   }
883 //
884 //   h->channel_cb (h->channel_cls,
885 //                  &msg->destination,
886 //                  &msg->owner);
887 // }
888
889
890
891 /**
892  * Check that message received from CADET service is well-formed.
893  *
894  * @param cls the `struct GNUNET_CADET_Handle`
895  * @param message the message we got
896  * @return #GNUNET_OK if the message is well-formed,
897  *         #GNUNET_SYSERR otherwise
898  */
899 static int
900 check_get_peers (void *cls,
901                  const struct GNUNET_CADET_LocalInfoPeer *message)
902 {
903   struct GNUNET_CADET_Handle *h = cls;
904   uint16_t size;
905
906   if (NULL == h->info_cb.peers_cb)
907   {
908     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
909                 "  no handler for peesr monitor message!\n");
910     return GNUNET_SYSERR;
911   }
912
913   size = ntohs (message->header.size);
914   if (sizeof (struct GNUNET_CADET_LocalInfoPeer) > size)
915   {
916     h->info_cb.peers_cb (h->info_cls, NULL, -1, 0, 0);
917     h->info_cb.peers_cb = NULL;
918     h->info_cls = NULL;
919     return GNUNET_SYSERR;
920   }
921
922   return GNUNET_OK;
923 }
924
925
926 /**
927  * Process a local reply about info on all tunnels, pass info to the user.
928  *
929  * @param cls Closure (Cadet handle).
930  * @param msg Message itself.
931  */
932 static void
933 handle_get_peers (void *cls,
934                   const struct GNUNET_CADET_LocalInfoPeer *msg)
935 {
936   struct GNUNET_CADET_Handle *h = cls;
937   h->info_cb.peers_cb (h->info_cls, &msg->destination,
938                        (int) ntohs (msg->tunnel),
939                        (unsigned int ) ntohs (msg->paths),
940                        0);
941 }
942
943
944 /**
945  * Check that message received from CADET service is well-formed.
946  *
947  * @param cls the `struct GNUNET_CADET_Handle`
948  * @param message the message we got
949  * @return #GNUNET_OK if the message is well-formed,
950  *         #GNUNET_SYSERR otherwise
951  */
952 static int
953 check_get_peer (void *cls,
954                 const struct GNUNET_CADET_LocalInfoPeer *message)
955 {
956   struct GNUNET_CADET_Handle *h = cls;
957   const size_t msize = sizeof (struct GNUNET_CADET_LocalInfoPeer);
958   struct GNUNET_PeerIdentity *paths_array;
959   size_t esize;
960   unsigned int epaths;
961   unsigned int paths;
962   unsigned int peers;
963
964   if (NULL == h->info_cb.peer_cb)
965   {
966     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
967                 "  no handler for peer monitor message!\n");
968     goto clean_cls;
969   }
970
971   /* Verify message sanity */
972   esize = ntohs (message->header.size);
973   if (esize < msize)
974   {
975     GNUNET_break_op (0);
976     h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL);
977     goto clean_cls;
978   }
979   if (0 != ((esize - msize) % sizeof (struct GNUNET_PeerIdentity)))
980   {
981     GNUNET_break_op (0);
982     h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL);
983     goto clean_cls;
984
985   }
986   peers = (esize - msize) / sizeof (struct GNUNET_PeerIdentity);
987   epaths = (unsigned int) ntohs (message->paths);
988   paths_array = (struct GNUNET_PeerIdentity *) &message[1];
989   paths = 0;
990   for (int i = 0; i < peers; i++)
991   {
992     if (0 == memcmp (&paths_array[i], &message->destination,
993                      sizeof (struct GNUNET_PeerIdentity)))
994     {
995       paths++;
996     }
997   }
998   if (paths != epaths)
999   {
1000     GNUNET_break_op (0);
1001     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "p:%u, e: %u\n", paths, epaths);
1002     h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL);
1003     goto clean_cls;
1004   }
1005
1006   return GNUNET_OK;
1007
1008 clean_cls:
1009   h->info_cb.peer_cb = NULL;
1010   h->info_cls = NULL;
1011   return GNUNET_SYSERR;
1012 }
1013
1014
1015 /**
1016  * Process a local peer info reply, pass info to the user.
1017  *
1018  * @param cls Closure (Cadet handle).
1019  * @param message Message itself.
1020  */
1021 static void
1022 handle_get_peer (void *cls,
1023                  const struct GNUNET_CADET_LocalInfoPeer *message)
1024 {
1025   struct GNUNET_CADET_Handle *h = cls;
1026   struct GNUNET_PeerIdentity *paths_array;
1027   unsigned int paths;
1028   unsigned int path_length;
1029   int neighbor;
1030   unsigned int peers;
1031
1032   paths = (unsigned int) ntohs (message->paths);
1033   paths_array = (struct GNUNET_PeerIdentity *) &message[1];
1034   peers = (ntohs (message->header.size) - sizeof (*message))
1035           / sizeof (struct GNUNET_PeerIdentity);
1036   path_length = 0;
1037   neighbor = GNUNET_NO;
1038
1039   for (int i = 0; i < peers; i++)
1040   {
1041     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", GNUNET_i2s (&paths_array[i]));
1042     path_length++;
1043     if (0 == memcmp (&paths_array[i], &message->destination,
1044                      sizeof (struct GNUNET_PeerIdentity)))
1045     {
1046       if (1 == path_length)
1047         neighbor = GNUNET_YES;
1048       path_length = 0;
1049     }
1050   }
1051
1052   /* Call Callback with tunnel info. */
1053   paths_array = (struct GNUNET_PeerIdentity *) &message[1];
1054   h->info_cb.peer_cb (h->info_cls,
1055                       &message->destination,
1056                       (int) ntohs (message->tunnel),
1057                       neighbor,
1058                       paths,
1059                       paths_array);
1060 }
1061
1062
1063 /**
1064  * Check that message received from CADET service is well-formed.
1065  *
1066  * @param cls the `struct GNUNET_CADET_Handle`
1067  * @param msg the message we got
1068  * @return #GNUNET_OK if the message is well-formed,
1069  *         #GNUNET_SYSERR otherwise
1070  */
1071 static int
1072 check_get_tunnels (void *cls,
1073                    const struct GNUNET_CADET_LocalInfoTunnel *msg)
1074 {
1075   struct GNUNET_CADET_Handle *h = cls;
1076   uint16_t size;
1077
1078   if (NULL == h->info_cb.tunnels_cb)
1079   {
1080     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1081                 "  no handler for tunnels monitor message!\n");
1082     return GNUNET_SYSERR;
1083   }
1084
1085   size = ntohs (msg->header.size);
1086   if (sizeof (struct GNUNET_CADET_LocalInfoTunnel) > size)
1087   {
1088     h->info_cb.tunnels_cb (h->info_cls, NULL, 0, 0, 0, 0);
1089     h->info_cb.tunnels_cb = NULL;
1090     h->info_cls = NULL;
1091     return GNUNET_SYSERR;
1092   }
1093   return GNUNET_OK;
1094 }
1095
1096
1097 /**
1098  * Process a local reply about info on all tunnels, pass info to the user.
1099  *
1100  * @param cls Closure (Cadet handle).
1101  * @param message Message itself.
1102  */
1103 static void
1104 handle_get_tunnels (void *cls,
1105                     const struct GNUNET_CADET_LocalInfoTunnel *msg)
1106 {
1107   struct GNUNET_CADET_Handle *h = cls;
1108
1109   h->info_cb.tunnels_cb (h->info_cls, &msg->destination,
1110                          ntohl (msg->channels), ntohl (msg->connections),
1111                          ntohs (msg->estate), ntohs (msg->cstate));
1112
1113 }
1114
1115
1116 /**
1117  * Check that message received from CADET service is well-formed.
1118  *
1119  * @param cls the `struct GNUNET_CADET_Handle`
1120  * @param msg the message we got
1121  * @return #GNUNET_OK if the message is well-formed,
1122  *         #GNUNET_SYSERR otherwise
1123  */
1124 static int
1125 check_get_tunnel (void *cls,
1126                   const struct GNUNET_CADET_LocalInfoTunnel *msg)
1127 {
1128   struct GNUNET_CADET_Handle *h = cls;
1129   unsigned int ch_n;
1130   unsigned int c_n;
1131   size_t esize;
1132   size_t msize;
1133
1134   if (NULL == h->info_cb.tunnel_cb)
1135   {
1136     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1137                 "  no handler for tunnel monitor message!\n");
1138     goto clean_cls;
1139   }
1140
1141   /* Verify message sanity */
1142   msize = ntohs (msg->header.size);
1143   esize = sizeof (struct GNUNET_CADET_LocalInfoTunnel);
1144   if (esize > msize)
1145   {
1146     GNUNET_break_op (0);
1147     h->info_cb.tunnel_cb (h->info_cls, NULL, 0, 0, NULL, NULL, 0, 0);
1148     goto clean_cls;
1149   }
1150   ch_n = ntohl (msg->channels);
1151   c_n = ntohl (msg->connections);
1152   esize += ch_n * sizeof (CADET_ChannelNumber);
1153   esize += c_n * sizeof (struct GNUNET_CADET_Hash);
1154   if (msize != esize)
1155   {
1156     GNUNET_break_op (0);
1157     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1158                 "m:%u, e: %u (%u ch, %u conn)\n",
1159                 (unsigned int) msize,
1160                 (unsigned int) esize,
1161                 ch_n,
1162                 c_n);
1163     h->info_cb.tunnel_cb (h->info_cls, NULL, 0, 0, NULL, NULL, 0, 0);
1164     goto clean_cls;
1165   }
1166
1167   return GNUNET_OK;
1168
1169 clean_cls:
1170   h->info_cb.tunnel_cb = NULL;
1171   h->info_cls = NULL;
1172   return GNUNET_SYSERR;
1173 }
1174
1175
1176 /**
1177  * Process a local tunnel info reply, pass info to the user.
1178  *
1179  * @param cls Closure (Cadet handle).
1180  * @param msg Message itself.
1181  */
1182 static void
1183 handle_get_tunnel (void *cls,
1184                    const struct GNUNET_CADET_LocalInfoTunnel *msg)
1185 {
1186   struct GNUNET_CADET_Handle *h = cls;
1187   unsigned int ch_n;
1188   unsigned int c_n;
1189   struct GNUNET_CADET_Hash *conns;
1190   CADET_ChannelNumber *chns;
1191
1192   ch_n = ntohl (msg->channels);
1193   c_n = ntohl (msg->connections);
1194
1195   /* Call Callback with tunnel info. */
1196   conns = (struct GNUNET_CADET_Hash *) &msg[1];
1197   chns = (CADET_ChannelNumber *) &conns[c_n];
1198   h->info_cb.tunnel_cb (h->info_cls, &msg->destination,
1199                         ch_n, c_n, chns, conns,
1200                         ntohs (msg->estate), ntohs (msg->cstate));
1201 }
1202
1203
1204
1205 /**
1206  * Reconnect to the service, retransmit all infomation to try to restore the
1207  * original state.
1208  *
1209  * @param h handle to the cadet
1210  *
1211  * @return GNUNET_YES in case of sucess, GNUNET_NO otherwise (service down...)
1212  */
1213 static int
1214 do_reconnect (struct GNUNET_CADET_Handle *h)
1215 {
1216   GNUNET_MQ_hd_fixed_size (channel_created,
1217                            GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE,
1218                            struct GNUNET_CADET_ChannelCreateMessage);
1219   GNUNET_MQ_hd_fixed_size (channel_destroy,
1220                            GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY,
1221                            struct GNUNET_CADET_ChannelDestroyMessage);
1222   GNUNET_MQ_hd_var_size (local_data,
1223                          GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
1224                          struct GNUNET_CADET_LocalData);
1225   GNUNET_MQ_hd_fixed_size (local_ack,
1226                            GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
1227                            struct GNUNET_CADET_LocalAck);
1228   GNUNET_MQ_hd_var_size (get_peers,
1229                          GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS,
1230                          struct GNUNET_CADET_LocalInfoPeer);
1231   GNUNET_MQ_hd_var_size (get_peer,
1232                          GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER,
1233                          struct GNUNET_CADET_LocalInfoPeer);
1234   GNUNET_MQ_hd_var_size (get_tunnels,
1235                          GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS,
1236                          struct GNUNET_CADET_LocalInfoTunnel);
1237   GNUNET_MQ_hd_var_size (get_tunnel,
1238                          GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL,
1239                          struct GNUNET_CADET_LocalInfoTunnel);
1240   // FIXME
1241 //   GNUNET_MQ_hd_fixed_Y       size (channel_destroyed,
1242 //                            GNUNET_MESSAGE_TYPE_CADET_CHANNEL_NACK,
1243 //                            struct GNUNET_CADET_ChannelDestroyMessage);
1244   struct GNUNET_MQ_MessageHandler handlers[] = {
1245     make_channel_created_handler (h),
1246     make_channel_destroy_handler (h),
1247     make_local_data_handler (h),
1248     make_local_ack_handler (h),
1249     make_get_peers_handler (h),
1250     make_get_peer_handler (h),
1251     make_get_tunnels_handler (h),
1252     make_get_tunnel_handler (h),
1253     GNUNET_MQ_handler_end ()
1254   };
1255
1256   LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to CADET\n");
1257
1258   GNUNET_assert (NULL == h->mq);
1259   h->mq = GNUNET_CLIENT_connecT (h->cfg,
1260                                  "cadet",
1261                                  handlers,
1262                                  &handle_mq_error,
1263                                  h);
1264   if (NULL == h->mq)
1265   {
1266     reconnect (h);
1267     return GNUNET_NO;
1268   }
1269   else
1270   {
1271     h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1272   }
1273   return GNUNET_YES;
1274 }
1275
1276 /**
1277  * Reconnect callback: tries to reconnect again after a failer previous
1278  * reconnecttion
1279  *
1280  * @param cls closure (cadet handle)
1281  */
1282 static void
1283 reconnect_cbk (void *cls)
1284 {
1285   struct GNUNET_CADET_Handle *h = cls;
1286
1287   h->reconnect_task = NULL;
1288   do_reconnect (h);
1289 }
1290
1291
1292 /**
1293  * Reconnect to the service, retransmit all infomation to try to restore the
1294  * original state.
1295  *
1296  * @param h handle to the cadet
1297  *
1298  * @return #GNUNET_YES in case of sucess, #GNUNET_NO otherwise (service down...)
1299  */
1300 static void
1301 reconnect (struct GNUNET_CADET_Handle *h)
1302 {
1303   struct GNUNET_CADET_Channel *ch;
1304
1305   LOG (GNUNET_ERROR_TYPE_DEBUG,
1306        "Requested RECONNECT, destroying all channels\n");
1307   for (ch = h->channels_head; NULL != ch; ch = h->channels_head)
1308     destroy_channel (ch, GNUNET_YES);
1309   if (NULL == h->reconnect_task)
1310     h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
1311                                                       &reconnect_cbk, h);
1312 }
1313
1314
1315 /******************************************************************************/
1316 /**********************      API CALL DEFINITIONS     *************************/
1317 /******************************************************************************/
1318
1319 struct GNUNET_CADET_Handle *
1320 GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls,
1321                      GNUNET_CADET_ChannelEndHandler cleaner,
1322                      const struct GNUNET_CADET_MessageHandler *handlers)
1323 {
1324   struct GNUNET_CADET_Handle *h;
1325
1326   LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_CADET_connect()\n");
1327   h = GNUNET_new (struct GNUNET_CADET_Handle);
1328   LOG (GNUNET_ERROR_TYPE_DEBUG, " addr %p\n", h);
1329   h->cfg = cfg;
1330   h->cleaner = cleaner;
1331   h->ports = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_YES);
1332   do_reconnect (h);
1333   if (h->mq == NULL)
1334   {
1335     GNUNET_break (0);
1336     GNUNET_CADET_disconnect (h);
1337     return NULL;
1338   }
1339   h->cls = cls;
1340   h->message_handlers = handlers;
1341   h->next_chid = GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
1342   h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1343   h->reconnect_task = NULL;
1344
1345   /* count handlers */
1346   for (h->n_handlers = 0;
1347        handlers && handlers[h->n_handlers].type;
1348        h->n_handlers++) ;
1349   LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_CADET_connect() END\n");
1350   return h;
1351 }
1352
1353
1354 void
1355 GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle)
1356 {
1357   struct GNUNET_CADET_Channel *ch;
1358   struct GNUNET_CADET_Channel *aux;
1359   struct GNUNET_CADET_TransmitHandle *th;
1360
1361   LOG (GNUNET_ERROR_TYPE_DEBUG, "CADET DISCONNECT\n");
1362
1363   ch = handle->channels_head;
1364   while (NULL != ch)
1365   {
1366     aux = ch->next;
1367     if (ch->chid < GNUNET_CADET_LOCAL_CHANNEL_ID_SERV)
1368     {
1369       GNUNET_break (0);
1370       LOG (GNUNET_ERROR_TYPE_DEBUG, "channel %X not destroyed\n", ch->chid);
1371     }
1372     destroy_channel (ch, GNUNET_YES);
1373     ch = aux;
1374   }
1375   while ( (th = handle->th_head) != NULL)
1376   {
1377     struct GNUNET_MessageHeader *msg;
1378
1379     /* Make sure it is an allowed packet (everything else should have been
1380      * already canceled).
1381      */
1382     GNUNET_break (GNUNET_NO == th_is_payload (th));
1383     msg = (struct GNUNET_MessageHeader *) &th[1];
1384     switch (ntohs(msg->type))
1385     {
1386       case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE:
1387       case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY:
1388       case GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN:
1389       case GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE:
1390       case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNELS:
1391       case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL:
1392       case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER:
1393       case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS:
1394       case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL:
1395       case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS:
1396         break;
1397       default:
1398         GNUNET_break (0);
1399         LOG (GNUNET_ERROR_TYPE_ERROR, "unexpected unsent msg %s\n",
1400              GC_m2s (ntohs(msg->type)));
1401     }
1402
1403     GNUNET_CADET_notify_transmit_ready_cancel (th);
1404   }
1405
1406   if (NULL != handle->mq)
1407   {
1408     GNUNET_MQ_destroy (handle->mq);
1409     handle->mq = NULL;
1410   }
1411   if (NULL != handle->reconnect_task)
1412   {
1413     GNUNET_SCHEDULER_cancel(handle->reconnect_task);
1414     handle->reconnect_task = NULL;
1415   }
1416
1417   GNUNET_CONTAINER_multihashmap_destroy (handle->ports);
1418   handle->ports = NULL;
1419   GNUNET_free (handle);
1420 }
1421
1422
1423 /**
1424  * Open a port to receive incomming channels.
1425  *
1426  * @param h CADET handle.
1427  * @param port Hash representing the port number.
1428  * @param new_channel Function called when an channel is received.
1429  * @param new_channel_cls Closure for @a new_channel.
1430  *
1431  * @return Port handle.
1432  */
1433 struct GNUNET_CADET_Port *
1434 GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h,
1435                         const struct GNUNET_HashCode *port,
1436                         GNUNET_CADET_InboundChannelNotificationHandler
1437                             new_channel,
1438                         void *new_channel_cls)
1439 {
1440   struct GNUNET_CADET_PortMessage *msg;
1441   struct GNUNET_MQ_Envelope *env;
1442   struct GNUNET_CADET_Port *p;
1443
1444   GNUNET_assert (NULL != new_channel);
1445   p = GNUNET_new (struct GNUNET_CADET_Port);
1446   p->cadet = h;
1447   p->hash = GNUNET_new (struct GNUNET_HashCode);
1448   *p->hash = *port;
1449   p->handler = new_channel;
1450   p->cls = new_channel_cls;
1451   GNUNET_assert (GNUNET_OK ==
1452                  GNUNET_CONTAINER_multihashmap_put (h->ports,
1453                                                     p->hash,
1454                                                     p,
1455                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1456
1457   env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN);
1458   msg->port = *p->hash;
1459   GNUNET_MQ_send (h->mq, env);
1460
1461   return p;
1462 }
1463
1464 /**
1465  * Close a port opened with @a GNUNET_CADET_open_port.
1466  * The @a new_channel callback will no longer be called.
1467  *
1468  * @param p Port handle.
1469  */
1470 void
1471 GNUNET_CADET_close_port (struct GNUNET_CADET_Port *p)
1472 {
1473   struct GNUNET_CADET_PortMessage *msg;
1474   struct GNUNET_MQ_Envelope *env;
1475
1476   env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE);
1477
1478   msg->port = *p->hash;
1479   GNUNET_MQ_send (p->cadet->mq, env);
1480   GNUNET_CONTAINER_multihashmap_remove (p->cadet->ports, p->hash, p);
1481   GNUNET_free (p->hash);
1482   GNUNET_free (p);
1483 }
1484
1485
1486 /**
1487  * Create a new channel towards a remote peer.
1488  *
1489  * If the destination port is not open by any peer or the destination peer
1490  * does not accept the channel, #GNUNET_CADET_ChannelEndHandler will be called
1491  * for this channel.
1492  *
1493  * @param h cadet handle
1494  * @param channel_ctx client's channel context to associate with the channel
1495  * @param peer peer identity the channel should go to
1496  * @param port Port hash (port number).
1497  * @param options CadetOption flag field, with all desired option bits set to 1.
1498  *
1499  * @return handle to the channel
1500  */
1501 struct GNUNET_CADET_Channel *
1502 GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle *h,
1503                             void *channel_ctx,
1504                             const struct GNUNET_PeerIdentity *peer,
1505                             const struct GNUNET_HashCode *port,
1506                             enum GNUNET_CADET_ChannelOption options)
1507 {
1508   struct GNUNET_CADET_ChannelCreateMessage *msg;
1509   struct GNUNET_MQ_Envelope *env;
1510   struct GNUNET_CADET_Channel *ch;
1511
1512   LOG (GNUNET_ERROR_TYPE_DEBUG,
1513        "Creating new channel to %s:%u\n",
1514        GNUNET_i2s (peer), port);
1515   ch = create_channel (h, 0);
1516   LOG (GNUNET_ERROR_TYPE_DEBUG, "  at %p\n", ch);
1517   LOG (GNUNET_ERROR_TYPE_DEBUG, "  number %X\n", ch->chid);
1518   ch->ctx = channel_ctx;
1519   ch->peer = GNUNET_PEER_intern (peer);
1520
1521   env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE);
1522   msg->channel_id = htonl (ch->chid);
1523   msg->port = *port;
1524   msg->peer = *peer;
1525   msg->opt = htonl (options);
1526   ch->allow_send = GNUNET_NO;
1527   GNUNET_MQ_send (h->mq, env);
1528
1529   return ch;
1530 }
1531
1532
1533 void
1534 GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel)
1535 {
1536   struct GNUNET_CADET_Handle *h;
1537   struct GNUNET_CADET_ChannelDestroyMessage *msg;
1538   struct GNUNET_MQ_Envelope *env;
1539   struct GNUNET_CADET_TransmitHandle *th;
1540   struct GNUNET_CADET_TransmitHandle *next;
1541
1542   LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying channel\n");
1543   h = channel->cadet;
1544   for  (th = h->th_head; th != NULL; th = next)
1545   {
1546     next = th->next;
1547     if (th->channel == channel)
1548     {
1549       GNUNET_break (0);
1550       if (GNUNET_YES == th_is_payload (th))
1551       {
1552         /* applications should cancel before destroying channel */
1553         LOG (GNUNET_ERROR_TYPE_WARNING,
1554              "Channel destroyed without cancelling transmission requests\n");
1555         th->notify (th->notify_cls, 0, NULL);
1556       }
1557       else
1558       {
1559         LOG (GNUNET_ERROR_TYPE_WARNING, "no meta-traffic should be queued\n");
1560       }
1561       GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th);
1562       GNUNET_CADET_notify_transmit_ready_cancel (th);
1563     }
1564   }
1565
1566   env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY);
1567   msg->channel_id = htonl (channel->chid);
1568   GNUNET_MQ_send (h->mq, env);
1569
1570   destroy_channel (channel, GNUNET_YES);
1571 }
1572
1573
1574 /**
1575  * Get information about a channel.
1576  *
1577  * @param channel Channel handle.
1578  * @param option Query (GNUNET_CADET_OPTION_*).
1579  * @param ... dependant on option, currently not used
1580  *
1581  * @return Union with an answer to the query.
1582  */
1583 const union GNUNET_CADET_ChannelInfo *
1584 GNUNET_CADET_channel_get_info (struct GNUNET_CADET_Channel *channel,
1585                               enum GNUNET_CADET_ChannelOption option, ...)
1586 {
1587   static int bool_flag;
1588   const union GNUNET_CADET_ChannelInfo *ret;
1589
1590   switch (option)
1591   {
1592     case GNUNET_CADET_OPTION_NOBUFFER:
1593     case GNUNET_CADET_OPTION_RELIABLE:
1594     case GNUNET_CADET_OPTION_OOORDER:
1595       if (0 != (option & channel->options))
1596         bool_flag = GNUNET_YES;
1597       else
1598         bool_flag = GNUNET_NO;
1599       ret = (const union GNUNET_CADET_ChannelInfo *) &bool_flag;
1600       break;
1601     case GNUNET_CADET_OPTION_PEER:
1602       ret = (const union GNUNET_CADET_ChannelInfo *) GNUNET_PEER_resolve2 (channel->peer);
1603       break;
1604     default:
1605       GNUNET_break (0);
1606       return NULL;
1607   }
1608
1609   return ret;
1610 }
1611
1612
1613 struct GNUNET_CADET_TransmitHandle *
1614 GNUNET_CADET_notify_transmit_ready (struct GNUNET_CADET_Channel *channel,
1615                                     int cork,
1616                                     struct GNUNET_TIME_Relative maxdelay,
1617                                     size_t notify_size,
1618                                     GNUNET_CONNECTION_TransmitReadyNotify notify,
1619                                     void *notify_cls)
1620 {
1621   struct GNUNET_CADET_TransmitHandle *th;
1622
1623   GNUNET_assert (NULL != channel);
1624   GNUNET_assert (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE >= notify_size);
1625   LOG (GNUNET_ERROR_TYPE_DEBUG, "CADET NOTIFY TRANSMIT READY\n");
1626   LOG (GNUNET_ERROR_TYPE_DEBUG, "    on channel %X\n", channel->chid);
1627   LOG (GNUNET_ERROR_TYPE_DEBUG, "    allow_send %d\n", channel->allow_send);
1628   if (channel->chid >= GNUNET_CADET_LOCAL_CHANNEL_ID_SERV)
1629     LOG (GNUNET_ERROR_TYPE_DEBUG, "    to origin\n");
1630   else
1631     LOG (GNUNET_ERROR_TYPE_DEBUG, "    to destination\n");
1632   LOG (GNUNET_ERROR_TYPE_DEBUG, "    payload size %u\n", notify_size);
1633   GNUNET_assert (NULL != notify);
1634   GNUNET_assert (0 == channel->packet_size); // Only one data packet allowed
1635
1636   if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us != maxdelay.rel_value_us)
1637   {
1638     LOG (GNUNET_ERROR_TYPE_WARNING,
1639          "CADET transmit ready timeout is deprected (has no effect)\n");
1640   }
1641
1642   th = GNUNET_new (struct GNUNET_CADET_TransmitHandle);
1643   th->channel = channel;
1644   th->size = notify_size;
1645   channel->packet_size = th->size;
1646   LOG (GNUNET_ERROR_TYPE_DEBUG, "    total size %u\n", th->size);
1647   th->notify = notify;
1648   th->notify_cls = notify_cls;
1649   if (GNUNET_YES == channel->allow_send)
1650     th->request_data_task = GNUNET_SCHEDULER_add_now (&request_data, th);
1651   else
1652     add_to_queue (channel->cadet, th);
1653
1654   LOG (GNUNET_ERROR_TYPE_DEBUG, "CADET NOTIFY TRANSMIT READY END\n");
1655   return th;
1656 }
1657
1658
1659 void
1660 GNUNET_CADET_notify_transmit_ready_cancel (struct GNUNET_CADET_TransmitHandle *th)
1661 {
1662   if (NULL != th->request_data_task)
1663   {
1664     GNUNET_SCHEDULER_cancel (th->request_data_task);
1665   }
1666   th->request_data_task = NULL;
1667
1668   /* It might or might not have been queued (rarely not), but check anyway. */
1669   if (NULL != th->next)
1670   {
1671     struct GNUNET_CADET_Handle *h;
1672     h = th->channel->cadet;
1673     GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th);
1674   }
1675   GNUNET_free (th);
1676 }
1677
1678
1679 void
1680 GNUNET_CADET_receive_done (struct GNUNET_CADET_Channel *channel)
1681 {
1682   send_ack (channel);
1683 }
1684
1685
1686 static void
1687 send_info_request (struct GNUNET_CADET_Handle *h, uint16_t type)
1688 {
1689   struct GNUNET_MessageHeader *msg;
1690   struct GNUNET_MQ_Envelope *env;
1691
1692   env = GNUNET_MQ_msg (msg, type);
1693   GNUNET_MQ_send (h->mq, env);
1694
1695   LOG (GNUNET_ERROR_TYPE_DEBUG,
1696        " Sending %s message to service\n",
1697        GC_m2s(type));
1698 }
1699
1700
1701 /**
1702  * Request a debug dump on the service's STDERR.
1703  *
1704  * WARNING: unstable API, likely to change in the future!
1705  *
1706  * @param h cadet handle
1707  */
1708 void
1709 GNUNET_CADET_request_dump (struct GNUNET_CADET_Handle *h)
1710 {
1711   LOG (GNUNET_ERROR_TYPE_DEBUG, "requesting dump\n");
1712   send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP);
1713 }
1714
1715
1716 /**
1717  * Request information about peers known to the running cadet service.
1718  * The callback will be called for every peer known to the service.
1719  * Only one info request (of any kind) can be active at once.
1720  *
1721  *
1722  * WARNING: unstable API, likely to change in the future!
1723  *
1724  * @param h Handle to the cadet peer.
1725  * @param callback Function to call with the requested data.
1726  * @param callback_cls Closure for @c callback.
1727  *
1728  * @return #GNUNET_OK / #GNUNET_SYSERR
1729  */
1730 int
1731 GNUNET_CADET_get_peers (struct GNUNET_CADET_Handle *h,
1732                        GNUNET_CADET_PeersCB callback,
1733                        void *callback_cls)
1734 {
1735   if (NULL != h->info_cb.peers_cb)
1736   {
1737     GNUNET_break (0);
1738     return GNUNET_SYSERR;
1739   }
1740   send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
1741   h->info_cb.peers_cb = callback;
1742   h->info_cls = callback_cls;
1743   return GNUNET_OK;
1744 }
1745
1746
1747 /**
1748  * Cancel a peer info request. The callback will not be called (anymore).
1749  *
1750  * WARNING: unstable API, likely to change in the future!
1751  *
1752  * @param h Cadet handle.
1753  *
1754  * @return Closure given to GNUNET_CADET_get_peers.
1755  */
1756 void *
1757 GNUNET_CADET_get_peers_cancel (struct GNUNET_CADET_Handle *h)
1758 {
1759   void *cls;
1760
1761   cls = h->info_cls;
1762   h->info_cb.peers_cb = NULL;
1763   h->info_cls = NULL;
1764   return cls;
1765 }
1766
1767
1768 /**
1769  * Request information about a peer known to the running cadet peer.
1770  * The callback will be called for the tunnel once.
1771  * Only one info request (of any kind) can be active at once.
1772  *
1773  * WARNING: unstable API, likely to change in the future!
1774  *
1775  * @param h Handle to the cadet peer.
1776  * @param id Peer whose tunnel to examine.
1777  * @param callback Function to call with the requested data.
1778  * @param callback_cls Closure for @c callback.
1779  *
1780  * @return #GNUNET_OK / #GNUNET_SYSERR
1781  */
1782 int
1783 GNUNET_CADET_get_peer (struct GNUNET_CADET_Handle *h,
1784                        const struct GNUNET_PeerIdentity *id,
1785                        GNUNET_CADET_PeerCB callback,
1786                        void *callback_cls)
1787 {
1788   struct GNUNET_CADET_LocalInfo *msg;
1789   struct GNUNET_MQ_Envelope *env;
1790
1791   if (NULL != h->info_cb.peer_cb)
1792   {
1793     GNUNET_break (0);
1794     return GNUNET_SYSERR;
1795   }
1796
1797   env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
1798   msg->peer = *id;
1799   GNUNET_MQ_send (h->mq, env);
1800
1801   h->info_cb.peer_cb = callback;
1802   h->info_cls = callback_cls;
1803   return GNUNET_OK;
1804 }
1805
1806
1807 /**
1808  * Request information about tunnels of the running cadet peer.
1809  * The callback will be called for every tunnel of the service.
1810  * Only one info request (of any kind) can be active at once.
1811  *
1812  * WARNING: unstable API, likely to change in the future!
1813  *
1814  * @param h Handle to the cadet peer.
1815  * @param callback Function to call with the requested data.
1816  * @param callback_cls Closure for @c callback.
1817  *
1818  * @return #GNUNET_OK / #GNUNET_SYSERR
1819  */
1820 int
1821 GNUNET_CADET_get_tunnels (struct GNUNET_CADET_Handle *h,
1822                          GNUNET_CADET_TunnelsCB callback,
1823                          void *callback_cls)
1824 {
1825   if (NULL != h->info_cb.tunnels_cb)
1826   {
1827     GNUNET_break (0);
1828     return GNUNET_SYSERR;
1829   }
1830   send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
1831   h->info_cb.tunnels_cb = callback;
1832   h->info_cls = callback_cls;
1833   return GNUNET_OK;
1834 }
1835
1836
1837 /**
1838  * Cancel a monitor request. The monitor callback will not be called.
1839  *
1840  * @param h Cadet handle.
1841  *
1842  * @return Closure given to GNUNET_CADET_get_tunnels.
1843  */
1844 void *
1845 GNUNET_CADET_get_tunnels_cancel (struct GNUNET_CADET_Handle *h)
1846 {
1847   void *cls;
1848
1849   h->info_cb.tunnels_cb = NULL;
1850   cls = h->info_cls;
1851   h->info_cls = NULL;
1852
1853   return cls;
1854 }
1855
1856
1857
1858 /**
1859  * Request information about a tunnel of the running cadet peer.
1860  * The callback will be called for the tunnel once.
1861  * Only one info request (of any kind) can be active at once.
1862  *
1863  * WARNING: unstable API, likely to change in the future!
1864  *
1865  * @param h Handle to the cadet peer.
1866  * @param id Peer whose tunnel to examine.
1867  * @param callback Function to call with the requested data.
1868  * @param callback_cls Closure for @c callback.
1869  *
1870  * @return #GNUNET_OK / #GNUNET_SYSERR
1871  */
1872 int
1873 GNUNET_CADET_get_tunnel (struct GNUNET_CADET_Handle *h,
1874                         const struct GNUNET_PeerIdentity *id,
1875                         GNUNET_CADET_TunnelCB callback,
1876                         void *callback_cls)
1877 {
1878   struct GNUNET_CADET_LocalInfo *msg;
1879   struct GNUNET_MQ_Envelope *env;
1880
1881   if (NULL != h->info_cb.tunnel_cb)
1882   {
1883     GNUNET_break (0);
1884     return GNUNET_SYSERR;
1885   }
1886
1887   env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
1888   msg->peer = *id;
1889   GNUNET_MQ_send (h->mq, env);
1890
1891   h->info_cb.tunnel_cb = callback;
1892   h->info_cls = callback_cls;
1893   return GNUNET_OK;
1894 }
1895
1896
1897 /**
1898  * Request information about a specific channel of the running cadet peer.
1899  *
1900  * WARNING: unstable API, likely to change in the future!
1901  * FIXME Add destination option.
1902  *
1903  * @param h Handle to the cadet peer.
1904  * @param initiator ID of the owner of the channel.
1905  * @param channel_number Channel number.
1906  * @param callback Function to call with the requested data.
1907  * @param callback_cls Closure for @c callback.
1908  *
1909  * @return #GNUNET_OK / #GNUNET_SYSERR
1910  */
1911 int
1912 GNUNET_CADET_show_channel (struct GNUNET_CADET_Handle *h,
1913                            struct GNUNET_PeerIdentity *initiator,
1914                            unsigned int channel_number,
1915                            GNUNET_CADET_ChannelCB callback,
1916                            void *callback_cls)
1917 {
1918   struct GNUNET_CADET_LocalInfo *msg;
1919   struct GNUNET_MQ_Envelope *env;
1920
1921   if (NULL != h->info_cb.channel_cb)
1922   {
1923     GNUNET_break (0);
1924     return GNUNET_SYSERR;
1925   }
1926
1927   env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL);
1928   msg->peer = *initiator;
1929   msg->channel_id = htonl (channel_number);
1930   GNUNET_MQ_send (h->mq, env);
1931
1932   h->info_cb.channel_cb = callback;
1933   h->info_cls = callback_cls;
1934   return GNUNET_OK;
1935 }
1936
1937
1938 /**
1939  * Function called to notify a client about the connection
1940  * begin ready to queue more data.  "buf" will be
1941  * NULL and "size" zero if the connection was closed for
1942  * writing in the meantime.
1943  *
1944  * @param cls closure
1945  * @param size number of bytes available in buf
1946  * @param buf where the callee should write the message
1947  * @return number of bytes written to buf
1948  */
1949 static size_t
1950 cadet_mq_ntr (void *cls, size_t size,
1951              void *buf)
1952 {
1953   struct GNUNET_MQ_Handle *mq = cls;
1954   struct CadetMQState *state = GNUNET_MQ_impl_state (mq);
1955   const struct GNUNET_MessageHeader *msg = GNUNET_MQ_impl_current (mq);
1956   uint16_t msize;
1957
1958   state->th = NULL;
1959   if (NULL == buf)
1960   {
1961     GNUNET_MQ_inject_error (mq, GNUNET_MQ_ERROR_WRITE);
1962     return 0;
1963   }
1964   msize = ntohs (msg->size);
1965   GNUNET_assert (msize <= size);
1966   GNUNET_memcpy (buf, msg, msize);
1967   GNUNET_MQ_impl_send_continue (mq);
1968   return msize;
1969 }
1970
1971
1972 /**
1973  * Signature of functions implementing the
1974  * sending functionality of a message queue.
1975  *
1976  * @param mq the message queue
1977  * @param msg the message to send
1978  * @param impl_state state of the implementation
1979  */
1980 static void
1981 cadet_mq_send_impl (struct GNUNET_MQ_Handle *mq,
1982                     const struct GNUNET_MessageHeader *msg,
1983                     void *impl_state)
1984 {
1985   struct CadetMQState *state = impl_state;
1986
1987   GNUNET_assert (NULL == state->th);
1988   state->th =
1989       GNUNET_CADET_notify_transmit_ready (state->channel,
1990                                          /* FIXME: add option for corking */
1991                                          GNUNET_NO,
1992                                          GNUNET_TIME_UNIT_FOREVER_REL,
1993                                          ntohs (msg->size),
1994                                          &cadet_mq_ntr, mq);
1995
1996 }
1997
1998
1999 /**
2000  * Signature of functions implementing the
2001  * destruction of a message queue.
2002  * Implementations must not free 'mq', but should
2003  * take care of 'impl_state'.
2004  *
2005  * @param mq the message queue to destroy
2006  * @param impl_state state of the implementation
2007  */
2008 static void
2009 cadet_mq_destroy_impl (struct GNUNET_MQ_Handle *mq,
2010                        void *impl_state)
2011 {
2012   struct CadetMQState *state = impl_state;
2013
2014   if (NULL != state->th)
2015     GNUNET_CADET_notify_transmit_ready_cancel (state->th);
2016
2017   GNUNET_free (state);
2018 }
2019
2020
2021 /**
2022  * Create a message queue for a cadet channel.
2023  * The message queue can only be used to transmit messages,
2024  * not to receive them.
2025  *
2026  * @param channel the channel to create the message qeue for
2027  * @return a message queue to messages over the channel
2028  */
2029 struct GNUNET_MQ_Handle *
2030 GNUNET_CADET_mq_create (struct GNUNET_CADET_Channel *channel)
2031 {
2032   struct GNUNET_MQ_Handle *mq;
2033   struct CadetMQState *state;
2034
2035   state = GNUNET_new (struct CadetMQState);
2036   state->channel = channel;
2037
2038   mq = GNUNET_MQ_queue_for_callbacks (&cadet_mq_send_impl,
2039                                       &cadet_mq_destroy_impl,
2040                                       NULL, /* FIXME: cancel impl. */
2041                                       state,
2042                                       NULL, /* no msg handlers */
2043                                       NULL, /* no err handlers */
2044                                       NULL); /* no handler cls */
2045   return mq;
2046 }
2047
2048
2049 /**
2050  * Transitional function to convert an unsigned int port to a hash value.
2051  * WARNING: local static value returned, NOT reentrant!
2052  * WARNING: do not use this function for new code!
2053  *
2054  * @param port Numerical port (unsigned int format).
2055  *
2056  * @return A GNUNET_HashCode usable for the new CADET API.
2057  */
2058 const struct GNUNET_HashCode *
2059 GC_u2h (uint32_t port)
2060 {
2061   static struct GNUNET_HashCode hash;
2062
2063   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2064               "This is a transitional function, "
2065               "use proper crypto hashes as CADET ports\n");
2066   GNUNET_CRYPTO_hash (&port, sizeof (port), &hash);
2067
2068   return &hash;
2069 }