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;
230 * Handle returned to identify the internal data structure the transport
231 * API has created to manage a message queue to a particular peer.
233 struct GNUNET_TRANSPORT_QueueHandle
239 struct GNUNET_TRANSPORT_QueueHandle *next;
244 struct GNUNET_TRANSPORT_QueueHandle *prev;
247 * Handle this queue belongs to.
249 struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
252 * Address used by the communication queue.
259 struct GNUNET_MQ_Handle *mq;
262 * Which peer we can communciate with.
264 struct GNUNET_PeerIdentity peer;
267 * Network type of the communciation queue.
269 enum GNUNET_NetworkType nt;
272 * Communication status of the queue.
274 enum GNUNET_TRANSPORT_ConnectionStatus cs;
277 * ID for this queue when talking to the transport service.
282 * Maximum transmission unit for the queue.
290 * Internal representation of an address a communicator is
291 * currently providing for the transport service.
293 struct GNUNET_TRANSPORT_AddressIdentifier
299 struct GNUNET_TRANSPORT_AddressIdentifier *next;
304 struct GNUNET_TRANSPORT_AddressIdentifier *prev;
307 * Transport handle where the address was added.
309 struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
312 * The actual address.
317 * When does the address expire? (Expected lifetime of the
320 struct GNUNET_TIME_Relative expiration;
323 * Internal UUID for the address used in communication with the
329 * Network type for the address.
331 enum GNUNET_NetworkType nt;
337 * (re)connect our communicator to the transport service
339 * @param ch handle to reconnect
342 reconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch);
346 * Send message to the transport service about address @a ai
347 * being now available.
349 * @param ai address to add
352 send_add_address (struct GNUNET_TRANSPORT_AddressIdentifier *ai)
354 struct GNUNET_MQ_Envelope *env;
355 struct GNUNET_TRANSPORT_AddAddressMessage *aam;
357 if (NULL == ai->ch->mq)
359 env = GNUNET_MQ_msg_extra (aam,
360 strlen (ai->address) + 1,
361 GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_ADDRESS);
362 aam->expiration = GNUNET_TIME_relative_hton (ai->expiration);
363 aam->nt = htonl ((uint32_t) ai->nt);
366 strlen (ai->address) + 1);
367 GNUNET_MQ_send (ai->ch->mq,
373 * Send message to the transport service about address @a ai
374 * being no longer available.
376 * @param ai address to delete
379 send_del_address (struct GNUNET_TRANSPORT_AddressIdentifier *ai)
381 struct GNUNET_MQ_Envelope *env;
382 struct GNUNET_TRANSPORT_DelAddressMessage *dam;
384 if (NULL == ai->ch->mq)
386 env = GNUNET_MQ_msg (dam,
387 GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_ADDRESS);
388 dam->aid = htonl (ai->aid);
389 GNUNET_MQ_send (ai->ch->mq,
395 * Send message to the transport service about queue @a qh
396 * being now available.
398 * @param qh queue to add
401 send_add_queue (struct GNUNET_TRANSPORT_QueueHandle *qh)
403 struct GNUNET_MQ_Envelope *env;
404 struct GNUNET_TRANSPORT_AddQueueMessage *aqm;
406 if (NULL == qh->ch->mq)
408 env = GNUNET_MQ_msg_extra (aqm,
409 strlen (qh->address) + 1,
410 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_SETUP);
411 aqm->qid = htonl (qh->queue_id);
412 aqm->receiver = qh->peer;
413 aqm->nt = htonl ((uint32_t) qh->nt);
414 aqm->mtu = htonl (qh->mtu);
415 aqm->cs = htonl ((uint32_t) qh->cs);
418 strlen (qh->address) + 1);
419 GNUNET_MQ_send (qh->ch->mq,
425 * Send message to the transport service about queue @a qh
426 * being no longer available.
428 * @param qh queue to delete
431 send_del_queue (struct GNUNET_TRANSPORT_QueueHandle *qh)
433 struct GNUNET_MQ_Envelope *env;
434 struct GNUNET_TRANSPORT_DelQueueMessage *dqm;
436 if (NULL == qh->ch->mq)
438 env = GNUNET_MQ_msg (dqm,
439 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_TEARDOWN);
440 dqm->qid = htonl (qh->queue_id);
441 dqm->receiver = qh->peer;
442 GNUNET_MQ_send (qh->ch->mq,
448 * Disconnect from the transport service. Purges
449 * all flow control entries as we will no longer receive
450 * the ACKs. Purges the ack pending entries as the
451 * transport will no longer expect the confirmations.
453 * @param ch service to disconnect from
456 disconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
458 struct FlowControl *fcn;
459 struct AckPending *apn;
461 for (struct FlowControl *fc = ch->fc_head;
466 GNUNET_CONTAINER_DLL_remove (ch->fc_head,
473 for (struct AckPending *ap = ch->ap_head;
478 GNUNET_CONTAINER_DLL_remove (ch->ap_head,
485 GNUNET_MQ_destroy (ch->mq);
491 * Function called on MQ errors.
494 error_handler (void *cls,
495 enum GNUNET_MQ_Error error)
497 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
499 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
500 "MQ failure %d, reconnecting to transport service.\n",
503 /* TODO: maybe do this with exponential backoff/delay */
509 * Transport service acknowledged a message we gave it
510 * (with flow control enabled). Tell the communicator.
512 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
513 * @param incoming_ack the ack
516 handle_incoming_ack (void *cls,
517 const struct GNUNET_TRANSPORT_IncomingMessageAck *incoming_ack)
519 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
521 for (struct FlowControl *fc = ch->fc_head;
525 if ( (fc->id == incoming_ack->fc_id) &&
526 (0 == memcmp (&fc->sender,
527 &incoming_ack->sender,
528 sizeof (struct GNUNET_PeerIdentity))) )
530 GNUNET_CONTAINER_DLL_remove (ch->fc_head,
541 /* TODO: maybe do this with exponential backoff/delay */
547 * Transport service wants us to create a queue. Check if @a cq
550 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
551 * @param cq the queue creation request
552 * @return #GNUNET_OK if @a smt is well-formed
555 check_create_queue (void *cls,
556 const struct GNUNET_TRANSPORT_CreateQueue *cq)
558 uint16_t len = ntohs (cq->header.size) - sizeof (*cq);
559 const char *addr = (const char *) &cq[1];
563 ('\0' != addr[len-1]) )
566 return GNUNET_SYSERR;
573 * Transport service wants us to create a queue. Tell the communicator.
575 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
576 * @param cq the queue creation request
579 handle_create_queue (void *cls,
580 const struct GNUNET_TRANSPORT_CreateQueue *cq)
582 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
583 const char *addr = (const char *) &cq[1];
584 struct GNUNET_TRANSPORT_CreateQueueResponse *cqr;
585 struct GNUNET_MQ_Envelope *env;
588 ch->mq_init (ch->mq_init_cls,
592 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
593 "Address `%s' invalid for this communicator\n",
595 env = GNUNET_MQ_msg (cqr,
596 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_FAIL);
600 env = GNUNET_MQ_msg (cqr,
601 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_OK);
603 cqr->request_id = cq->request_id;
604 GNUNET_MQ_send (ch->mq,
610 * Transport service wants us to send a message. Check if @a smt
613 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
614 * @param smt the transmission request
615 * @return #GNUNET_OK if @a smt is well-formed
618 check_send_msg (void *cls,
619 const struct GNUNET_TRANSPORT_SendMessageTo *smt)
622 GNUNET_MQ_check_boxed_message (smt);
628 * Notify transport service about @a status of a message with
629 * @a mid sent to @a receiver.
632 * @param status #GNUNET_OK on success, #GNUNET_SYSERR on failure
633 * @param receiver which peer was the receiver
634 * @param mid message that the ack is about
637 send_ack (struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
639 const struct GNUNET_PeerIdentity *receiver,
642 struct GNUNET_MQ_Envelope *env;
643 struct GNUNET_TRANSPORT_SendMessageToAck *ack;
645 env = GNUNET_MQ_msg (ack,
646 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG_ACK);
647 ack->status = htonl (status);
649 ack->receiver = *receiver;
650 GNUNET_MQ_send (ch->mq,
656 * Message queue transmission by communicator was successful,
657 * notify transport service.
659 * @param cls an `struct AckPending *`
662 send_ack_cb (void *cls)
664 struct AckPending *ap = cls;
665 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = ap->ch;
667 GNUNET_CONTAINER_DLL_remove (ch->ap_head,
679 * Transport service wants us to send a message. Tell the communicator.
681 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
682 * @param smt the transmission request
685 handle_send_msg (void *cls,
686 const struct GNUNET_TRANSPORT_SendMessageTo *smt)
688 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
689 const struct GNUNET_MessageHeader *mh;
690 struct GNUNET_MQ_Envelope *env;
691 struct AckPending *ap;
692 struct GNUNET_TRANSPORT_QueueHandle *qh;
694 for (qh = ch->queue_head;NULL != qh; qh = qh->next)
695 if ( (qh->queue_id == smt->qid) &&
696 (0 == memcmp (&qh->peer,
698 sizeof (struct GNUNET_PeerIdentity))) )
702 /* queue is already gone, tell transport this one failed */
703 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
704 "Transmission failed, queue no longer exists.\n");
711 ap = GNUNET_new (struct AckPending);
713 ap->receiver = smt->receiver;
715 GNUNET_CONTAINER_DLL_insert (ch->ap_head,
718 mh = (const struct GNUNET_MessageHeader *) &smt[1];
719 env = GNUNET_MQ_msg_copy (mh);
720 GNUNET_MQ_notify_sent (env,
723 GNUNET_MQ_send (qh->mq,
729 * Transport service gives us backchannel message. Check if @a bi
732 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
733 * @param bi the backchannel message
734 * @return #GNUNET_OK if @a smt is well-formed
737 check_backchannel_incoming (void *cls,
738 const struct GNUNET_TRANSPORT_CommunicatorBackchannelIncoming *bi)
741 GNUNET_MQ_check_boxed_message (bi);
747 * Transport service gives us backchannel message. Handle it.
749 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
750 * @param bi the backchannel message
753 handle_backchannel_incoming (void *cls,
754 const struct GNUNET_TRANSPORT_CommunicatorBackchannelIncoming *bi)
756 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
758 if (NULL != ch->notify_cb)
759 ch->notify_cb (ch->notify_cb_cls,
761 (const struct GNUNET_MessageHeader *) &bi[1]);
763 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
764 _("Dropped backchanel message: handler not provided by communicator\n"));
769 * (re)connect our communicator to the transport service
771 * @param ch handle to reconnect
774 reconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
776 struct GNUNET_MQ_MessageHandler handlers[] = {
777 GNUNET_MQ_hd_fixed_size (incoming_ack,
778 GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG_ACK,
779 struct GNUNET_TRANSPORT_IncomingMessageAck,
781 GNUNET_MQ_hd_var_size (create_queue,
782 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE,
783 struct GNUNET_TRANSPORT_CreateQueue,
785 GNUNET_MQ_hd_var_size (send_msg,
786 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG,
787 struct GNUNET_TRANSPORT_SendMessageTo,
789 GNUNET_MQ_hd_var_size (backchannel_incoming,
790 GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL_INCOMING,
791 struct GNUNET_TRANSPORT_CommunicatorBackchannelIncoming,
793 GNUNET_MQ_handler_end()
795 struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam;
796 struct GNUNET_MQ_Envelope *env;
798 ch->mq = GNUNET_CLIENT_connect (ch->cfg,
805 env = GNUNET_MQ_msg_extra (cam,
806 strlen (ch->addr_prefix) + 1,
807 GNUNET_MESSAGE_TYPE_TRANSPORT_NEW_COMMUNICATOR);
808 cam->cc = htonl ((uint32_t) ch->cc);
811 strlen (ch->addr_prefix) + 1);
812 GNUNET_MQ_send (ch->mq,
814 for (struct GNUNET_TRANSPORT_AddressIdentifier *ai = ch->ai_head;
817 send_add_address (ai);
818 for (struct GNUNET_TRANSPORT_QueueHandle *qh = ch->queue_head;
826 * Connect to the transport service.
828 * @param cfg configuration to use
829 * @param config_section section of the configuration to use for options
830 * @param addr_prefix address prefix for addresses supported by this
831 * communicator, could be NULL for incoming-only communicators
832 * @param cc what characteristics does the communicator have?
833 * @param mtu maximum message size supported by communicator, 0 if
834 * sending is not supported, SIZE_MAX for no MTU
835 * @param mq_init function to call to initialize a message queue given
836 * the address of another peer, can be NULL if the
837 * communicator only supports receiving messages
838 * @param mq_init_cls closure for @a mq_init
839 * @param notify_cb function to pass backchannel messages to communicator
840 * @param notify_cb_cls closure for @a notify_cb
841 * @return NULL on error
843 struct GNUNET_TRANSPORT_CommunicatorHandle *
844 GNUNET_TRANSPORT_communicator_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
845 const char *config_section,
846 const char *addr_prefix,
847 enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc,
848 GNUNET_TRANSPORT_CommunicatorMqInit mq_init,
850 GNUNET_TRANSPORT_CommunicatorNotify notify_cb,
853 struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
855 ch = GNUNET_new (struct GNUNET_TRANSPORT_CommunicatorHandle);
857 ch->config_section = config_section;
858 ch->addr_prefix = addr_prefix;
859 ch->mq_init = mq_init;
860 ch->mq_init_cls = mq_init_cls;
861 ch->notify_cb = notify_cb;
862 ch->notify_cb_cls = notify_cb_cls;
866 GNUNET_CONFIGURATION_get_value_number (cfg,
869 &ch->max_queue_length))
870 ch->max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
881 * Disconnect from the transport service.
883 * @param ch handle returned from connect
886 GNUNET_TRANSPORT_communicator_disconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
889 while (NULL != ch->ai_head)
891 GNUNET_break (0); /* communicator forgot to remove address, warn! */
892 GNUNET_TRANSPORT_communicator_address_remove (ch->ai_head);
898 /* ************************* Receiving *************************** */
902 * Notify transport service that the communicator has received
905 * @param ch connection to transport service
906 * @param sender presumed sender of the message (details to be checked
908 * @param msg the message
909 * @param expected_addr_validity how long does the communicator believe it
910 * will continue to be able to receive messages from the same address
911 * on which it received this message?
912 * @param cb function to call once handling the message is done, NULL if
913 * flow control is not supported by this communicator
914 * @param cb_cls closure for @a cb
915 * @return #GNUNET_OK if all is well, #GNUNET_NO if the message was
916 * immediately dropped due to memory limitations (communicator
917 * should try to apply back pressure),
918 * #GNUNET_SYSERR if the message could not be delivered because
919 * the tranport service is not yet up
922 GNUNET_TRANSPORT_communicator_receive (struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
923 const struct GNUNET_PeerIdentity *sender,
924 const struct GNUNET_MessageHeader *msg,
925 struct GNUNET_TIME_Relative expected_addr_validity,
926 GNUNET_TRANSPORT_MessageCompletedCallback cb,
929 struct GNUNET_MQ_Envelope *env;
930 struct GNUNET_TRANSPORT_IncomingMessage *im;
934 return GNUNET_SYSERR;
936 (GNUNET_MQ_get_length (ch->mq) >= ch->max_queue_length) )
938 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
939 "Dropping message: transprot is too slow, queue length %llu exceeded\n",
940 ch->max_queue_length);
944 msize = ntohs (msg->size);
945 env = GNUNET_MQ_msg_extra (im,
947 GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG);
951 return GNUNET_SYSERR;
953 im->expected_address_validity = GNUNET_TIME_relative_hton (expected_addr_validity);
954 im->sender = *sender;
960 struct FlowControl *fc;
962 im->fc_on = htonl (GNUNET_YES);
963 im->fc_id = ch->fc_gen++;
964 fc = GNUNET_new (struct FlowControl);
965 fc->sender = *sender;
969 GNUNET_CONTAINER_DLL_insert (ch->fc_head,
973 GNUNET_MQ_send (ch->mq,
979 /* ************************* Discovery *************************** */
983 * Notify transport service that an MQ became available due to an
984 * "inbound" connection or because the communicator discovered the
985 * presence of another peer.
987 * @param ch connection to transport service
988 * @param peer peer with which we can now communicate
989 * @param address address in human-readable format, 0-terminated, UTF-8
990 * @param mtu maximum message size supported by queue, 0 if
991 * sending is not supported, SIZE_MAX for no MTU
992 * @param nt which network type does the @a address belong to?
993 * @param cc what characteristics does the communicator have?
994 * @param cs what is the connection status of the queue?
995 * @param mq message queue of the @a peer
996 * @return API handle identifying the new MQ
998 struct GNUNET_TRANSPORT_QueueHandle *
999 GNUNET_TRANSPORT_communicator_mq_add (struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
1000 const struct GNUNET_PeerIdentity *peer,
1001 const char *address,
1003 enum GNUNET_NetworkType nt,
1004 enum GNUNET_TRANSPORT_ConnectionStatus cs,
1005 struct GNUNET_MQ_Handle *mq)
1007 struct GNUNET_TRANSPORT_QueueHandle *qh;
1009 qh = GNUNET_new (struct GNUNET_TRANSPORT_QueueHandle);
1012 qh->address = GNUNET_strdup (address);
1017 qh->queue_id = ch->queue_gen++;
1018 GNUNET_CONTAINER_DLL_insert (ch->queue_head,
1021 send_add_queue (qh);
1027 * Notify transport service that an MQ became unavailable due to a
1028 * disconnect or timeout.
1030 * @param qh handle for the queue that must be invalidated
1033 GNUNET_TRANSPORT_communicator_mq_del (struct GNUNET_TRANSPORT_QueueHandle *qh)
1035 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = qh->ch;
1037 send_del_queue (qh);
1038 GNUNET_CONTAINER_DLL_remove (ch->queue_head,
1041 GNUNET_MQ_destroy (qh->mq);
1042 GNUNET_free (qh->address);
1048 * Notify transport service about an address that this communicator
1049 * provides for this peer.
1051 * @param ch connection to transport service
1052 * @param address our address in human-readable format, 0-terminated, UTF-8
1053 * @param nt which network type does the address belong to?
1054 * @param expiration when does the communicator forsee this address expiring?
1056 struct GNUNET_TRANSPORT_AddressIdentifier *
1057 GNUNET_TRANSPORT_communicator_address_add (struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
1058 const char *address,
1059 enum GNUNET_NetworkType nt,
1060 struct GNUNET_TIME_Relative expiration)
1062 struct GNUNET_TRANSPORT_AddressIdentifier *ai;
1064 ai = GNUNET_new (struct GNUNET_TRANSPORT_AddressIdentifier);
1066 ai->address = GNUNET_strdup (address);
1068 ai->expiration = expiration;
1069 ai->aid = ch->aid_gen++;
1070 GNUNET_CONTAINER_DLL_insert (ch->ai_head,
1073 send_add_address (ai);
1079 * Notify transport service about an address that this communicator no
1080 * longer provides for this peer.
1082 * @param ai address that is no longer provided
1085 GNUNET_TRANSPORT_communicator_address_remove (struct GNUNET_TRANSPORT_AddressIdentifier *ai)
1087 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = ai->ch;
1089 send_del_address (ai);
1090 GNUNET_CONTAINER_DLL_remove (ch->ai_head,
1093 GNUNET_free (ai->address);
1098 /* ************************* Backchannel *************************** */
1102 * The communicator asks the transport service to route a message via
1103 * a different path to another communicator service at another peer.
1104 * This must only be done for special control traffic (as there is no
1105 * flow control for this API), such as acknowledgements, and generally
1106 * only be done if the communicator is uni-directional (i.e. cannot
1107 * send the message back itself).
1109 * @param ch handle of this communicator
1110 * @param pid peer to send the message to
1111 * @param comm name of the communicator to send the message to
1112 * @param header header of the message to transmit and pass via the
1113 * notify-API to @a pid's communicator @a comm
1116 GNUNET_TRANSPORT_communicator_notify (struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
1117 const struct GNUNET_PeerIdentity *pid,
1119 const struct GNUNET_MessageHeader *header)
1121 struct GNUNET_MQ_Envelope *env;
1122 struct GNUNET_TRANSPORT_CommunicatorBackchannel *cb;
1123 size_t slen = strlen (comm) + 1;
1124 uint16_t mlen = ntohs (header->size);
1126 GNUNET_assert (mlen + slen + sizeof (*cb) < UINT16_MAX);
1127 env = GNUNET_MQ_msg_extra (cb,
1129 GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL);
1134 memcpy (((char *)&cb[1]) + mlen,
1137 GNUNET_MQ_send (ch->mq,
1142 /* end of transport_api2_communication.c */