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