2 This file is part of GNUnet.
3 Copyright (C) 2010-2016, 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/>.
19 * @file transport/gnunet-service-transport.c
20 * @brief main for gnunet-service-transport
21 * @author Christian Grothoff
24 #include "gnunet_util_lib.h"
25 #include "gnunet_statistics_service.h"
26 #include "gnunet_transport_service.h"
27 #include "gnunet_peerinfo_service.h"
28 #include "gnunet_ats_service.h"
29 #include "gnunet-service-transport.h"
30 #include "transport.h"
34 * How many messages can we have pending for a given client process
35 * before we start to drop incoming messages? We typically should
36 * have only one client and so this would be the primary buffer for
37 * messages, so the number should be chosen rather generously.
39 * The expectation here is that most of the time the queue is large
40 * enough so that a drop is virtually never required. Note that
41 * this value must be about as large as 'TOTAL_MSGS' in the
42 * 'test_transport_api_reliability.c', otherwise that testcase may
45 #define MAX_PENDING (128 * 1024)
49 * What type of client is the `struct TransportClient` about?
54 * We do not know yet (client is fresh).
59 * Is the CORE service, we need to forward traffic to it.
64 * It is a monitor, forward monitor data.
69 * It is a communicator, use for communication.
76 * Client connected to the transport service.
78 struct TransportClient;
82 * A neighbour that at least one communicator is connected to.
88 * List of available queues for a particular neighbour.
95 struct Queue *next_neighbour;
100 struct Queue *prev_neighbour;
105 struct Queue *prev_client;
110 struct Queue *next_client;
113 * Which neighbour is this queue for?
115 struct Neighbour *neighbour;
118 * Which communicator offers this queue?
120 struct TransportClient *tc;
123 * Address served by the queue.
128 * Unique identifier of this queue with the communicator.
133 * Network type offered by this queue.
135 enum GNUNET_ATS_Network_Type nt;
140 * A neighbour that at least one communicator is connected to.
146 * Which peer is this about?
148 struct GNUNET_PeerIdentity pid;
151 * Head of list of messages pending for this neighbour.
153 struct PendingMessage *pending_msg_head;
156 * Tail of list of messages pending for this neighbour.
158 struct PendingMessage *pending_msg_tail;
161 * Head of DLL of queues to this peer.
163 struct Queue *queue_head;
166 * Tail of DLL of queues to this peer.
168 struct Queue *queue_tail;
174 * Transmission request from CORE that is awaiting delivery.
176 struct PendingMessage
179 * Kept in a MDLL of messages for this @a target.
181 struct PendingMessage *next_neighbour;
184 * Kept in a MDLL of messages for this @a target.
186 struct PendingMessage *prev_neighbour;
189 * Kept in a MDLL of messages from this @a client.
191 struct PendingMessage *next_client;
194 * Kept in a MDLL of messages from this @a client.
196 struct PendingMessage *prev_client;
199 * Target of the request.
201 struct Neighbour *target;
204 * Client that issued the transmission request.
206 struct TransportClient *client;
209 * Size of the original message.
217 * One of the addresses of this peer.
219 struct AddressListEntry
225 struct AddressListEntry *next;
230 struct AddressListEntry *prev;
233 * Which communicator provides this address?
235 struct TransportClient *tc;
238 * The actual address.
243 * What is a typical lifetime the communicator expects this
244 * address to have? (Always from now.)
246 struct GNUNET_TIME_Relative expiration;
249 * Address identifier used by the communicator.
254 * Network type offered by this address.
256 enum GNUNET_ATS_Network_Type nt;
262 * Client connected to the transport service.
264 struct TransportClient
270 struct TransportClient *next;
275 struct TransportClient *prev;
278 * Handle to the client.
280 struct GNUNET_SERVICE_Client *client;
283 * Message queue to the client.
285 struct GNUNET_MQ_Handle *mq;
288 * What type of client is this?
290 enum ClientType type;
296 * Information for @e type #CT_CORE.
301 * Head of list of messages pending for this client.
303 struct PendingMessage *pending_msg_head;
306 * Tail of list of messages pending for this client.
308 struct PendingMessage *pending_msg_tail;
313 * Information for @e type #CT_MONITOR.
318 * Peer identity to monitor the addresses of.
319 * Zero to monitor all neighbours. Valid if
320 * @e type is #CT_MONITOR.
322 struct GNUNET_PeerIdentity peer;
325 * Is this a one-shot monitor?
333 * Information for @e type #CT_COMMUNICATOR.
337 * If @e type is #CT_COMMUNICATOR, this communicator
338 * supports communicating using these addresses.
340 char *address_prefix;
343 * Head of DLL of queues offered by this communicator.
345 struct Queue *queue_head;
348 * Tail of DLL of queues offered by this communicator.
350 struct Queue *queue_tail;
353 * Head of list of the addresses of this peer offered by this communicator.
355 struct AddressListEntry *addr_head;
358 * Tail of list of the addresses of this peer offered by this communicator.
360 struct AddressListEntry *addr_tail;
370 * Head of linked list of all clients to this service.
372 static struct TransportClient *clients_head;
375 * Tail of linked list of all clients to this service.
377 static struct TransportClient *clients_tail;
382 struct GNUNET_STATISTICS_Handle *GST_stats;
385 * Configuration handle.
387 const struct GNUNET_CONFIGURATION_Handle *GST_cfg;
392 struct GNUNET_PeerIdentity GST_my_identity;
397 struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key;
400 * Map from PIDs to `struct Neighbour` entries. A peer is
401 * a neighbour if we have an MQ to it from some communicator.
403 static struct GNUNET_CONTAINER_MultiPeerMap *neighbours;
407 * Lookup neighbour record for peer @a pid.
409 * @param pid neighbour to look for
410 * @return NULL if we do not have this peer as a neighbour
412 static struct Neighbour *
413 lookup_neighbour (const struct GNUNET_PeerIdentity *pid)
415 return GNUNET_CONTAINER_multipeermap_get (neighbours,
421 * Called whenever a client connects. Allocates our
422 * data structures associated with that client.
424 * @param cls closure, NULL
425 * @param client identification of the client
426 * @param mq message queue for the client
427 * @return our `struct TransportClient`
430 client_connect_cb (void *cls,
431 struct GNUNET_SERVICE_Client *client,
432 struct GNUNET_MQ_Handle *mq)
434 struct TransportClient *tc;
436 tc = GNUNET_new (struct TransportClient);
439 GNUNET_CONTAINER_DLL_insert (clients_head,
442 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
443 "Client %p connected\n",
450 * Called whenever a client is disconnected. Frees our
451 * resources associated with that client.
453 * @param cls closure, NULL
454 * @param client identification of the client
455 * @param app_ctx our `struct TransportClient`
458 client_disconnect_cb (void *cls,
459 struct GNUNET_SERVICE_Client *client,
462 struct TransportClient *tc = app_ctx;
464 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
465 "Client %p disconnected, cleaning up.\n",
467 GNUNET_CONTAINER_DLL_remove (clients_head,
476 struct PendingMessage *pm;
478 while (NULL != (pm = tc->details.core.pending_msg_head))
480 GNUNET_CONTAINER_MDLL_remove (client,
481 tc->details.core.pending_msg_head,
482 tc->details.core.pending_msg_tail,
490 case CT_COMMUNICATOR:
491 GNUNET_free (tc->details.communicator.address_prefix);
499 * Initialize a "CORE" client. We got a start message from this
500 * client, so add it to the list of clients for broadcasting of
503 * @param cls the client
504 * @param start the start message that was sent
507 handle_client_start (void *cls,
508 const struct StartMessage *start)
510 struct TransportClient *tc = cls;
513 options = ntohl (start->options);
514 if ( (0 != (1 & options)) &&
516 memcmp (&start->self,
518 sizeof (struct GNUNET_PeerIdentity)) ) )
520 /* client thinks this is a different peer, reject */
522 GNUNET_SERVICE_client_drop (tc->client);
525 if (CT_NONE != tc->type)
528 GNUNET_SERVICE_client_drop (tc->client);
532 GNUNET_SERVICE_client_continue (tc->client);
537 * Client asked for transmission to a peer. Process the request.
539 * @param cls the client
540 * @param obm the send message that was sent
543 check_client_send (void *cls,
544 const struct OutboundMessage *obm)
546 struct TransportClient *tc = cls;
548 const struct GNUNET_MessageHeader *obmm;
550 if (CT_CORE != tc->type)
553 return GNUNET_SYSERR;
555 size = ntohs (obm->header.size) - sizeof (struct OutboundMessage);
556 if (size < sizeof (struct GNUNET_MessageHeader))
559 return GNUNET_SYSERR;
561 obmm = (const struct GNUNET_MessageHeader *) &obm[1];
562 if (size != ntohs (obmm->size))
565 return GNUNET_SYSERR;
572 * Send a response to the @a pm that we have processed a
573 * "send" request with status @a success. We
574 * transmitted @a bytes_physical on the actual wire.
575 * Sends a confirmation to the "core" client responsible
576 * for the original request and free's @a pm.
578 * @param pm handle to the original pending message
579 * @param success status code, #GNUNET_OK on success, #GNUNET_SYSERR
580 * for transmission failure
581 * @param bytes_physical amount of bandwidth consumed
584 client_send_response (struct PendingMessage *pm,
586 uint32_t bytes_physical)
588 struct TransportClient *tc = pm->client;
589 struct Neighbour *target = pm->target;
590 struct GNUNET_MQ_Envelope *env;
591 struct SendOkMessage *som;
595 env = GNUNET_MQ_msg (som,
596 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK);
597 som->success = htonl ((uint32_t) success);
598 som->bytes_msg = htonl (pm->bytes_msg);
599 som->bytes_physical = htonl (bytes_physical);
600 som->peer = target->pid;
601 GNUNET_MQ_send (tc->mq,
603 GNUNET_CONTAINER_MDLL_remove (client,
604 tc->details.core.pending_msg_head,
605 tc->details.core.pending_msg_tail,
608 GNUNET_CONTAINER_MDLL_remove (neighbour,
609 target->pending_msg_head,
610 target->pending_msg_tail,
617 * Client asked for transmission to a peer. Process the request.
619 * @param cls the client
620 * @param obm the send message that was sent
623 handle_client_send (void *cls,
624 const struct OutboundMessage *obm)
626 struct TransportClient *tc = cls;
627 struct PendingMessage *pm;
628 const struct GNUNET_MessageHeader *obmm;
629 struct Neighbour *target;
632 GNUNET_assert (CT_CORE == tc->type);
633 obmm = (const struct GNUNET_MessageHeader *) &obm[1];
634 bytes_msg = ntohs (obmm->size);
635 target = lookup_neighbour (&obm->peer);
638 /* Failure: don't have this peer as a neighbour (anymore).
639 Might have gone down asynchronously, so this is NOT
640 a protocol violation by CORE. Still count the event,
641 as this should be rare. */
642 struct GNUNET_MQ_Envelope *env;
643 struct SendOkMessage *som;
645 env = GNUNET_MQ_msg (som,
646 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK);
647 som->success = htonl (GNUNET_SYSERR);
648 som->bytes_msg = htonl (bytes_msg);
649 som->bytes_physical = htonl (0);
650 som->peer = obm->peer;
651 GNUNET_MQ_send (tc->mq,
653 GNUNET_SERVICE_client_continue (tc->client);
654 GNUNET_STATISTICS_update (GST_stats,
655 "# messages dropped (neighbour unknown)",
660 pm = GNUNET_new (struct PendingMessage);
663 pm->bytes_msg = bytes_msg;
664 GNUNET_CONTAINER_MDLL_insert (neighbour,
665 target->pending_msg_head,
666 target->pending_msg_tail,
668 GNUNET_CONTAINER_MDLL_insert (client,
669 tc->details.core.pending_msg_head,
670 tc->details.core.pending_msg_tail,
672 // FIXME: do the work, continuation with:
673 client_send_response (pm,
680 * Communicator started. Test message is well-formed.
682 * @param cls the client
683 * @param cam the send message that was sent
686 check_communicator_available (void *cls,
687 const struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam)
689 struct TransportClient *tc = cls;
693 if (CT_NONE != tc->type)
696 return GNUNET_SYSERR;
698 tc->type = CT_COMMUNICATOR;
699 size = ntohs (cam->header.size) - sizeof (*cam);
701 return GNUNET_OK; /* receive-only communicator */
702 addr = (const char *) &cam[1];
703 if ('\0' != addr[size-1])
706 return GNUNET_SYSERR;
713 * Communicator started. Process the request.
715 * @param cls the client
716 * @param cam the send message that was sent
719 handle_communicator_available (void *cls,
720 const struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam)
722 struct TransportClient *tc = cls;
725 size = ntohs (cam->header.size) - sizeof (*cam);
727 return; /* receive-only communicator */
728 tc->details.communicator.address_prefix = GNUNET_strdup ((const char *) &cam[1]);
729 GNUNET_SERVICE_client_continue (tc->client);
734 * Address of our peer added. Test message is well-formed.
736 * @param cls the client
737 * @param aam the send message that was sent
740 check_add_address (void *cls,
741 const struct GNUNET_TRANSPORT_AddAddressMessage *aam)
743 struct TransportClient *tc = cls;
747 if (CT_COMMUNICATOR != tc->type)
750 return GNUNET_SYSERR;
752 size = ntohs (aam->header.size) - sizeof (*aam);
756 return GNUNET_SYSERR;
758 addr = (const char *) &aam[1];
759 if ('\0' != addr[size-1])
762 return GNUNET_SYSERR;
769 * Address of our peer added. Process the request.
771 * @param cls the client
772 * @param aam the send message that was sent
775 handle_add_address (void *cls,
776 const struct GNUNET_TRANSPORT_AddAddressMessage *aam)
778 struct TransportClient *tc = cls;
779 struct AddressListEntry *ale;
782 slen = ntohs (aam->header.size) - sizeof (*aam);
783 ale = GNUNET_malloc (sizeof (struct AddressListEntry) + slen);
785 ale->address = (const char *) &ale[1];
786 ale->expiration = GNUNET_TIME_relative_ntoh (aam->expiration);
788 ale->nt = (enum GNUNET_ATS_Network_Type) ntohl (aam->nt);
792 GNUNET_CONTAINER_DLL_insert (tc->details.communicator.addr_head,
793 tc->details.communicator.addr_tail,
795 // FIXME: notify somebody?!
796 GNUNET_SERVICE_client_continue (tc->client);
801 * Address of our peer deleted. Process the request.
803 * @param cls the client
804 * @param dam the send message that was sent
807 handle_del_address (void *cls,
808 const struct GNUNET_TRANSPORT_DelAddressMessage *dam)
810 struct TransportClient *tc = cls;
812 if (CT_COMMUNICATOR != tc->type)
815 GNUNET_SERVICE_client_drop (tc->client);
818 for (struct AddressListEntry *ale = tc->details.communicator.addr_head;
822 if (dam->aid != ale->aid)
824 GNUNET_assert (ale->tc == tc);
825 GNUNET_CONTAINER_DLL_remove (tc->details.communicator.addr_head,
826 tc->details.communicator.addr_tail,
828 // FIXME: notify somebody?
830 GNUNET_SERVICE_client_continue (tc->client);
833 GNUNET_SERVICE_client_drop (tc->client);
838 * Client notified us about transmission from a peer. Process the request.
840 * @param cls the client
841 * @param obm the send message that was sent
844 check_incoming_msg (void *cls,
845 const struct GNUNET_TRANSPORT_IncomingMessage *im)
847 struct TransportClient *tc = cls;
849 const struct GNUNET_MessageHeader *obmm;
851 if (CT_COMMUNICATOR != tc->type)
854 return GNUNET_SYSERR;
856 size = ntohs (im->header.size) - sizeof (*im);
857 if (size < sizeof (struct GNUNET_MessageHeader))
860 return GNUNET_SYSERR;
862 obmm = (const struct GNUNET_MessageHeader *) &im[1];
863 if (size != ntohs (obmm->size))
866 return GNUNET_SYSERR;
873 * Incoming meessage. Process the request.
875 * @param cls the client
876 * @param im the send message that was received
879 handle_incoming_msg (void *cls,
880 const struct GNUNET_TRANSPORT_IncomingMessage *im)
882 struct TransportClient *tc = cls;
884 GNUNET_SERVICE_client_continue (tc->client);
889 * New queue became available. Check message.
891 * @param cls the client
892 * @param aqm the send message that was sent
895 check_add_queue_message (void *cls,
896 const struct GNUNET_TRANSPORT_AddQueueMessage *aqm)
898 struct TransportClient *tc = cls;
902 if (CT_COMMUNICATOR != tc->type)
905 return GNUNET_SYSERR;
907 size = ntohs (aqm->header.size) - sizeof (*aqm);
911 return GNUNET_SYSERR;
913 addr = (const char *) &aqm[1];
914 if ('\0' != addr[size-1])
917 return GNUNET_SYSERR;
924 * New queue became available. Process the request.
926 * @param cls the client
927 * @param aqm the send message that was sent
930 handle_add_queue_message (void *cls,
931 const struct GNUNET_TRANSPORT_AddQueueMessage *aqm)
933 struct TransportClient *tc = cls;
935 struct Neighbour *neighbour;
939 neighbour = lookup_neighbour (&aqm->receiver);
940 if (NULL == neighbour)
942 neighbour = GNUNET_new (struct Neighbour);
943 neighbour->pid = aqm->receiver;
944 GNUNET_assert (GNUNET_OK ==
945 GNUNET_CONTAINER_multipeermap_put (neighbours,
948 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
949 // FIXME: notify ATS/COREs/monitors!
951 addr_len = ntohs (aqm->header.size) - sizeof (*aqm);
952 addr = (const char *) &aqm[1];
954 queue = GNUNET_malloc (sizeof (struct Queue) + addr_len);
955 queue->qid = aqm->qid;
956 queue->nt = (enum GNUNET_ATS_Network_Type) ntohl (aqm->nt);
958 queue->neighbour = neighbour;
959 queue->address = (const char *) &queue[1];
963 GNUNET_CONTAINER_MDLL_insert (neighbour,
964 neighbour->queue_head,
965 neighbour->queue_tail,
967 GNUNET_CONTAINER_MDLL_insert (client,
968 tc->details.communicator.queue_head,
969 tc->details.communicator.queue_tail,
971 // FIXME: possibly transmit queued messages?
972 GNUNET_SERVICE_client_continue (tc->client);
977 * Release memory used by @a neighbour.
979 * @param neighbour neighbour entry to free
982 free_neighbour (struct Neighbour *neighbour)
984 GNUNET_assert (NULL == neighbour->queue_head);
985 GNUNET_assert (GNUNET_YES ==
986 GNUNET_CONTAINER_multipeermap_remove (neighbours,
989 GNUNET_free (neighbour);
994 * Queue to a peer went down. Process the request.
996 * @param cls the client
997 * @param dqm the send message that was sent
1000 handle_del_queue_message (void *cls,
1001 const struct GNUNET_TRANSPORT_DelQueueMessage *dqm)
1003 struct TransportClient *tc = cls;
1005 if (CT_COMMUNICATOR != tc->type)
1008 GNUNET_SERVICE_client_drop (tc->client);
1011 for (struct Queue *queue = tc->details.communicator.queue_head;
1013 queue = queue->next_client)
1015 struct Neighbour *neighbour = queue->neighbour;
1017 if ( (dqm->qid != queue->qid) ||
1018 (0 != memcmp (&dqm->receiver,
1020 sizeof (struct GNUNET_PeerIdentity))) )
1022 GNUNET_CONTAINER_MDLL_remove (neighbour,
1023 neighbour->queue_head,
1024 neighbour->queue_tail,
1026 GNUNET_CONTAINER_MDLL_remove (client,
1027 tc->details.communicator.queue_head,
1028 tc->details.communicator.queue_tail,
1030 GNUNET_free (queue);
1031 if (NULL == neighbour->queue_head)
1033 // FIXME: notify cores/monitors!
1034 free_neighbour (neighbour);
1036 GNUNET_SERVICE_client_continue (tc->client);
1040 GNUNET_SERVICE_client_drop (tc->client);
1045 * Message was transmitted. Process the request.
1047 * @param cls the client
1048 * @param sma the send message that was sent
1051 handle_send_message_ack (void *cls,
1052 const struct GNUNET_TRANSPORT_SendMessageToAck *sma)
1054 struct TransportClient *tc = cls;
1056 if (CT_COMMUNICATOR != tc->type)
1059 GNUNET_SERVICE_client_drop (tc->client);
1062 GNUNET_SERVICE_client_continue (tc->client);
1067 * Initialize a monitor client.
1069 * @param cls the client
1070 * @param start the start message that was sent
1073 handle_monitor_start (void *cls,
1074 const struct GNUNET_TRANSPORT_MonitorStart *start)
1076 struct TransportClient *tc = cls;
1078 if (CT_NONE != tc->type)
1081 GNUNET_SERVICE_client_drop (tc->client);
1084 tc->type = CT_MONITOR;
1085 tc->details.monitor.peer = start->peer;
1086 tc->details.monitor.one_shot = ntohl (start->one_shot);
1088 GNUNET_SERVICE_client_continue (tc->client);
1093 * Free neighbour entry.
1097 * @param value a `struct Neighbour`
1098 * @return #GNUNET_OK (always)
1101 free_neighbour_cb (void *cls,
1102 const struct GNUNET_PeerIdentity *pid,
1105 struct Neighbour *neighbour = value;
1109 GNUNET_break (0); // should this ever happen?
1110 free_neighbour (neighbour);
1117 * Function called when the service shuts down. Unloads our plugins
1118 * and cancels pending validations.
1120 * @param cls closure, unused
1123 do_shutdown (void *cls)
1127 if (NULL != GST_stats)
1129 GNUNET_STATISTICS_destroy (GST_stats,
1133 if (NULL != GST_my_private_key)
1135 GNUNET_free (GST_my_private_key);
1136 GST_my_private_key = NULL;
1138 GNUNET_CONTAINER_multipeermap_iterate (neighbours,
1141 GNUNET_CONTAINER_multipeermap_destroy (neighbours);
1146 * Initiate transport service.
1148 * @param cls closure
1149 * @param c configuration to use
1150 * @param service the initialized service
1154 const struct GNUNET_CONFIGURATION_Handle *c,
1155 struct GNUNET_SERVICE_Handle *service)
1160 neighbours = GNUNET_CONTAINER_multipeermap_create (1024,
1162 GST_my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (GST_cfg);
1163 if (NULL == GST_my_private_key)
1165 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1166 _("Transport service is lacking key configuration settings. Exiting.\n"));
1167 GNUNET_SCHEDULER_shutdown ();
1170 GNUNET_CRYPTO_eddsa_key_get_public (GST_my_private_key,
1171 &GST_my_identity.public_key);
1172 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1173 "My identity is `%s'\n",
1174 GNUNET_i2s_full (&GST_my_identity));
1176 GST_stats = GNUNET_STATISTICS_create ("transport",
1178 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
1180 /* start subsystems */
1185 * Define "main" method using service macro.
1189 GNUNET_SERVICE_OPTION_NONE,
1192 &client_disconnect_cb,
1194 /* communication with core */
1195 GNUNET_MQ_hd_fixed_size (client_start,
1196 GNUNET_MESSAGE_TYPE_TRANSPORT_START,
1197 struct StartMessage,
1199 GNUNET_MQ_hd_var_size (client_send,
1200 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND,
1201 struct OutboundMessage,
1203 /* communication with communicators */
1204 GNUNET_MQ_hd_var_size (communicator_available,
1205 GNUNET_MESSAGE_TYPE_TRANSPORT_NEW_COMMUNICATOR,
1206 struct GNUNET_TRANSPORT_CommunicatorAvailableMessage,
1208 GNUNET_MQ_hd_var_size (add_address,
1209 GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_ADDRESS,
1210 struct GNUNET_TRANSPORT_AddAddressMessage,
1212 GNUNET_MQ_hd_fixed_size (del_address,
1213 GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_ADDRESS,
1214 struct GNUNET_TRANSPORT_DelAddressMessage,
1216 GNUNET_MQ_hd_var_size (incoming_msg,
1217 GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG,
1218 struct GNUNET_TRANSPORT_IncomingMessage,
1220 GNUNET_MQ_hd_var_size (add_queue_message,
1221 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_SETUP,
1222 struct GNUNET_TRANSPORT_AddQueueMessage,
1224 GNUNET_MQ_hd_fixed_size (del_queue_message,
1225 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_TEARDOWN,
1226 struct GNUNET_TRANSPORT_DelQueueMessage,
1228 GNUNET_MQ_hd_fixed_size (send_message_ack,
1229 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG_ACK,
1230 struct GNUNET_TRANSPORT_SendMessageToAck,
1232 /* communication with monitors */
1233 GNUNET_MQ_hd_fixed_size (monitor_start,
1234 GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_START,
1235 struct GNUNET_TRANSPORT_MonitorStart,
1237 GNUNET_MQ_handler_end ());
1240 /* end of file gnunet-service-transport.c */