2 This file is part of GNUnet.
3 Copyright (C) 2018 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
22 * @file transport/transport_api2_communication.c
23 * @brief implementation of the gnunet_transport_communication_service.h API
24 * @author Christian Grothoff
27 #include "gnunet_util_lib.h"
28 #include "gnunet_protocols.h"
29 #include "gnunet_transport_communication_service.h"
30 #include "gnunet_ats_transport_service.h"
31 #include "transport.h"
35 * How many messages do we keep at most in the queue to the
36 * transport service before we start to drop (default,
37 * can be changed via the configuration file).
39 #define DEFAULT_MAX_QUEUE_LENGTH 16
43 * Information we track per packet to enable flow control.
50 struct FlowControl *next;
55 struct FlowControl *prev;
58 * Function to call once the message was processed.
60 GNUNET_TRANSPORT_MessageCompletedCallback cb;
68 * Which peer is this about?
70 struct GNUNET_PeerIdentity sender;
73 * More-or-less unique ID for the message.
80 * Information we track per message to tell the transport about
81 * success or failures.
88 struct AckPending *next;
93 struct AckPending *prev;
96 * Communicator this entry belongs to.
98 struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
101 * Which peer is this about?
103 struct GNUNET_PeerIdentity receiver;
106 * More-or-less unique ID for the message.
113 * Opaque handle to the transport service for communicators.
115 struct GNUNET_TRANSPORT_CommunicatorHandle
118 * Head of DLL of addresses this communicator offers to the transport service.
120 struct GNUNET_TRANSPORT_AddressIdentifier *ai_head;
123 * Tail of DLL of addresses this communicator offers to the transport service.
125 struct GNUNET_TRANSPORT_AddressIdentifier *ai_tail;
128 * DLL of messages awaiting flow control confirmation (ack).
130 struct FlowControl *fc_head;
133 * DLL of messages awaiting flow control confirmation (ack).
135 struct FlowControl *fc_tail;
138 * DLL of messages awaiting transmission confirmation (ack).
140 struct AckPending *ap_head;
143 * DLL of messages awaiting transmission confirmation (ack).
145 struct AckPending *ap_tail;
148 * DLL of queues we offer.
150 struct GNUNET_TRANSPORT_QueueHandle *queue_head;
153 * DLL of queues we offer.
155 struct GNUNET_TRANSPORT_QueueHandle *queue_tail;
160 const struct GNUNET_CONFIGURATION_Handle *cfg;
163 * Config section to use.
165 const char *config_section;
168 * Address prefix to use.
170 const char *addr_prefix;
173 * Function to call when the transport service wants us to initiate
174 * a communication channel with another peer.
176 GNUNET_TRANSPORT_CommunicatorMqInit mq_init;
179 * Closure for @e mq_init.
184 * Function to call when the transport service receives messages
185 * for a communicator (i.e. for NAT traversal or for non-bidirectional
188 GNUNET_TRANSPORT_CommunicatorNotify notify_cb;
191 * Closure for @e notify_Cb.
196 * Queue to talk to the transport service.
198 struct GNUNET_MQ_Handle *mq;
201 * Maximum permissable queue length.
203 unsigned long long max_queue_length;
206 * Flow-control identifier generator.
211 * Internal UUID for the address used in communication with the
217 * Queue identifier generator.
222 * Characteristics of the communicator.
224 enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc;
229 * Handle returned to identify the internal data structure the transport
230 * API has created to manage a message queue to a particular peer.
232 struct GNUNET_TRANSPORT_QueueHandle
238 struct GNUNET_TRANSPORT_QueueHandle *next;
243 struct GNUNET_TRANSPORT_QueueHandle *prev;
246 * Handle this queue belongs to.
248 struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
251 * Address used by the communication queue.
258 struct GNUNET_MQ_Handle *mq;
261 * Which peer we can communciate with.
263 struct GNUNET_PeerIdentity peer;
266 * Network type of the communciation queue.
268 enum GNUNET_NetworkType nt;
271 * Communication status of the queue.
273 enum GNUNET_TRANSPORT_ConnectionStatus cs;
276 * ID for this queue when talking to the transport service.
281 * Maximum transmission unit for the queue.
288 * Internal representation of an address a communicator is
289 * currently providing for the transport service.
291 struct GNUNET_TRANSPORT_AddressIdentifier
297 struct GNUNET_TRANSPORT_AddressIdentifier *next;
302 struct GNUNET_TRANSPORT_AddressIdentifier *prev;
305 * Transport handle where the address was added.
307 struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
310 * The actual address.
315 * When does the address expire? (Expected lifetime of the
318 struct GNUNET_TIME_Relative expiration;
321 * Internal UUID for the address used in communication with the
327 * Network type for the address.
329 enum GNUNET_NetworkType nt;
334 * (re)connect our communicator to the transport service
336 * @param ch handle to reconnect
339 reconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch);
343 * Send message to the transport service about address @a ai
344 * being now available.
346 * @param ai address to add
349 send_add_address (struct GNUNET_TRANSPORT_AddressIdentifier *ai)
351 struct GNUNET_MQ_Envelope *env;
352 struct GNUNET_TRANSPORT_AddAddressMessage *aam;
354 if (NULL == ai->ch->mq)
356 env = GNUNET_MQ_msg_extra (aam,
357 strlen (ai->address) + 1,
358 GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_ADDRESS);
359 aam->expiration = GNUNET_TIME_relative_hton (ai->expiration);
360 aam->nt = htonl ((uint32_t) ai->nt);
361 memcpy (&aam[1], ai->address, strlen (ai->address) + 1);
362 GNUNET_MQ_send (ai->ch->mq, env);
367 * Send message to the transport service about address @a ai
368 * being no longer available.
370 * @param ai address to delete
373 send_del_address (struct GNUNET_TRANSPORT_AddressIdentifier *ai)
375 struct GNUNET_MQ_Envelope *env;
376 struct GNUNET_TRANSPORT_DelAddressMessage *dam;
378 if (NULL == ai->ch->mq)
380 env = GNUNET_MQ_msg (dam, GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_ADDRESS);
381 dam->aid = htonl (ai->aid);
382 GNUNET_MQ_send (ai->ch->mq, env);
387 * Send message to the transport service about queue @a qh
388 * being now available.
390 * @param qh queue to add
393 send_add_queue (struct GNUNET_TRANSPORT_QueueHandle *qh)
395 struct GNUNET_MQ_Envelope *env;
396 struct GNUNET_TRANSPORT_AddQueueMessage *aqm;
398 if (NULL == qh->ch->mq)
400 env = GNUNET_MQ_msg_extra (aqm,
401 strlen (qh->address) + 1,
402 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_SETUP);
403 aqm->qid = htonl (qh->queue_id);
404 aqm->receiver = qh->peer;
405 aqm->nt = htonl ((uint32_t) qh->nt);
406 aqm->mtu = htonl (qh->mtu);
407 aqm->cs = htonl ((uint32_t) qh->cs);
408 memcpy (&aqm[1], qh->address, strlen (qh->address) + 1);
409 GNUNET_MQ_send (qh->ch->mq, env);
414 * Send message to the transport service about queue @a qh
415 * being no longer available.
417 * @param qh queue to delete
420 send_del_queue (struct GNUNET_TRANSPORT_QueueHandle *qh)
422 struct GNUNET_MQ_Envelope *env;
423 struct GNUNET_TRANSPORT_DelQueueMessage *dqm;
425 if (NULL == qh->ch->mq)
427 env = GNUNET_MQ_msg (dqm, GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_TEARDOWN);
428 dqm->qid = htonl (qh->queue_id);
429 dqm->receiver = qh->peer;
430 GNUNET_MQ_send (qh->ch->mq, env);
435 * Disconnect from the transport service. Purges
436 * all flow control entries as we will no longer receive
437 * the ACKs. Purges the ack pending entries as the
438 * transport will no longer expect the confirmations.
440 * @param ch service to disconnect from
443 disconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
445 struct FlowControl *fcn;
446 struct AckPending *apn;
448 for (struct FlowControl *fc = ch->fc_head; NULL != fc; fc = fcn)
451 GNUNET_CONTAINER_DLL_remove (ch->fc_head, ch->fc_tail, fc);
452 fc->cb (fc->cb_cls, GNUNET_SYSERR);
455 for (struct AckPending *ap = ch->ap_head; NULL != ap; ap = apn)
458 GNUNET_CONTAINER_DLL_remove (ch->ap_head, ch->ap_tail, ap);
463 GNUNET_MQ_destroy (ch->mq);
469 * Function called on MQ errors.
472 error_handler (void *cls, enum GNUNET_MQ_Error error)
474 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
476 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
477 "MQ failure %d, reconnecting to transport service.\n",
480 /* TODO: maybe do this with exponential backoff/delay */
486 * Transport service acknowledged a message we gave it
487 * (with flow control enabled). Tell the communicator.
489 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
490 * @param incoming_ack the ack
493 handle_incoming_ack (
495 const struct GNUNET_TRANSPORT_IncomingMessageAck *incoming_ack)
497 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
499 for (struct FlowControl *fc = ch->fc_head; NULL != fc; fc = fc->next)
501 if ((fc->id == incoming_ack->fc_id) &&
502 (0 == memcmp (&fc->sender,
503 &incoming_ack->sender,
504 sizeof (struct GNUNET_PeerIdentity))))
506 GNUNET_CONTAINER_DLL_remove (ch->fc_head, ch->fc_tail, fc);
507 fc->cb (fc->cb_cls, GNUNET_OK);
514 /* TODO: maybe do this with exponential backoff/delay */
520 * Transport service wants us to create a queue. Check if @a cq
523 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
524 * @param cq the queue creation request
525 * @return #GNUNET_OK if @a smt is well-formed
528 check_create_queue (void *cls, const struct GNUNET_TRANSPORT_CreateQueue *cq)
531 GNUNET_MQ_check_zero_termination (cq);
537 * Transport service wants us to create a queue. Tell the communicator.
539 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
540 * @param cq the queue creation request
543 handle_create_queue (void *cls, const struct GNUNET_TRANSPORT_CreateQueue *cq)
545 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
546 const char *addr = (const char *) &cq[1];
547 struct GNUNET_TRANSPORT_CreateQueueResponse *cqr;
548 struct GNUNET_MQ_Envelope *env;
550 if (GNUNET_OK != ch->mq_init (ch->mq_init_cls, &cq->receiver, addr))
552 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
553 "Address `%s' invalid for this communicator\n",
555 env = GNUNET_MQ_msg (cqr, GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_FAIL);
559 env = GNUNET_MQ_msg (cqr, GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_OK);
561 cqr->request_id = cq->request_id;
562 GNUNET_MQ_send (ch->mq, env);
567 * Transport service wants us to send a message. Check if @a smt
570 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
571 * @param smt the transmission request
572 * @return #GNUNET_OK if @a smt is well-formed
575 check_send_msg (void *cls, const struct GNUNET_TRANSPORT_SendMessageTo *smt)
578 GNUNET_MQ_check_boxed_message (smt);
584 * Notify transport service about @a status of a message with
585 * @a mid sent to @a receiver.
588 * @param status #GNUNET_OK on success, #GNUNET_SYSERR on failure
589 * @param receiver which peer was the receiver
590 * @param mid message that the ack is about
593 send_ack (struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
595 const struct GNUNET_PeerIdentity *receiver,
598 struct GNUNET_MQ_Envelope *env;
599 struct GNUNET_TRANSPORT_SendMessageToAck *ack;
601 env = GNUNET_MQ_msg (ack, GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG_ACK);
602 ack->status = htonl (status);
604 ack->receiver = *receiver;
605 GNUNET_MQ_send (ch->mq, env);
610 * Message queue transmission by communicator was successful,
611 * notify transport service.
613 * @param cls an `struct AckPending *`
616 send_ack_cb (void *cls)
618 struct AckPending *ap = cls;
619 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = ap->ch;
621 GNUNET_CONTAINER_DLL_remove (ch->ap_head, ch->ap_tail, ap);
622 send_ack (ch, GNUNET_OK, &ap->receiver, ap->mid);
628 * Transport service wants us to send a message. Tell the communicator.
630 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
631 * @param smt the transmission request
634 handle_send_msg (void *cls, const struct GNUNET_TRANSPORT_SendMessageTo *smt)
636 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
637 const struct GNUNET_MessageHeader *mh;
638 struct GNUNET_MQ_Envelope *env;
639 struct AckPending *ap;
640 struct GNUNET_TRANSPORT_QueueHandle *qh;
642 for (qh = ch->queue_head; NULL != qh; qh = qh->next)
643 if ((qh->queue_id == smt->qid) &&
644 (0 == memcmp (&qh->peer,
646 sizeof (struct GNUNET_PeerIdentity))))
650 /* queue is already gone, tell transport this one failed */
651 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
652 "Transmission failed, queue no longer exists.\n");
653 send_ack (ch, GNUNET_NO, &smt->receiver, smt->mid);
656 ap = GNUNET_new (struct AckPending);
658 ap->receiver = smt->receiver;
660 GNUNET_CONTAINER_DLL_insert (ch->ap_head, ch->ap_tail, ap);
661 mh = (const struct GNUNET_MessageHeader *) &smt[1];
662 env = GNUNET_MQ_msg_copy (mh);
663 GNUNET_MQ_notify_sent (env, &send_ack_cb, ap);
664 GNUNET_MQ_send (qh->mq, env);
669 * Transport service gives us backchannel message. Check if @a bi
672 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
673 * @param bi the backchannel message
674 * @return #GNUNET_OK if @a smt is well-formed
677 check_backchannel_incoming (
679 const struct GNUNET_TRANSPORT_CommunicatorBackchannelIncoming *bi)
682 GNUNET_MQ_check_boxed_message (bi);
688 * Transport service gives us backchannel message. Handle it.
690 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
691 * @param bi the backchannel message
694 handle_backchannel_incoming (
696 const struct GNUNET_TRANSPORT_CommunicatorBackchannelIncoming *bi)
698 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
700 if (NULL != ch->notify_cb)
701 ch->notify_cb (ch->notify_cb_cls,
703 (const struct GNUNET_MessageHeader *) &bi[1]);
706 GNUNET_ERROR_TYPE_INFO,
707 _ ("Dropped backchanel message: handler not provided by communicator\n"));
712 * (re)connect our communicator to the transport service
714 * @param ch handle to reconnect
717 reconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
719 struct GNUNET_MQ_MessageHandler handlers[] =
720 {GNUNET_MQ_hd_fixed_size (incoming_ack,
721 GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG_ACK,
722 struct GNUNET_TRANSPORT_IncomingMessageAck,
724 GNUNET_MQ_hd_var_size (create_queue,
725 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE,
726 struct GNUNET_TRANSPORT_CreateQueue,
728 GNUNET_MQ_hd_var_size (send_msg,
729 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG,
730 struct GNUNET_TRANSPORT_SendMessageTo,
732 GNUNET_MQ_hd_var_size (
733 backchannel_incoming,
734 GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL_INCOMING,
735 struct GNUNET_TRANSPORT_CommunicatorBackchannelIncoming,
737 GNUNET_MQ_handler_end ()};
738 struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam;
739 struct GNUNET_MQ_Envelope *env;
742 GNUNET_CLIENT_connect (ch->cfg, "transport", handlers, &error_handler, ch);
745 env = GNUNET_MQ_msg_extra (cam,
746 strlen (ch->addr_prefix) + 1,
747 GNUNET_MESSAGE_TYPE_TRANSPORT_NEW_COMMUNICATOR);
748 cam->cc = htonl ((uint32_t) ch->cc);
749 memcpy (&cam[1], ch->addr_prefix, strlen (ch->addr_prefix) + 1);
750 GNUNET_MQ_send (ch->mq, env);
751 for (struct GNUNET_TRANSPORT_AddressIdentifier *ai = ch->ai_head; NULL != ai;
753 send_add_address (ai);
754 for (struct GNUNET_TRANSPORT_QueueHandle *qh = ch->queue_head; NULL != qh;
761 * Connect to the transport service.
763 * @param cfg configuration to use
764 * @param config_section section of the configuration to use for options
765 * @param addr_prefix address prefix for addresses supported by this
766 * communicator, could be NULL for incoming-only communicators
767 * @param cc what characteristics does the communicator have?
768 * @param mtu maximum message size supported by communicator, 0 if
769 * sending is not supported, SIZE_MAX for no MTU
770 * @param mq_init function to call to initialize a message queue given
771 * the address of another peer, can be NULL if the
772 * communicator only supports receiving messages
773 * @param mq_init_cls closure for @a mq_init
774 * @param notify_cb function to pass backchannel messages to communicator
775 * @param notify_cb_cls closure for @a notify_cb
776 * @return NULL on error
778 struct GNUNET_TRANSPORT_CommunicatorHandle *
779 GNUNET_TRANSPORT_communicator_connect (
780 const struct GNUNET_CONFIGURATION_Handle *cfg,
781 const char *config_section,
782 const char *addr_prefix,
783 enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc,
784 GNUNET_TRANSPORT_CommunicatorMqInit mq_init,
786 GNUNET_TRANSPORT_CommunicatorNotify notify_cb,
789 struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
791 ch = GNUNET_new (struct GNUNET_TRANSPORT_CommunicatorHandle);
793 ch->config_section = config_section;
794 ch->addr_prefix = addr_prefix;
795 ch->mq_init = mq_init;
796 ch->mq_init_cls = mq_init_cls;
797 ch->notify_cb = notify_cb;
798 ch->notify_cb_cls = notify_cb_cls;
802 GNUNET_CONFIGURATION_get_value_number (cfg,
805 &ch->max_queue_length))
806 ch->max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
817 * Disconnect from the transport service.
819 * @param ch handle returned from connect
822 GNUNET_TRANSPORT_communicator_disconnect (
823 struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
826 while (NULL != ch->ai_head)
828 GNUNET_break (0); /* communicator forgot to remove address, warn! */
829 GNUNET_TRANSPORT_communicator_address_remove (ch->ai_head);
835 /* ************************* Receiving *************************** */
839 * Notify transport service that the communicator has received
842 * @param ch connection to transport service
843 * @param sender presumed sender of the message (details to be checked
845 * @param msg the message
846 * @param expected_addr_validity how long does the communicator believe it
847 * will continue to be able to receive messages from the same address
848 * on which it received this message?
849 * @param cb function to call once handling the message is done, NULL if
850 * flow control is not supported by this communicator
851 * @param cb_cls closure for @a cb
852 * @return #GNUNET_OK if all is well, #GNUNET_NO if the message was
853 * immediately dropped due to memory limitations (communicator
854 * should try to apply back pressure),
855 * #GNUNET_SYSERR if the message could not be delivered because
856 * the tranport service is not yet up
859 GNUNET_TRANSPORT_communicator_receive (
860 struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
861 const struct GNUNET_PeerIdentity *sender,
862 const struct GNUNET_MessageHeader *msg,
863 struct GNUNET_TIME_Relative expected_addr_validity,
864 GNUNET_TRANSPORT_MessageCompletedCallback cb,
867 struct GNUNET_MQ_Envelope *env;
868 struct GNUNET_TRANSPORT_IncomingMessage *im;
872 return GNUNET_SYSERR;
873 if ((NULL == cb) && (GNUNET_MQ_get_length (ch->mq) >= ch->max_queue_length))
876 GNUNET_ERROR_TYPE_WARNING,
877 "Dropping message: transprot is too slow, queue length %llu exceeded\n",
878 ch->max_queue_length);
882 msize = ntohs (msg->size);
884 GNUNET_MQ_msg_extra (im, msize, GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG);
888 return GNUNET_SYSERR;
890 im->expected_address_validity =
891 GNUNET_TIME_relative_hton (expected_addr_validity);
892 im->sender = *sender;
893 memcpy (&im[1], msg, msize);
896 struct FlowControl *fc;
898 im->fc_on = htonl (GNUNET_YES);
899 im->fc_id = ch->fc_gen++;
900 fc = GNUNET_new (struct FlowControl);
901 fc->sender = *sender;
905 GNUNET_CONTAINER_DLL_insert (ch->fc_head, ch->fc_tail, fc);
907 GNUNET_MQ_send (ch->mq, env);
912 /* ************************* Discovery *************************** */
916 * Notify transport service that an MQ became available due to an
917 * "inbound" connection or because the communicator discovered the
918 * presence of another peer.
920 * @param ch connection to transport service
921 * @param peer peer with which we can now communicate
922 * @param address address in human-readable format, 0-terminated, UTF-8
923 * @param mtu maximum message size supported by queue, 0 if
924 * sending is not supported, SIZE_MAX for no MTU
925 * @param nt which network type does the @a address belong to?
926 * @param cc what characteristics does the communicator have?
927 * @param cs what is the connection status of the queue?
928 * @param mq message queue of the @a peer
929 * @return API handle identifying the new MQ
931 struct GNUNET_TRANSPORT_QueueHandle *
932 GNUNET_TRANSPORT_communicator_mq_add (
933 struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
934 const struct GNUNET_PeerIdentity *peer,
937 enum GNUNET_NetworkType nt,
938 enum GNUNET_TRANSPORT_ConnectionStatus cs,
939 struct GNUNET_MQ_Handle *mq)
941 struct GNUNET_TRANSPORT_QueueHandle *qh;
943 qh = GNUNET_new (struct GNUNET_TRANSPORT_QueueHandle);
946 qh->address = GNUNET_strdup (address);
951 qh->queue_id = ch->queue_gen++;
952 GNUNET_CONTAINER_DLL_insert (ch->queue_head, ch->queue_tail, qh);
959 * Notify transport service that an MQ became unavailable due to a
960 * disconnect or timeout.
962 * @param qh handle for the queue that must be invalidated
965 GNUNET_TRANSPORT_communicator_mq_del (struct GNUNET_TRANSPORT_QueueHandle *qh)
967 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = qh->ch;
970 GNUNET_CONTAINER_DLL_remove (ch->queue_head, ch->queue_tail, qh);
971 GNUNET_MQ_destroy (qh->mq);
972 GNUNET_free (qh->address);
978 * Notify transport service about an address that this communicator
979 * provides for this peer.
981 * @param ch connection to transport service
982 * @param address our address in human-readable format, 0-terminated, UTF-8
983 * @param nt which network type does the address belong to?
984 * @param expiration when does the communicator forsee this address expiring?
986 struct GNUNET_TRANSPORT_AddressIdentifier *
987 GNUNET_TRANSPORT_communicator_address_add (
988 struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
990 enum GNUNET_NetworkType nt,
991 struct GNUNET_TIME_Relative expiration)
993 struct GNUNET_TRANSPORT_AddressIdentifier *ai;
995 ai = GNUNET_new (struct GNUNET_TRANSPORT_AddressIdentifier);
997 ai->address = GNUNET_strdup (address);
999 ai->expiration = expiration;
1000 ai->aid = ch->aid_gen++;
1001 GNUNET_CONTAINER_DLL_insert (ch->ai_head, ch->ai_tail, ai);
1002 send_add_address (ai);
1008 * Notify transport service about an address that this communicator no
1009 * longer provides for this peer.
1011 * @param ai address that is no longer provided
1014 GNUNET_TRANSPORT_communicator_address_remove (
1015 struct GNUNET_TRANSPORT_AddressIdentifier *ai)
1017 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = ai->ch;
1019 send_del_address (ai);
1020 GNUNET_CONTAINER_DLL_remove (ch->ai_head, ch->ai_tail, ai);
1021 GNUNET_free (ai->address);
1026 /* ************************* Backchannel *************************** */
1030 * The communicator asks the transport service to route a message via
1031 * a different path to another communicator service at another peer.
1032 * This must only be done for special control traffic (as there is no
1033 * flow control for this API), such as acknowledgements, and generally
1034 * only be done if the communicator is uni-directional (i.e. cannot
1035 * send the message back itself).
1037 * @param ch handle of this communicator
1038 * @param pid peer to send the message to
1039 * @param comm name of the communicator to send the message to
1040 * @param header header of the message to transmit and pass via the
1041 * notify-API to @a pid's communicator @a comm
1044 GNUNET_TRANSPORT_communicator_notify (
1045 struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
1046 const struct GNUNET_PeerIdentity *pid,
1048 const struct GNUNET_MessageHeader *header)
1050 struct GNUNET_MQ_Envelope *env;
1051 struct GNUNET_TRANSPORT_CommunicatorBackchannel *cb;
1052 size_t slen = strlen (comm) + 1;
1053 uint16_t mlen = ntohs (header->size);
1055 GNUNET_assert (mlen + slen + sizeof (*cb) < UINT16_MAX);
1057 GNUNET_MQ_msg_extra (cb,
1059 GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL);
1061 memcpy (&cb[1], header, mlen);
1062 memcpy (((char *) &cb[1]) + mlen, comm, slen);
1063 GNUNET_MQ_send (ch->mq, env);
1067 /* end of transport_api2_communication.c */