2 This file is part of GNUnet.
3 Copyright (C) 2011 GNUnet e.V.
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.
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.
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.
21 * @file cadet/cadet_api.c
22 * @brief cadet api: client implementation of new cadet service
23 * @author Bartlomiej Polot
27 #include "gnunet_util_lib.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_cadet_service.h"
31 #include "cadet_protocol.h"
33 #define LOG(kind,...) GNUNET_log_from (kind, "cadet-api",__VA_ARGS__)
35 /******************************************************************************/
36 /************************ DATA STRUCTURES ****************************/
37 /******************************************************************************/
40 * Transmission queue to the service
42 struct GNUNET_CADET_TransmitHandle
47 struct GNUNET_CADET_TransmitHandle *next;
52 struct GNUNET_CADET_TransmitHandle *prev;
55 * Channel this message is sent on / for (may be NULL for control messages).
57 struct GNUNET_CADET_Channel *channel;
62 struct GNUNET_SCHEDULER_Task *request_data_task;
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
70 GNUNET_CONNECTION_TransmitReadyNotify notify;
73 * Closure for 'notify'
78 * Size of the payload.
88 GNUNET_CADET_ChannelCB channel_cb;
93 GNUNET_CADET_PeersCB peers_cb;
98 GNUNET_CADET_PeerCB peer_cb;
103 GNUNET_CADET_TunnelsCB tunnels_cb;
108 GNUNET_CADET_TunnelCB tunnel_cb;
113 * Opaque handle to the service.
115 struct GNUNET_CADET_Handle
118 * Message queue (if available).
120 struct GNUNET_MQ_Handle *mq;
123 * Set of handlers used for processing incoming messages in the channels
125 const struct GNUNET_CADET_MessageHandler *message_handlers;
128 * Number of handlers in the handlers array.
130 unsigned int n_handlers;
135 struct GNUNET_CONTAINER_MultiHashMap *ports;
138 * Double linked list of the channels this client is connected to, head.
140 struct GNUNET_CADET_Channel *channels_head;
143 * Double linked list of the channels this client is connected to, tail.
145 struct GNUNET_CADET_Channel *channels_tail;
148 * Callback for inbound channel disconnection
150 GNUNET_CADET_ChannelEndHandler *cleaner;
153 * Closure for all the handlers given by the client
158 * Messages to send to the service, head.
160 struct GNUNET_CADET_TransmitHandle *th_head;
163 * Messages to send to the service, tail.
165 struct GNUNET_CADET_TransmitHandle *th_tail;
168 * chid of the next channel to create (to avoid reusing IDs often)
170 CADET_ChannelNumber next_chid;
173 * Configuration given by the client, in case of reconnection
175 const struct GNUNET_CONFIGURATION_Handle *cfg;
178 * Time to the next reconnect in case one reconnect fails
180 struct GNUNET_TIME_Relative reconnect_time;
183 * Task for trying to reconnect.
185 struct GNUNET_SCHEDULER_Task * reconnect_task;
188 * Callback for an info task (only one active at a time).
190 union CadetInfoCB info_cb;
193 * Info callback closure for @c info_cb.
200 * Description of a peer
202 struct GNUNET_CADET_Peer
205 * ID of the peer in short form
210 * Channel this peer belongs to
212 struct GNUNET_CADET_Channel *t;
217 * Opaque handle to a channel.
219 struct GNUNET_CADET_Channel
224 struct GNUNET_CADET_Channel *next;
229 struct GNUNET_CADET_Channel *prev;
232 * Handle to the cadet this channel belongs to
234 struct GNUNET_CADET_Handle *cadet;
237 * Local ID of the channel
239 CADET_ChannelNumber chid;
242 * Channel's port, if any.
244 struct GNUNET_CADET_Port *port;
247 * Other end of the channel.
252 * Any data the caller wants to put in here
257 * Size of packet queued in this channel
259 unsigned int packet_size;
262 * Channel options: reliability, etc.
264 enum GNUNET_CADET_ChannelOption options;
267 * Are we allowed to send to the service?
274 * Opaque handle to a port.
276 struct GNUNET_CADET_Port
279 * Handle to the CADET session this port belongs to.
281 struct GNUNET_CADET_Handle *cadet;
286 struct GNUNET_HashCode *hash;
289 * Callback handler for incoming channels on this port.
291 GNUNET_CADET_InboundChannelNotificationHandler *handler;
294 * Closure for @a handler.
301 * Implementation state for cadet's message queue.
306 * The current transmit handle, or NULL
307 * if no transmit is active.
309 struct GNUNET_CADET_TransmitHandle *th;
312 * Channel to send the data over.
314 struct GNUNET_CADET_Channel *channel;
318 /******************************************************************************/
319 /*********************** AUXILIARY FUNCTIONS *************************/
320 /******************************************************************************/
323 * Check if transmission is a payload packet.
325 * @param th Transmission handle.
327 * @return #GNUNET_YES if it is a payload packet,
328 * #GNUNET_NO if it is a cadet management packet.
331 th_is_payload (struct GNUNET_CADET_TransmitHandle *th)
333 return (th->notify != NULL) ? GNUNET_YES : GNUNET_NO;
338 * Find the Port struct for a hash.
340 * @param h CADET handle.
341 * @param hash HashCode for the port number.
343 * @return The port handle if known, NULL otherwise.
345 static struct GNUNET_CADET_Port *
346 find_port (const struct GNUNET_CADET_Handle *h,
347 const struct GNUNET_HashCode *hash)
349 struct GNUNET_CADET_Port *p;
351 p = GNUNET_CONTAINER_multihashmap_get (h->ports, hash);
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
363 static struct GNUNET_CADET_Channel *
364 retrieve_channel (struct GNUNET_CADET_Handle *h, CADET_ChannelNumber chid)
366 struct GNUNET_CADET_Channel *ch;
368 ch = h->channels_head;
371 if (ch->chid == chid)
380 * Create a new channel and insert it in the channel list of the cadet handle
382 * @param h Cadet handle
383 * @param chid Desired chid of the channel, 0 to assign one automatically.
385 * @return Handle to the created channel.
387 static struct GNUNET_CADET_Channel *
388 create_channel (struct GNUNET_CADET_Handle *h, CADET_ChannelNumber chid)
390 struct GNUNET_CADET_Channel *ch;
392 ch = GNUNET_new (struct GNUNET_CADET_Channel);
393 GNUNET_CONTAINER_DLL_insert (h->channels_head, h->channels_tail, ch);
397 ch->chid = h->next_chid;
398 while (NULL != retrieve_channel (h, h->next_chid))
401 h->next_chid &= ~GNUNET_CADET_LOCAL_CHANNEL_ID_SERV;
402 h->next_chid |= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
409 ch->allow_send = GNUNET_NO;
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
421 * @param ch Pointer to the channel.
422 * @param call_cleaner Whether to call the cleaner handler.
424 * @return Handle to the required channel or NULL if not found.
427 destroy_channel (struct GNUNET_CADET_Channel *ch, int call_cleaner)
429 struct GNUNET_CADET_Handle *h;
430 struct GNUNET_CADET_TransmitHandle *th;
431 struct GNUNET_CADET_TransmitHandle *next;
433 LOG (GNUNET_ERROR_TYPE_DEBUG, " destroy_channel %X\n", ch->chid);
442 GNUNET_CONTAINER_DLL_remove (h->channels_head, h->channels_tail, ch);
444 /* signal channel destruction */
445 if ( (NULL != h->cleaner) && (0 != ch->peer) && (GNUNET_YES == call_cleaner) )
447 LOG (GNUNET_ERROR_TYPE_DEBUG, " calling cleaner\n");
448 h->cleaner (h->cls, ch, ch->ctx);
451 /* check that clients did not leave messages behind in the queue */
452 for (th = h->th_head; NULL != th; th = next)
455 if (th->channel != ch)
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.
461 GNUNET_break (GNUNET_NO == th_is_payload (th));
462 GNUNET_CADET_notify_transmit_ready_cancel (th);
466 GNUNET_PEER_change_rc (ch->peer, -1);
473 * Add a transmit handle to the transmission queue and set the
476 * @param h cadet handle with the queue head and tail
477 * @param th handle to the packet to be transmitted
480 add_to_queue (struct GNUNET_CADET_Handle *h,
481 struct GNUNET_CADET_TransmitHandle *th)
483 GNUNET_CONTAINER_DLL_insert_tail (h->th_head, h->th_tail, th);
488 * Remove a transmit handle from the transmission queue, if present.
490 * Safe to call even if not queued.
492 * @param th handle to the packet to be unqueued.
495 remove_from_queue (struct GNUNET_CADET_TransmitHandle *th)
497 struct GNUNET_CADET_Handle *h = th->channel->cadet;
499 /* It might or might not have been queued (rarely not), but check anyway. */
500 if (NULL != th->next || h->th_tail == th)
502 GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th);
508 * Send an ack on the channel to confirm the processing of a message.
510 * @param ch Channel on which to send the ACK.
513 send_ack (struct GNUNET_CADET_Channel *ch)
515 struct GNUNET_CADET_LocalAck *msg;
516 struct GNUNET_MQ_Envelope *env;
518 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
520 LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending ACK on channel %X\n", ch->chid);
521 msg->channel_id = htonl (ch->chid);
522 GNUNET_MQ_send (ch->cadet->mq, env);
529 /******************************************************************************/
530 /*********************** RECEIVE HANDLERS ****************************/
531 /******************************************************************************/
535 * Call the @a notify callback given to #GNUNET_CADET_notify_transmit_ready to
536 * request the data to send over MQ. Since MQ manages the queue, this function
537 * is scheduled immediatly after a transmit ready notification.
539 * @param cls Closure (transmit handle).
542 request_data (void *cls)
544 struct GNUNET_CADET_TransmitHandle *th = cls;
545 struct GNUNET_CADET_LocalData *msg;
546 struct GNUNET_MQ_Envelope *env;
549 LOG (GNUNET_ERROR_TYPE_DEBUG, "Requesting Data: %u bytes\n", th->size);
551 GNUNET_assert (GNUNET_YES == th->channel->allow_send);
552 th->channel->allow_send = GNUNET_NO;
553 th->request_data_task = NULL;
554 th->channel->packet_size = 0;
555 remove_from_queue (th);
557 env = GNUNET_MQ_msg_extra (msg, th->size,
558 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
559 msg->id = htonl (th->channel->chid);
560 osize = th->notify (th->notify_cls, th->size, &msg[1]);
561 GNUNET_assert (osize == th->size);
562 GNUNET_MQ_send (th->channel->cadet->mq, env);
569 * Process the new channel notification and add it to the channels in the handle
571 * @param h The cadet handle
572 * @param msg A message with the details of the new incoming channel
575 handle_channel_created (void *cls,
576 const struct GNUNET_CADET_ChannelCreateMessage *msg)
578 struct GNUNET_CADET_Handle *h = cls;
579 struct GNUNET_CADET_Channel *ch;
580 struct GNUNET_CADET_Port *port;
581 const struct GNUNET_HashCode *port_number;
582 CADET_ChannelNumber chid;
584 chid = ntohl (msg->channel_id);
585 port_number = &msg->port;
586 LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating incoming channel %X [%s]\n",
587 chid, GNUNET_h2s (port_number));
588 if (chid < GNUNET_CADET_LOCAL_CHANNEL_ID_SERV)
593 port = find_port (h, port_number);
598 ch = create_channel (h, chid);
599 ch->allow_send = GNUNET_NO;
600 ch->peer = GNUNET_PEER_intern (&msg->peer);
604 ch->options = ntohl (msg->opt);
606 LOG (GNUNET_ERROR_TYPE_DEBUG, " created channel %p\n", ch);
607 ctx = port->handler (port->cls, ch, &msg->peer, port->hash, ch->options);
610 LOG (GNUNET_ERROR_TYPE_DEBUG, "User notified\n");
614 struct GNUNET_CADET_ChannelDestroyMessage *d_msg;
615 struct GNUNET_MQ_Envelope *env;
617 LOG (GNUNET_ERROR_TYPE_DEBUG, "No handler for incoming channels\n");
618 env = GNUNET_MQ_msg (d_msg, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY);
619 d_msg->channel_id = msg->channel_id;
620 GNUNET_MQ_send (h->mq, env);
627 * Process the channel destroy notification and free associated resources
629 * @param h The cadet handle
630 * @param msg A message with the details of the channel being destroyed
633 handle_channel_destroy (void *cls,
634 const struct GNUNET_CADET_ChannelDestroyMessage *msg)
636 struct GNUNET_CADET_Handle *h = cls;
637 struct GNUNET_CADET_Channel *ch;
638 CADET_ChannelNumber chid;
640 chid = ntohl (msg->channel_id);
641 LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %X Destroy from service\n", chid);
642 ch = retrieve_channel (h, chid);
646 LOG (GNUNET_ERROR_TYPE_DEBUG, "channel %X unknown\n", chid);
649 destroy_channel (ch, GNUNET_YES);
654 * Check that message received from CADET service is well-formed.
656 * @param cls the `struct GNUNET_CADET_Handle`
657 * @param message the message we got
658 * @return #GNUNET_OK if the message is well-formed,
659 * #GNUNET_SYSERR otherwise
662 check_local_data (void *cls,
663 const struct GNUNET_CADET_LocalData *message)
665 struct GNUNET_CADET_Handle *h = cls;
666 struct GNUNET_CADET_Channel *ch;
669 size = ntohs (message->header.size);
670 if (sizeof (*message) + sizeof (struct GNUNET_MessageHeader) > size)
673 return GNUNET_SYSERR;
676 ch = retrieve_channel (h, ntohl (message->id));
680 return GNUNET_SYSERR;
688 * Process the incoming data packets, call appropriate handlers.
690 * @param h The cadet handle
691 * @param message A message encapsulating the data
694 handle_local_data (void *cls,
695 const struct GNUNET_CADET_LocalData *message)
697 struct GNUNET_CADET_Handle *h = cls;
698 const struct GNUNET_MessageHeader *payload;
699 const struct GNUNET_CADET_MessageHandler *handler;
700 struct GNUNET_CADET_Channel *ch;
704 LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a data message!\n");
705 ch = retrieve_channel (h, ntohl (message->id));
706 GNUNET_assert (NULL != ch);
708 payload = (struct GNUNET_MessageHeader *) &message[1];
709 LOG (GNUNET_ERROR_TYPE_DEBUG, " %s data on channel %s [%X]\n",
710 GC_f2s (ch->chid >= GNUNET_CADET_LOCAL_CHANNEL_ID_SERV),
711 GNUNET_i2s (GNUNET_PEER_resolve2 (ch->peer)), ntohl (message->id));
713 type = ntohs (payload->type);
714 LOG (GNUNET_ERROR_TYPE_DEBUG, " payload type %s\n", GC_m2s (type));
715 for (i = 0; i < h->n_handlers; i++)
717 handler = &h->message_handlers[i];
718 LOG (GNUNET_ERROR_TYPE_DEBUG, " checking handler for type %u\n",
720 if (handler->type == type)
723 handler->callback (h->cls, ch, &ch->ctx, payload))
725 LOG (GNUNET_ERROR_TYPE_DEBUG, "callback caused disconnection\n");
726 GNUNET_CADET_channel_destroy (ch);
731 LOG (GNUNET_ERROR_TYPE_DEBUG,
732 "callback completed successfully\n");
741 * Process a local ACK message, enabling the client to send
742 * more data to the service.
744 * @param h Cadet handle.
745 * @param message Message itself.
748 handle_local_ack (void *cls,
749 const struct GNUNET_CADET_LocalAck *message)
751 struct GNUNET_CADET_Handle *h = cls;
752 struct GNUNET_CADET_Channel *ch;
753 CADET_ChannelNumber chid;
755 LOG (GNUNET_ERROR_TYPE_DEBUG, "Got an ACK!\n");
756 chid = ntohl (message->channel_id);
757 ch = retrieve_channel (h, chid);
760 LOG (GNUNET_ERROR_TYPE_DEBUG, "ACK on unknown channel %X\n", chid);
763 LOG (GNUNET_ERROR_TYPE_DEBUG, " on channel %X!\n", ch->chid);
764 ch->allow_send = GNUNET_YES;
765 if (0 < ch->packet_size)
767 struct GNUNET_CADET_TransmitHandle *th;
768 struct GNUNET_CADET_TransmitHandle *next;
769 LOG (GNUNET_ERROR_TYPE_DEBUG,
770 " pending data, sending %u bytes!\n",
772 for (th = h->th_head; NULL != th; th = next)
775 if (th->channel == ch)
777 GNUNET_assert (NULL == th->request_data_task);
778 th->request_data_task = GNUNET_SCHEDULER_add_now (&request_data, th);
782 /* Complain if we got thru all th without sending anything, ch was wrong */
783 GNUNET_break (NULL != th);
788 * Reconnect to the service, retransmit all infomation to try to restore the
791 * @param h handle to the cadet
793 * @return #GNUNET_YES in case of sucess, #GNUNET_NO otherwise (service down...)
796 reconnect (struct GNUNET_CADET_Handle *h);
800 * Reconnect callback: tries to reconnect again after a failer previous
803 * @param cls closure (cadet handle)
806 reconnect_cbk (void *cls);
810 * Generic error handler, called with the appropriate error code and
811 * the same closure specified at the creation of the message queue.
812 * Not every message queue implementation supports an error handler.
814 * @param cls closure, a `struct GNUNET_CORE_Handle *`
815 * @param error error code
818 handle_mq_error (void *cls,
819 enum GNUNET_MQ_Error error)
821 struct GNUNET_CADET_Handle *h = cls;
823 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MQ ERROR: %u\n", error);
824 GNUNET_MQ_destroy (h->mq);
831 * Process a local reply about info on all channels, pass info to the user.
833 * @param h Cadet handle.
834 * @param message Message itself.
837 // process_get_channels (struct GNUNET_CADET_Handle *h,
838 // const struct GNUNET_MessageHeader *message)
840 // struct GNUNET_CADET_LocalInfo *msg;
842 // GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Get Channels messasge received\n");
844 // if (NULL == h->channels_cb)
846 // GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " ignored\n");
850 // msg = (struct GNUNET_CADET_LocalInfo *) message;
851 // if (ntohs (message->size) !=
852 // (sizeof (struct GNUNET_CADET_LocalInfo) +
853 // sizeof (struct GNUNET_PeerIdentity)))
855 // GNUNET_break_op (0);
856 // GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
857 // "Get channels message: size %hu - expected %u\n",
858 // ntohs (message->size),
859 // sizeof (struct GNUNET_CADET_LocalInfo));
862 // h->channels_cb (h->channels_cls,
863 // ntohl (msg->channel_id),
865 // &msg->destination);
871 * Process a local monitor_channel reply, pass info to the user.
873 * @param h Cadet handle.
874 * @param message Message itself.
877 // process_show_channel (struct GNUNET_CADET_Handle *h,
878 // const struct GNUNET_MessageHeader *message)
880 // struct GNUNET_CADET_LocalInfo *msg;
883 // GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Show Channel messasge received\n");
885 // if (NULL == h->channel_cb)
887 // GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " ignored\n");
891 // /* Verify message sanity */
892 // msg = (struct GNUNET_CADET_LocalInfo *) message;
893 // esize = sizeof (struct GNUNET_CADET_LocalInfo);
894 // if (ntohs (message->size) != esize)
896 // GNUNET_break_op (0);
897 // GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
898 // "Show channel message: size %hu - expected %u\n",
899 // ntohs (message->size),
902 // h->channel_cb (h->channel_cls, NULL, NULL);
903 // h->channel_cb = NULL;
904 // h->channel_cls = NULL;
909 // h->channel_cb (h->channel_cls,
910 // &msg->destination,
917 * Check that message received from CADET service is well-formed.
919 * @param cls the `struct GNUNET_CADET_Handle`
920 * @param message the message we got
921 * @return #GNUNET_OK if the message is well-formed,
922 * #GNUNET_SYSERR otherwise
925 check_get_peers (void *cls,
926 const struct GNUNET_CADET_LocalInfoPeer *message)
928 struct GNUNET_CADET_Handle *h = cls;
931 if (NULL == h->info_cb.peers_cb)
933 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
934 " no handler for peesr monitor message!\n");
935 return GNUNET_SYSERR;
938 size = ntohs (message->header.size);
939 if (sizeof (struct GNUNET_CADET_LocalInfoPeer) > size)
941 h->info_cb.peers_cb (h->info_cls, NULL, -1, 0, 0);
942 h->info_cb.peers_cb = NULL;
944 return GNUNET_SYSERR;
952 * Process a local reply about info on all tunnels, pass info to the user.
954 * @param cls Closure (Cadet handle).
955 * @param msg Message itself.
958 handle_get_peers (void *cls,
959 const struct GNUNET_CADET_LocalInfoPeer *msg)
961 struct GNUNET_CADET_Handle *h = cls;
962 h->info_cb.peers_cb (h->info_cls, &msg->destination,
963 (int) ntohs (msg->tunnel),
964 (unsigned int ) ntohs (msg->paths),
970 * Check that message received from CADET service is well-formed.
972 * @param cls the `struct GNUNET_CADET_Handle`
973 * @param message the message we got
974 * @return #GNUNET_OK if the message is well-formed,
975 * #GNUNET_SYSERR otherwise
978 check_get_peer (void *cls,
979 const struct GNUNET_CADET_LocalInfoPeer *message)
981 struct GNUNET_CADET_Handle *h = cls;
982 const size_t msize = sizeof (struct GNUNET_CADET_LocalInfoPeer);
983 struct GNUNET_PeerIdentity *paths_array;
989 if (NULL == h->info_cb.peer_cb)
991 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
992 " no handler for peer monitor message!\n");
996 /* Verify message sanity */
997 esize = ntohs (message->header.size);
1000 GNUNET_break_op (0);
1001 h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL);
1004 if (0 != ((esize - msize) % sizeof (struct GNUNET_PeerIdentity)))
1006 GNUNET_break_op (0);
1007 h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL);
1011 peers = (esize - msize) / sizeof (struct GNUNET_PeerIdentity);
1012 epaths = (unsigned int) ntohs (message->paths);
1013 paths_array = (struct GNUNET_PeerIdentity *) &message[1];
1015 for (int i = 0; i < peers; i++)
1017 if (0 == memcmp (&paths_array[i], &message->destination,
1018 sizeof (struct GNUNET_PeerIdentity)))
1023 if (paths != epaths)
1025 GNUNET_break_op (0);
1026 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "p:%u, e: %u\n", paths, epaths);
1027 h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL);
1034 h->info_cb.peer_cb = NULL;
1036 return GNUNET_SYSERR;
1041 * Process a local peer info reply, pass info to the user.
1043 * @param cls Closure (Cadet handle).
1044 * @param message Message itself.
1047 handle_get_peer (void *cls,
1048 const struct GNUNET_CADET_LocalInfoPeer *message)
1050 struct GNUNET_CADET_Handle *h = cls;
1051 struct GNUNET_PeerIdentity *paths_array;
1053 unsigned int path_length;
1057 paths = (unsigned int) ntohs (message->paths);
1058 paths_array = (struct GNUNET_PeerIdentity *) &message[1];
1059 peers = (ntohs (message->header.size) - sizeof (*message))
1060 / sizeof (struct GNUNET_PeerIdentity);
1062 neighbor = GNUNET_NO;
1064 for (int i = 0; i < peers; i++)
1066 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", GNUNET_i2s (&paths_array[i]));
1068 if (0 == memcmp (&paths_array[i], &message->destination,
1069 sizeof (struct GNUNET_PeerIdentity)))
1071 if (1 == path_length)
1072 neighbor = GNUNET_YES;
1077 /* Call Callback with tunnel info. */
1078 paths_array = (struct GNUNET_PeerIdentity *) &message[1];
1079 h->info_cb.peer_cb (h->info_cls,
1080 &message->destination,
1081 (int) ntohs (message->tunnel),
1089 * Check that message received from CADET service is well-formed.
1091 * @param cls the `struct GNUNET_CADET_Handle`
1092 * @param msg the message we got
1093 * @return #GNUNET_OK if the message is well-formed,
1094 * #GNUNET_SYSERR otherwise
1097 check_get_tunnels (void *cls,
1098 const struct GNUNET_CADET_LocalInfoTunnel *msg)
1100 struct GNUNET_CADET_Handle *h = cls;
1103 if (NULL == h->info_cb.tunnels_cb)
1105 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1106 " no handler for tunnels monitor message!\n");
1107 return GNUNET_SYSERR;
1110 size = ntohs (msg->header.size);
1111 if (sizeof (struct GNUNET_CADET_LocalInfoTunnel) > size)
1113 h->info_cb.tunnels_cb (h->info_cls, NULL, 0, 0, 0, 0);
1114 h->info_cb.tunnels_cb = NULL;
1116 return GNUNET_SYSERR;
1123 * Process a local reply about info on all tunnels, pass info to the user.
1125 * @param cls Closure (Cadet handle).
1126 * @param message Message itself.
1129 handle_get_tunnels (void *cls,
1130 const struct GNUNET_CADET_LocalInfoTunnel *msg)
1132 struct GNUNET_CADET_Handle *h = cls;
1134 h->info_cb.tunnels_cb (h->info_cls, &msg->destination,
1135 ntohl (msg->channels), ntohl (msg->connections),
1136 ntohs (msg->estate), ntohs (msg->cstate));
1142 * Check that message received from CADET service is well-formed.
1144 * @param cls the `struct GNUNET_CADET_Handle`
1145 * @param msg the message we got
1146 * @return #GNUNET_OK if the message is well-formed,
1147 * #GNUNET_SYSERR otherwise
1150 check_get_tunnel (void *cls,
1151 const struct GNUNET_CADET_LocalInfoTunnel *msg)
1153 struct GNUNET_CADET_Handle *h = cls;
1159 if (NULL == h->info_cb.tunnel_cb)
1161 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1162 " no handler for tunnel monitor message!\n");
1166 /* Verify message sanity */
1167 msize = ntohs (msg->header.size);
1168 esize = sizeof (struct GNUNET_CADET_LocalInfoTunnel);
1171 GNUNET_break_op (0);
1172 h->info_cb.tunnel_cb (h->info_cls, NULL, 0, 0, NULL, NULL, 0, 0);
1175 ch_n = ntohl (msg->channels);
1176 c_n = ntohl (msg->connections);
1177 esize += ch_n * sizeof (CADET_ChannelNumber);
1178 esize += c_n * sizeof (struct GNUNET_CADET_Hash);
1181 GNUNET_break_op (0);
1182 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1183 "m:%u, e: %u (%u ch, %u conn)\n",
1184 (unsigned int) msize,
1185 (unsigned int) esize,
1188 h->info_cb.tunnel_cb (h->info_cls, NULL, 0, 0, NULL, NULL, 0, 0);
1195 h->info_cb.tunnel_cb = NULL;
1197 return GNUNET_SYSERR;
1202 * Process a local tunnel info reply, pass info to the user.
1204 * @param cls Closure (Cadet handle).
1205 * @param msg Message itself.
1208 handle_get_tunnel (void *cls,
1209 const struct GNUNET_CADET_LocalInfoTunnel *msg)
1211 struct GNUNET_CADET_Handle *h = cls;
1214 struct GNUNET_CADET_Hash *conns;
1215 CADET_ChannelNumber *chns;
1217 ch_n = ntohl (msg->channels);
1218 c_n = ntohl (msg->connections);
1220 /* Call Callback with tunnel info. */
1221 conns = (struct GNUNET_CADET_Hash *) &msg[1];
1222 chns = (CADET_ChannelNumber *) &conns[c_n];
1223 h->info_cb.tunnel_cb (h->info_cls, &msg->destination,
1224 ch_n, c_n, chns, conns,
1225 ntohs (msg->estate), ntohs (msg->cstate));
1231 * Reconnect to the service, retransmit all infomation to try to restore the
1234 * @param h handle to the cadet
1236 * @return GNUNET_YES in case of sucess, GNUNET_NO otherwise (service down...)
1239 do_reconnect (struct GNUNET_CADET_Handle *h)
1241 GNUNET_MQ_hd_fixed_size (channel_created,
1242 GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE,
1243 struct GNUNET_CADET_ChannelCreateMessage);
1244 GNUNET_MQ_hd_fixed_size (channel_destroy,
1245 GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY,
1246 struct GNUNET_CADET_ChannelDestroyMessage);
1247 GNUNET_MQ_hd_var_size (local_data,
1248 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
1249 struct GNUNET_CADET_LocalData);
1250 GNUNET_MQ_hd_fixed_size (local_ack,
1251 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
1252 struct GNUNET_CADET_LocalAck);
1253 GNUNET_MQ_hd_var_size (get_peers,
1254 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS,
1255 struct GNUNET_CADET_LocalInfoPeer);
1256 GNUNET_MQ_hd_var_size (get_peer,
1257 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER,
1258 struct GNUNET_CADET_LocalInfoPeer);
1259 GNUNET_MQ_hd_var_size (get_tunnels,
1260 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS,
1261 struct GNUNET_CADET_LocalInfoTunnel);
1262 GNUNET_MQ_hd_var_size (get_tunnel,
1263 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL,
1264 struct GNUNET_CADET_LocalInfoTunnel);
1266 // GNUNET_MQ_hd_fixed_Y size (channel_destroyed,
1267 // GNUNET_MESSAGE_TYPE_CADET_CHANNEL_NACK,
1268 // struct GNUNET_CADET_ChannelDestroyMessage);
1269 struct GNUNET_MQ_MessageHandler handlers[] = {
1270 make_channel_created_handler (h),
1271 make_channel_destroy_handler (h),
1272 make_local_data_handler (h),
1273 make_local_ack_handler (h),
1274 make_get_peers_handler (h),
1275 make_get_peer_handler (h),
1276 make_get_tunnels_handler (h),
1277 make_get_tunnel_handler (h),
1278 GNUNET_MQ_handler_end ()
1281 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to CADET\n");
1283 GNUNET_assert (NULL == h->mq);
1284 h->mq = GNUNET_CLIENT_connecT (h->cfg,
1296 h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1302 * Reconnect callback: tries to reconnect again after a failer previous
1305 * @param cls closure (cadet handle)
1308 reconnect_cbk (void *cls)
1310 struct GNUNET_CADET_Handle *h = cls;
1312 h->reconnect_task = NULL;
1318 * Reconnect to the service, retransmit all infomation to try to restore the
1321 * @param h handle to the cadet
1323 * @return #GNUNET_YES in case of sucess, #GNUNET_NO otherwise (service down...)
1326 reconnect (struct GNUNET_CADET_Handle *h)
1328 struct GNUNET_CADET_Channel *ch;
1330 LOG (GNUNET_ERROR_TYPE_DEBUG,
1331 "Requested RECONNECT, destroying all channels\n");
1332 for (ch = h->channels_head; NULL != ch; ch = h->channels_head)
1333 destroy_channel (ch, GNUNET_YES);
1334 if (NULL == h->reconnect_task)
1335 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
1340 /******************************************************************************/
1341 /********************** API CALL DEFINITIONS *************************/
1342 /******************************************************************************/
1344 struct GNUNET_CADET_Handle *
1345 GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls,
1346 GNUNET_CADET_ChannelEndHandler cleaner,
1347 const struct GNUNET_CADET_MessageHandler *handlers)
1349 struct GNUNET_CADET_Handle *h;
1351 LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_CADET_connect()\n");
1352 h = GNUNET_new (struct GNUNET_CADET_Handle);
1353 LOG (GNUNET_ERROR_TYPE_DEBUG, " addr %p\n", h);
1355 h->cleaner = cleaner;
1356 h->ports = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_YES);
1361 GNUNET_CADET_disconnect (h);
1365 h->message_handlers = handlers;
1366 h->next_chid = GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
1367 h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1368 h->reconnect_task = NULL;
1370 /* count handlers */
1371 for (h->n_handlers = 0;
1372 handlers && handlers[h->n_handlers].type;
1374 LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_CADET_connect() END\n");
1380 GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle)
1382 struct GNUNET_CADET_Channel *ch;
1383 struct GNUNET_CADET_Channel *aux;
1384 struct GNUNET_CADET_TransmitHandle *th;
1386 LOG (GNUNET_ERROR_TYPE_DEBUG, "CADET DISCONNECT\n");
1388 ch = handle->channels_head;
1392 if (ch->chid < GNUNET_CADET_LOCAL_CHANNEL_ID_SERV)
1395 LOG (GNUNET_ERROR_TYPE_DEBUG, "channel %X not destroyed\n", ch->chid);
1397 destroy_channel (ch, GNUNET_YES);
1400 while ( (th = handle->th_head) != NULL)
1402 struct GNUNET_MessageHeader *msg;
1404 /* Make sure it is an allowed packet (everything else should have been
1405 * already canceled).
1407 GNUNET_break (GNUNET_NO == th_is_payload (th));
1408 msg = (struct GNUNET_MessageHeader *) &th[1];
1409 switch (ntohs(msg->type))
1411 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE:
1412 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY:
1413 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN:
1414 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE:
1415 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNELS:
1416 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL:
1417 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER:
1418 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS:
1419 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL:
1420 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS:
1424 LOG (GNUNET_ERROR_TYPE_ERROR, "unexpected unsent msg %s\n",
1425 GC_m2s (ntohs(msg->type)));
1428 GNUNET_CADET_notify_transmit_ready_cancel (th);
1431 if (NULL != handle->mq)
1433 GNUNET_MQ_destroy (handle->mq);
1436 if (NULL != handle->reconnect_task)
1438 GNUNET_SCHEDULER_cancel(handle->reconnect_task);
1439 handle->reconnect_task = NULL;
1442 GNUNET_CONTAINER_multihashmap_destroy (handle->ports);
1443 handle->ports = NULL;
1444 GNUNET_free (handle);
1449 * Open a port to receive incomming channels.
1451 * @param h CADET handle.
1452 * @param port Hash representing the port number.
1453 * @param new_channel Function called when an channel is received.
1454 * @param new_channel_cls Closure for @a new_channel.
1456 * @return Port handle.
1458 struct GNUNET_CADET_Port *
1459 GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h,
1460 const struct GNUNET_HashCode *port,
1461 GNUNET_CADET_InboundChannelNotificationHandler
1463 void *new_channel_cls)
1465 struct GNUNET_CADET_PortMessage *msg;
1466 struct GNUNET_MQ_Envelope *env;
1467 struct GNUNET_CADET_Port *p;
1469 GNUNET_assert (NULL != new_channel);
1470 p = GNUNET_new (struct GNUNET_CADET_Port);
1472 p->hash = GNUNET_new (struct GNUNET_HashCode);
1474 p->handler = new_channel;
1475 p->cls = new_channel_cls;
1476 GNUNET_assert (GNUNET_OK ==
1477 GNUNET_CONTAINER_multihashmap_put (h->ports,
1480 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1482 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN);
1483 msg->port = *p->hash;
1484 GNUNET_MQ_send (h->mq, env);
1490 * Close a port opened with @a GNUNET_CADET_open_port.
1491 * The @a new_channel callback will no longer be called.
1493 * @param p Port handle.
1496 GNUNET_CADET_close_port (struct GNUNET_CADET_Port *p)
1498 struct GNUNET_CADET_PortMessage *msg;
1499 struct GNUNET_MQ_Envelope *env;
1501 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE);
1503 msg->port = *p->hash;
1504 GNUNET_MQ_send (p->cadet->mq, env);
1505 GNUNET_CONTAINER_multihashmap_remove (p->cadet->ports, p->hash, p);
1506 GNUNET_free (p->hash);
1512 * Create a new channel towards a remote peer.
1514 * If the destination port is not open by any peer or the destination peer
1515 * does not accept the channel, #GNUNET_CADET_ChannelEndHandler will be called
1518 * @param h cadet handle
1519 * @param channel_ctx client's channel context to associate with the channel
1520 * @param peer peer identity the channel should go to
1521 * @param port Port hash (port number).
1522 * @param options CadetOption flag field, with all desired option bits set to 1.
1524 * @return handle to the channel
1526 struct GNUNET_CADET_Channel *
1527 GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle *h,
1529 const struct GNUNET_PeerIdentity *peer,
1530 const struct GNUNET_HashCode *port,
1531 enum GNUNET_CADET_ChannelOption options)
1533 struct GNUNET_CADET_ChannelCreateMessage *msg;
1534 struct GNUNET_MQ_Envelope *env;
1535 struct GNUNET_CADET_Channel *ch;
1537 LOG (GNUNET_ERROR_TYPE_DEBUG,
1538 "Creating new channel to %s:%u\n",
1539 GNUNET_i2s (peer), port);
1540 ch = create_channel (h, 0);
1541 LOG (GNUNET_ERROR_TYPE_DEBUG, " at %p\n", ch);
1542 LOG (GNUNET_ERROR_TYPE_DEBUG, " number %X\n", ch->chid);
1543 ch->ctx = channel_ctx;
1544 ch->peer = GNUNET_PEER_intern (peer);
1546 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE);
1547 msg->channel_id = htonl (ch->chid);
1550 msg->opt = htonl (options);
1551 ch->allow_send = GNUNET_NO;
1552 GNUNET_MQ_send (h->mq, env);
1559 GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel)
1561 struct GNUNET_CADET_Handle *h;
1562 struct GNUNET_CADET_ChannelDestroyMessage *msg;
1563 struct GNUNET_MQ_Envelope *env;
1564 struct GNUNET_CADET_TransmitHandle *th;
1565 struct GNUNET_CADET_TransmitHandle *next;
1567 LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying channel\n");
1569 for (th = h->th_head; th != NULL; th = next)
1572 if (th->channel == channel)
1575 if (GNUNET_YES == th_is_payload (th))
1577 /* applications should cancel before destroying channel */
1578 LOG (GNUNET_ERROR_TYPE_WARNING,
1579 "Channel destroyed without cancelling transmission requests\n");
1580 th->notify (th->notify_cls, 0, NULL);
1584 LOG (GNUNET_ERROR_TYPE_WARNING, "no meta-traffic should be queued\n");
1586 GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th);
1587 GNUNET_CADET_notify_transmit_ready_cancel (th);
1591 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY);
1592 msg->channel_id = htonl (channel->chid);
1593 GNUNET_MQ_send (h->mq, env);
1595 destroy_channel (channel, GNUNET_YES);
1600 * Get information about a channel.
1602 * @param channel Channel handle.
1603 * @param option Query (GNUNET_CADET_OPTION_*).
1604 * @param ... dependant on option, currently not used
1606 * @return Union with an answer to the query.
1608 const union GNUNET_CADET_ChannelInfo *
1609 GNUNET_CADET_channel_get_info (struct GNUNET_CADET_Channel *channel,
1610 enum GNUNET_CADET_ChannelOption option, ...)
1612 static int bool_flag;
1613 const union GNUNET_CADET_ChannelInfo *ret;
1617 case GNUNET_CADET_OPTION_NOBUFFER:
1618 case GNUNET_CADET_OPTION_RELIABLE:
1619 case GNUNET_CADET_OPTION_OOORDER:
1620 if (0 != (option & channel->options))
1621 bool_flag = GNUNET_YES;
1623 bool_flag = GNUNET_NO;
1624 ret = (const union GNUNET_CADET_ChannelInfo *) &bool_flag;
1626 case GNUNET_CADET_OPTION_PEER:
1627 ret = (const union GNUNET_CADET_ChannelInfo *) GNUNET_PEER_resolve2 (channel->peer);
1638 struct GNUNET_CADET_TransmitHandle *
1639 GNUNET_CADET_notify_transmit_ready (struct GNUNET_CADET_Channel *channel,
1641 struct GNUNET_TIME_Relative maxdelay,
1643 GNUNET_CONNECTION_TransmitReadyNotify notify,
1646 struct GNUNET_CADET_TransmitHandle *th;
1648 GNUNET_assert (NULL != channel);
1649 GNUNET_assert (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE >= notify_size);
1650 LOG (GNUNET_ERROR_TYPE_DEBUG, "CADET NOTIFY TRANSMIT READY\n");
1651 LOG (GNUNET_ERROR_TYPE_DEBUG, " on channel %X\n", channel->chid);
1652 LOG (GNUNET_ERROR_TYPE_DEBUG, " allow_send %d\n", channel->allow_send);
1653 if (channel->chid >= GNUNET_CADET_LOCAL_CHANNEL_ID_SERV)
1654 LOG (GNUNET_ERROR_TYPE_DEBUG, " to origin\n");
1656 LOG (GNUNET_ERROR_TYPE_DEBUG, " to destination\n");
1657 LOG (GNUNET_ERROR_TYPE_DEBUG, " payload size %u\n", notify_size);
1658 GNUNET_assert (NULL != notify);
1659 GNUNET_assert (0 == channel->packet_size); // Only one data packet allowed
1661 if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us != maxdelay.rel_value_us)
1663 LOG (GNUNET_ERROR_TYPE_WARNING,
1664 "CADET transmit ready timeout is deprected (has no effect)\n");
1667 th = GNUNET_new (struct GNUNET_CADET_TransmitHandle);
1668 th->channel = channel;
1669 th->size = notify_size;
1670 channel->packet_size = th->size;
1671 LOG (GNUNET_ERROR_TYPE_DEBUG, " total size %u\n", th->size);
1672 th->notify = notify;
1673 th->notify_cls = notify_cls;
1674 if (GNUNET_YES == channel->allow_send)
1675 th->request_data_task = GNUNET_SCHEDULER_add_now (&request_data, th);
1677 add_to_queue (channel->cadet, th);
1679 LOG (GNUNET_ERROR_TYPE_DEBUG, "CADET NOTIFY TRANSMIT READY END\n");
1685 GNUNET_CADET_notify_transmit_ready_cancel (struct GNUNET_CADET_TransmitHandle *th)
1687 if (NULL != th->request_data_task)
1689 GNUNET_SCHEDULER_cancel (th->request_data_task);
1691 th->request_data_task = NULL;
1693 remove_from_queue (th);
1699 GNUNET_CADET_receive_done (struct GNUNET_CADET_Channel *channel)
1706 send_info_request (struct GNUNET_CADET_Handle *h, uint16_t type)
1708 struct GNUNET_MessageHeader *msg;
1709 struct GNUNET_MQ_Envelope *env;
1711 LOG (GNUNET_ERROR_TYPE_DEBUG,
1712 " Sending %s monitor message to service\n",
1715 env = GNUNET_MQ_msg (msg, type);
1716 GNUNET_MQ_send (h->mq, env);
1721 * Request a debug dump on the service's STDERR.
1723 * WARNING: unstable API, likely to change in the future!
1725 * @param h cadet handle
1728 GNUNET_CADET_request_dump (struct GNUNET_CADET_Handle *h)
1730 LOG (GNUNET_ERROR_TYPE_DEBUG, "requesting dump\n");
1731 send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP);
1736 * Request information about peers known to the running cadet service.
1737 * The callback will be called for every peer known to the service.
1738 * Only one info request (of any kind) can be active at once.
1741 * WARNING: unstable API, likely to change in the future!
1743 * @param h Handle to the cadet peer.
1744 * @param callback Function to call with the requested data.
1745 * @param callback_cls Closure for @c callback.
1747 * @return #GNUNET_OK / #GNUNET_SYSERR
1750 GNUNET_CADET_get_peers (struct GNUNET_CADET_Handle *h,
1751 GNUNET_CADET_PeersCB callback,
1754 if (NULL != h->info_cb.peers_cb)
1757 return GNUNET_SYSERR;
1759 send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
1760 h->info_cb.peers_cb = callback;
1761 h->info_cls = callback_cls;
1767 * Cancel a peer info request. The callback will not be called (anymore).
1769 * WARNING: unstable API, likely to change in the future!
1771 * @param h Cadet handle.
1773 * @return Closure given to GNUNET_CADET_get_peers.
1776 GNUNET_CADET_get_peers_cancel (struct GNUNET_CADET_Handle *h)
1781 h->info_cb.peers_cb = NULL;
1788 * Request information about a peer known to the running cadet peer.
1789 * The callback will be called for the tunnel once.
1790 * Only one info request (of any kind) can be active at once.
1792 * WARNING: unstable API, likely to change in the future!
1794 * @param h Handle to the cadet peer.
1795 * @param id Peer whose tunnel to examine.
1796 * @param callback Function to call with the requested data.
1797 * @param callback_cls Closure for @c callback.
1799 * @return #GNUNET_OK / #GNUNET_SYSERR
1802 GNUNET_CADET_get_peer (struct GNUNET_CADET_Handle *h,
1803 const struct GNUNET_PeerIdentity *id,
1804 GNUNET_CADET_PeerCB callback,
1807 struct GNUNET_CADET_LocalInfo *msg;
1808 struct GNUNET_MQ_Envelope *env;
1810 if (NULL != h->info_cb.peer_cb)
1813 return GNUNET_SYSERR;
1816 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
1818 GNUNET_MQ_send (h->mq, env);
1820 h->info_cb.peer_cb = callback;
1821 h->info_cls = callback_cls;
1827 * Request information about tunnels of the running cadet peer.
1828 * The callback will be called for every tunnel of the service.
1829 * Only one info request (of any kind) can be active at once.
1831 * WARNING: unstable API, likely to change in the future!
1833 * @param h Handle to the cadet peer.
1834 * @param callback Function to call with the requested data.
1835 * @param callback_cls Closure for @c callback.
1837 * @return #GNUNET_OK / #GNUNET_SYSERR
1840 GNUNET_CADET_get_tunnels (struct GNUNET_CADET_Handle *h,
1841 GNUNET_CADET_TunnelsCB callback,
1844 if (NULL != h->info_cb.tunnels_cb)
1847 return GNUNET_SYSERR;
1849 send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
1850 h->info_cb.tunnels_cb = callback;
1851 h->info_cls = callback_cls;
1857 * Cancel a monitor request. The monitor callback will not be called.
1859 * @param h Cadet handle.
1861 * @return Closure given to GNUNET_CADET_get_tunnels.
1864 GNUNET_CADET_get_tunnels_cancel (struct GNUNET_CADET_Handle *h)
1868 h->info_cb.tunnels_cb = NULL;
1878 * Request information about a tunnel of the running cadet peer.
1879 * The callback will be called for the tunnel once.
1880 * Only one info request (of any kind) can be active at once.
1882 * WARNING: unstable API, likely to change in the future!
1884 * @param h Handle to the cadet peer.
1885 * @param id Peer whose tunnel to examine.
1886 * @param callback Function to call with the requested data.
1887 * @param callback_cls Closure for @c callback.
1889 * @return #GNUNET_OK / #GNUNET_SYSERR
1892 GNUNET_CADET_get_tunnel (struct GNUNET_CADET_Handle *h,
1893 const struct GNUNET_PeerIdentity *id,
1894 GNUNET_CADET_TunnelCB callback,
1897 struct GNUNET_CADET_LocalInfo *msg;
1898 struct GNUNET_MQ_Envelope *env;
1900 if (NULL != h->info_cb.tunnel_cb)
1903 return GNUNET_SYSERR;
1906 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
1908 GNUNET_MQ_send (h->mq, env);
1910 h->info_cb.tunnel_cb = callback;
1911 h->info_cls = callback_cls;
1917 * Request information about a specific channel of the running cadet peer.
1919 * WARNING: unstable API, likely to change in the future!
1920 * FIXME Add destination option.
1922 * @param h Handle to the cadet peer.
1923 * @param initiator ID of the owner of the channel.
1924 * @param channel_number Channel number.
1925 * @param callback Function to call with the requested data.
1926 * @param callback_cls Closure for @c callback.
1928 * @return #GNUNET_OK / #GNUNET_SYSERR
1931 GNUNET_CADET_show_channel (struct GNUNET_CADET_Handle *h,
1932 struct GNUNET_PeerIdentity *initiator,
1933 unsigned int channel_number,
1934 GNUNET_CADET_ChannelCB callback,
1937 struct GNUNET_CADET_LocalInfo *msg;
1938 struct GNUNET_MQ_Envelope *env;
1940 if (NULL != h->info_cb.channel_cb)
1943 return GNUNET_SYSERR;
1946 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL);
1947 msg->peer = *initiator;
1948 msg->channel_id = htonl (channel_number);
1949 GNUNET_MQ_send (h->mq, env);
1951 h->info_cb.channel_cb = callback;
1952 h->info_cls = callback_cls;
1958 * Function called to notify a client about the connection
1959 * begin ready to queue more data. "buf" will be
1960 * NULL and "size" zero if the connection was closed for
1961 * writing in the meantime.
1963 * @param cls closure
1964 * @param size number of bytes available in buf
1965 * @param buf where the callee should write the message
1966 * @return number of bytes written to buf
1969 cadet_mq_ntr (void *cls, size_t size,
1972 struct GNUNET_MQ_Handle *mq = cls;
1973 struct CadetMQState *state = GNUNET_MQ_impl_state (mq);
1974 const struct GNUNET_MessageHeader *msg = GNUNET_MQ_impl_current (mq);
1980 GNUNET_MQ_inject_error (mq, GNUNET_MQ_ERROR_WRITE);
1983 msize = ntohs (msg->size);
1984 GNUNET_assert (msize <= size);
1985 GNUNET_memcpy (buf, msg, msize);
1986 GNUNET_MQ_impl_send_continue (mq);
1992 * Signature of functions implementing the
1993 * sending functionality of a message queue.
1995 * @param mq the message queue
1996 * @param msg the message to send
1997 * @param impl_state state of the implementation
2000 cadet_mq_send_impl (struct GNUNET_MQ_Handle *mq,
2001 const struct GNUNET_MessageHeader *msg,
2004 struct CadetMQState *state = impl_state;
2006 GNUNET_assert (NULL == state->th);
2008 GNUNET_CADET_notify_transmit_ready (state->channel,
2009 /* FIXME: add option for corking */
2011 GNUNET_TIME_UNIT_FOREVER_REL,
2019 * Signature of functions implementing the
2020 * destruction of a message queue.
2021 * Implementations must not free 'mq', but should
2022 * take care of 'impl_state'.
2024 * @param mq the message queue to destroy
2025 * @param impl_state state of the implementation
2028 cadet_mq_destroy_impl (struct GNUNET_MQ_Handle *mq,
2031 struct CadetMQState *state = impl_state;
2033 if (NULL != state->th)
2034 GNUNET_CADET_notify_transmit_ready_cancel (state->th);
2036 GNUNET_free (state);
2041 * Create a message queue for a cadet channel.
2042 * The message queue can only be used to transmit messages,
2043 * not to receive them.
2045 * @param channel the channel to create the message qeue for
2046 * @return a message queue to messages over the channel
2048 struct GNUNET_MQ_Handle *
2049 GNUNET_CADET_mq_create (struct GNUNET_CADET_Channel *channel)
2051 struct GNUNET_MQ_Handle *mq;
2052 struct CadetMQState *state;
2054 state = GNUNET_new (struct CadetMQState);
2055 state->channel = channel;
2057 mq = GNUNET_MQ_queue_for_callbacks (&cadet_mq_send_impl,
2058 &cadet_mq_destroy_impl,
2059 NULL, /* FIXME: cancel impl. */
2061 NULL, /* no msg handlers */
2062 NULL, /* no err handlers */
2063 NULL); /* no handler cls */
2069 * Transitional function to convert an unsigned int port to a hash value.
2070 * WARNING: local static value returned, NOT reentrant!
2071 * WARNING: do not use this function for new code!
2073 * @param port Numerical port (unsigned int format).
2075 * @return A GNUNET_HashCode usable for the new CADET API.
2077 const struct GNUNET_HashCode *
2078 GC_u2h (uint32_t port)
2080 static struct GNUNET_HashCode hash;
2082 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2083 "This is a transitional function, "
2084 "use proper crypto hashes as CADET ports\n");
2085 GNUNET_CRYPTO_hash (&port, sizeof (port), &hash);