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 * How many hops is the target away (DV-only)
282 * ID for this queue when talking to the transport service.
287 * Maximum transmission unit for the queue.
295 * Internal representation of an address a communicator is
296 * currently providing for the transport service.
298 struct GNUNET_TRANSPORT_AddressIdentifier
304 struct GNUNET_TRANSPORT_AddressIdentifier *next;
309 struct GNUNET_TRANSPORT_AddressIdentifier *prev;
312 * Transport handle where the address was added.
314 struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
317 * The actual address.
322 * When does the address expire? (Expected lifetime of the
325 struct GNUNET_TIME_Relative expiration;
328 * Internal UUID for the address used in communication with the
334 * Network type for the address.
336 enum GNUNET_NetworkType nt;
342 * (re)connect our communicator to the transport service
344 * @param ch handle to reconnect
347 reconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch);
351 * Send message to the transport service about address @a ai
352 * being now available.
354 * @param ai address to add
357 send_add_address (struct GNUNET_TRANSPORT_AddressIdentifier *ai)
359 struct GNUNET_MQ_Envelope *env;
360 struct GNUNET_TRANSPORT_AddAddressMessage *aam;
362 if (NULL == ai->ch->mq)
364 env = GNUNET_MQ_msg_extra (aam,
365 strlen (ai->address) + 1,
366 GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_ADDRESS);
367 aam->expiration = GNUNET_TIME_relative_hton (ai->expiration);
368 aam->nt = htonl ((uint32_t) ai->nt);
371 strlen (ai->address) + 1);
372 GNUNET_MQ_send (ai->ch->mq,
378 * Send message to the transport service about address @a ai
379 * being no longer available.
381 * @param ai address to delete
384 send_del_address (struct GNUNET_TRANSPORT_AddressIdentifier *ai)
386 struct GNUNET_MQ_Envelope *env;
387 struct GNUNET_TRANSPORT_DelAddressMessage *dam;
389 if (NULL == ai->ch->mq)
391 env = GNUNET_MQ_msg (dam,
392 GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_ADDRESS);
393 dam->aid = htonl (ai->aid);
394 GNUNET_MQ_send (ai->ch->mq,
400 * Send message to the transport service about queue @a qh
401 * being now available.
403 * @param qh queue to add
406 send_add_queue (struct GNUNET_TRANSPORT_QueueHandle *qh)
408 struct GNUNET_MQ_Envelope *env;
409 struct GNUNET_TRANSPORT_AddQueueMessage *aqm;
411 if (NULL == qh->ch->mq)
413 env = GNUNET_MQ_msg_extra (aqm,
414 strlen (qh->address) + 1,
415 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_SETUP);
416 aqm->qid = htonl (qh->queue_id);
417 aqm->receiver = qh->peer;
418 aqm->nt = htonl ((uint32_t) qh->nt);
419 aqm->mtu = htonl (qh->mtu);
420 aqm->cs = htonl ((uint32_t) qh->cs);
421 aqm->distance = htonl (qh->distance);
424 strlen (qh->address) + 1);
425 GNUNET_MQ_send (qh->ch->mq,
431 * Send message to the transport service about queue @a qh
432 * being no longer available.
434 * @param qh queue to delete
437 send_del_queue (struct GNUNET_TRANSPORT_QueueHandle *qh)
439 struct GNUNET_MQ_Envelope *env;
440 struct GNUNET_TRANSPORT_DelQueueMessage *dqm;
442 if (NULL == qh->ch->mq)
444 env = GNUNET_MQ_msg (dqm,
445 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_TEARDOWN);
446 dqm->qid = htonl (qh->queue_id);
447 dqm->receiver = qh->peer;
448 GNUNET_MQ_send (qh->ch->mq,
454 * Disconnect from the transport service. Purges
455 * all flow control entries as we will no longer receive
456 * the ACKs. Purges the ack pending entries as the
457 * transport will no longer expect the confirmations.
459 * @param ch service to disconnect from
462 disconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
464 struct FlowControl *fcn;
465 struct AckPending *apn;
467 for (struct FlowControl *fc = ch->fc_head;
472 GNUNET_CONTAINER_DLL_remove (ch->fc_head,
479 for (struct AckPending *ap = ch->ap_head;
484 GNUNET_CONTAINER_DLL_remove (ch->ap_head,
491 GNUNET_MQ_destroy (ch->mq);
497 * Function called on MQ errors.
500 error_handler (void *cls,
501 enum GNUNET_MQ_Error error)
503 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
505 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
506 "MQ failure %d, reconnecting to transport service.\n",
509 /* TODO: maybe do this with exponential backoff/delay */
515 * Transport service acknowledged a message we gave it
516 * (with flow control enabled). Tell the communicator.
518 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
519 * @param incoming_ack the ack
522 handle_incoming_ack (void *cls,
523 const struct GNUNET_TRANSPORT_IncomingMessageAck *incoming_ack)
525 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
527 for (struct FlowControl *fc = ch->fc_head;
531 if ( (fc->id == incoming_ack->fc_id) &&
532 (0 == memcmp (&fc->sender,
533 &incoming_ack->sender,
534 sizeof (struct GNUNET_PeerIdentity))) )
536 GNUNET_CONTAINER_DLL_remove (ch->fc_head,
547 /* TODO: maybe do this with exponential backoff/delay */
553 * Transport service wants us to create a queue. Check if @a cq
556 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
557 * @param cq the queue creation request
558 * @return #GNUNET_OK if @a smt is well-formed
561 check_create_queue (void *cls,
562 const struct GNUNET_TRANSPORT_CreateQueue *cq)
564 uint16_t len = ntohs (cq->header.size) - sizeof (*cq);
565 const char *addr = (const char *) &cq[1];
569 ('\0' != addr[len-1]) )
572 return GNUNET_SYSERR;
579 * Transport service wants us to create a queue. Tell the communicator.
581 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
582 * @param cq the queue creation request
585 handle_create_queue (void *cls,
586 const struct GNUNET_TRANSPORT_CreateQueue *cq)
588 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
589 const char *addr = (const char *) &cq[1];
590 struct GNUNET_TRANSPORT_CreateQueueResponse *cqr;
591 struct GNUNET_MQ_Envelope *env;
594 ch->mq_init (ch->mq_init_cls,
598 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
599 "Address `%s' invalid for this communicator\n",
601 env = GNUNET_MQ_msg (cqr,
602 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_FAIL);
606 env = GNUNET_MQ_msg (cqr,
607 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_OK);
609 cqr->request_id = cq->request_id;
610 GNUNET_MQ_send (ch->mq,
616 * Transport service wants us to send a message. Check if @a smt
619 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
620 * @param smt the transmission request
621 * @return #GNUNET_OK if @a smt is well-formed
624 check_send_msg (void *cls,
625 const struct GNUNET_TRANSPORT_SendMessageTo *smt)
627 uint16_t len = ntohs (smt->header.size) - sizeof (*smt);
628 const struct GNUNET_MessageHeader *mh = (const struct GNUNET_MessageHeader *) &smt[1];
631 if (ntohs (mh->size) != len)
634 return GNUNET_SYSERR;
641 * Notify transport service about @a status of a message with
642 * @a mid sent to @a receiver.
645 * @param status #GNUNET_OK on success, #GNUNET_SYSERR on failure
646 * @param receiver which peer was the receiver
647 * @param mid message that the ack is about
650 send_ack (struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
652 const struct GNUNET_PeerIdentity *receiver,
655 struct GNUNET_MQ_Envelope *env;
656 struct GNUNET_TRANSPORT_SendMessageToAck *ack;
658 env = GNUNET_MQ_msg (ack,
659 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG_ACK);
660 ack->status = htonl (status);
662 ack->receiver = *receiver;
663 GNUNET_MQ_send (ch->mq,
669 * Message queue transmission by communicator was successful,
670 * notify transport service.
672 * @param cls an `struct AckPending *`
675 send_ack_cb (void *cls)
677 struct AckPending *ap = cls;
678 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = ap->ch;
680 GNUNET_CONTAINER_DLL_remove (ch->ap_head,
692 * Transport service wants us to send a message. Tell the communicator.
694 * @param cls our `struct GNUNET_TRANSPORT_CommunicatorHandle *`
695 * @param smt the transmission request
698 handle_send_msg (void *cls,
699 const struct GNUNET_TRANSPORT_SendMessageTo *smt)
701 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
702 const struct GNUNET_MessageHeader *mh;
703 struct GNUNET_MQ_Envelope *env;
704 struct AckPending *ap;
705 struct GNUNET_TRANSPORT_QueueHandle *qh;
707 for (qh = ch->queue_head;NULL != qh; qh = qh->next)
708 if ( (qh->queue_id == smt->qid) &&
709 (0 == memcmp (&qh->peer,
711 sizeof (struct GNUNET_PeerIdentity))) )
715 /* queue is already gone, tell transport this one failed */
716 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
717 "Transmission failed, queue no longer exists.\n");
724 ap = GNUNET_new (struct AckPending);
726 ap->receiver = smt->receiver;
728 GNUNET_CONTAINER_DLL_insert (ch->ap_head,
731 mh = (const struct GNUNET_MessageHeader *) &smt[1];
732 env = GNUNET_MQ_msg_copy (mh);
733 GNUNET_MQ_notify_sent (env,
736 GNUNET_MQ_send (qh->mq,
742 * (re)connect our communicator to the transport service
744 * @param ch handle to reconnect
747 reconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
749 struct GNUNET_MQ_MessageHandler handlers[] = {
750 GNUNET_MQ_hd_fixed_size (incoming_ack,
751 GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG_ACK,
752 struct GNUNET_TRANSPORT_IncomingMessageAck,
754 GNUNET_MQ_hd_var_size (create_queue,
755 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE,
756 struct GNUNET_TRANSPORT_CreateQueue,
758 GNUNET_MQ_hd_var_size (send_msg,
759 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG,
760 struct GNUNET_TRANSPORT_SendMessageTo,
762 // FIXME: handle backchannel notifications!
763 GNUNET_MQ_handler_end()
765 struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam;
766 struct GNUNET_MQ_Envelope *env;
768 ch->mq = GNUNET_CLIENT_connect (ch->cfg,
775 env = GNUNET_MQ_msg_extra (cam,
776 strlen (ch->addr_prefix) + 1,
777 GNUNET_MESSAGE_TYPE_TRANSPORT_NEW_COMMUNICATOR);
778 cam->cc = htonl ((uint32_t) ch->cc);
781 strlen (ch->addr_prefix) + 1);
782 GNUNET_MQ_send (ch->mq,
784 for (struct GNUNET_TRANSPORT_AddressIdentifier *ai = ch->ai_head;
787 send_add_address (ai);
788 for (struct GNUNET_TRANSPORT_QueueHandle *qh = ch->queue_head;
796 * Connect to the transport service.
798 * @param cfg configuration to use
799 * @param config_section section of the configuration to use for options
800 * @param addr_prefix address prefix for addresses supported by this
801 * communicator, could be NULL for incoming-only communicators
802 * @param cc what characteristics does the communicator have?
803 * @param mtu maximum message size supported by communicator, 0 if
804 * sending is not supported, SIZE_MAX for no MTU
805 * @param mq_init function to call to initialize a message queue given
806 * the address of another peer, can be NULL if the
807 * communicator only supports receiving messages
808 * @param mq_init_cls closure for @a mq_init
809 * @param notify_cb function to pass backchannel messages to communicator
810 * @param notify_cb_cls closure for @a notify_cb
811 * @return NULL on error
813 struct GNUNET_TRANSPORT_CommunicatorHandle *
814 GNUNET_TRANSPORT_communicator_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
815 const char *config_section,
816 const char *addr_prefix,
817 enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc,
818 GNUNET_TRANSPORT_CommunicatorMqInit mq_init,
820 GNUNET_TRANSPORT_CommunicatorNotify notify_cb,
823 struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
825 ch = GNUNET_new (struct GNUNET_TRANSPORT_CommunicatorHandle);
827 ch->config_section = config_section;
828 ch->addr_prefix = addr_prefix;
829 ch->mq_init = mq_init;
830 ch->mq_init_cls = mq_init_cls;
831 ch->notify_cb = notify_cb;
832 ch->notify_cb_cls = notify_cb_cls;
836 GNUNET_CONFIGURATION_get_value_number (cfg,
839 &ch->max_queue_length))
840 ch->max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
851 * Disconnect from the transport service.
853 * @param ch handle returned from connect
856 GNUNET_TRANSPORT_communicator_disconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
859 while (NULL != ch->ai_head)
861 GNUNET_break (0); /* communicator forgot to remove address, warn! */
862 GNUNET_TRANSPORT_communicator_address_remove (ch->ai_head);
868 /* ************************* Receiving *************************** */
872 * Notify transport service that the communicator has received
875 * @param ch connection to transport service
876 * @param sender presumed sender of the message (details to be checked
878 * @param msg the message
879 * @param cb function to call once handling the message is done, NULL if
880 * flow control is not supported by this communicator
881 * @param cb_cls closure for @a cb
882 * @return #GNUNET_OK if all is well, #GNUNET_NO if the message was
883 * immediately dropped due to memory limitations (communicator
884 * should try to apply back pressure),
885 * #GNUNET_SYSERR if the message could not be delivered because
886 * the tranport service is not yet up
889 GNUNET_TRANSPORT_communicator_receive (struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
890 const struct GNUNET_PeerIdentity *sender,
891 const struct GNUNET_MessageHeader *msg,
892 GNUNET_TRANSPORT_MessageCompletedCallback cb,
895 struct GNUNET_MQ_Envelope *env;
896 struct GNUNET_TRANSPORT_IncomingMessage *im;
900 return GNUNET_SYSERR;
902 (GNUNET_MQ_get_length (ch->mq) >= ch->max_queue_length) )
904 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
905 "Dropping message: transprot is too slow, queue length %llu exceeded\n",
906 ch->max_queue_length);
910 msize = ntohs (msg->size);
911 env = GNUNET_MQ_msg_extra (im,
913 GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG);
917 return GNUNET_SYSERR;
919 im->sender = *sender;
925 struct FlowControl *fc;
927 im->fc_on = htonl (GNUNET_YES);
928 im->fc_id = ch->fc_gen++;
929 fc = GNUNET_new (struct FlowControl);
930 fc->sender = *sender;
934 GNUNET_CONTAINER_DLL_insert (ch->fc_head,
938 GNUNET_MQ_send (ch->mq,
944 /* ************************* Discovery *************************** */
948 * Notify transport service that an MQ became available due to an
949 * "inbound" connection or because the communicator discovered the
950 * presence of another peer.
952 * @param ch connection to transport service
953 * @param peer peer with which we can now communicate
954 * @param address address in human-readable format, 0-terminated, UTF-8
955 * @param mtu maximum message size supported by queue, 0 if
956 * sending is not supported, SIZE_MAX for no MTU
957 * @param nt which network type does the @a address belong to?
958 * @param cc what characteristics does the communicator have?
959 * @param distance how many hops does this queue use (DV-only)?
960 * @param cs what is the connection status of the queue?
961 * @param mq message queue of the @a peer
962 * @return API handle identifying the new MQ
964 struct GNUNET_TRANSPORT_QueueHandle *
965 GNUNET_TRANSPORT_communicator_mq_add (struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
966 const struct GNUNET_PeerIdentity *peer,
969 enum GNUNET_NetworkType nt,
971 enum GNUNET_TRANSPORT_ConnectionStatus cs,
972 struct GNUNET_MQ_Handle *mq)
974 struct GNUNET_TRANSPORT_QueueHandle *qh;
976 qh = GNUNET_new (struct GNUNET_TRANSPORT_QueueHandle);
979 qh->address = GNUNET_strdup (address);
982 qh->distance = distance;
985 qh->queue_id = ch->queue_gen++;
986 GNUNET_CONTAINER_DLL_insert (ch->queue_head,
995 * Notify transport service that an MQ became unavailable due to a
996 * disconnect or timeout.
998 * @param qh handle for the queue that must be invalidated
1001 GNUNET_TRANSPORT_communicator_mq_del (struct GNUNET_TRANSPORT_QueueHandle *qh)
1003 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = qh->ch;
1005 send_del_queue (qh);
1006 GNUNET_CONTAINER_DLL_remove (ch->queue_head,
1009 GNUNET_MQ_destroy (qh->mq);
1010 GNUNET_free (qh->address);
1016 * Notify transport service about an address that this communicator
1017 * provides for this peer.
1019 * @param ch connection to transport service
1020 * @param address our address in human-readable format, 0-terminated, UTF-8
1021 * @param nt which network type does the address belong to?
1022 * @param expiration when does the communicator forsee this address expiring?
1024 struct GNUNET_TRANSPORT_AddressIdentifier *
1025 GNUNET_TRANSPORT_communicator_address_add (struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
1026 const char *address,
1027 enum GNUNET_NetworkType nt,
1028 struct GNUNET_TIME_Relative expiration)
1030 struct GNUNET_TRANSPORT_AddressIdentifier *ai;
1032 ai = GNUNET_new (struct GNUNET_TRANSPORT_AddressIdentifier);
1034 ai->address = GNUNET_strdup (address);
1036 ai->expiration = expiration;
1037 ai->aid = ch->aid_gen++;
1038 GNUNET_CONTAINER_DLL_insert (ch->ai_head,
1041 send_add_address (ai);
1047 * Notify transport service about an address that this communicator no
1048 * longer provides for this peer.
1050 * @param ai address that is no longer provided
1053 GNUNET_TRANSPORT_communicator_address_remove (struct GNUNET_TRANSPORT_AddressIdentifier *ai)
1055 struct GNUNET_TRANSPORT_CommunicatorHandle *ch = ai->ch;
1057 send_del_address (ai);
1058 GNUNET_CONTAINER_DLL_remove (ch->ai_head,
1061 GNUNET_free (ai->address);
1066 /* ************************* Backchannel *************************** */
1070 * The communicator asks the transport service to route a message via
1071 * a different path to another communicator service at another peer.
1072 * This must only be done for special control traffic (as there is no
1073 * flow control for this API), such as acknowledgements, and generally
1074 * only be done if the communicator is uni-directional (i.e. cannot
1075 * send the message back itself).
1077 * @param ch handle of this communicator
1078 * @param pid peer to send the message to
1079 * @param comm name of the communicator to send the message to
1080 * @param header header of the message to transmit and pass via the
1081 * notify-API to @a pid's communicator @a comm
1084 GNUNET_TRANSPORT_communicator_notify (struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
1085 const struct GNUNET_PeerIdentity *pid,
1087 const struct GNUNET_MessageHeader *header)
1089 struct GNUNET_MQ_Envelope *env;
1090 struct GNUNET_TRANSPORT_CommunicatorBackchannel *cb;
1091 size_t slen = strlen (comm) + 1;
1092 uint16_t mlen = ntohs (header->size);
1094 GNUNET_assert (mlen + slen + sizeof (*cb) < UINT16_MAX);
1095 env = GNUNET_MQ_msg_extra (cb,
1097 GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL);
1102 memcpy (((char *)&cb[1]) + mlen,
1105 GNUNET_MQ_send (ch->mq,
1110 /* end of transport_api2_communication.c */