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 * - make *our* collected addresses available somehow somewhere
25 * => Choices: in peerstore or revive/keep peerinfo?
26 * - MTU information is missing for queues!
27 * - start supporting monitor logic (add functions to signal monitors!)
28 * - manage fragmentation/defragmentation, retransmission, track RTT, loss, etc.
29 * - ask ATS about bandwidth allocation
33 #include "gnunet_util_lib.h"
34 #include "gnunet_statistics_service.h"
35 #include "gnunet_transport_service.h"
36 #include "gnunet_peerinfo_service.h"
37 #include "gnunet_ats_service.h"
38 #include "gnunet-service-transport.h"
39 #include "transport.h"
43 * How many messages can we have pending for a given client process
44 * before we start to drop incoming messages? We typically should
45 * have only one client and so this would be the primary buffer for
46 * messages, so the number should be chosen rather generously.
48 * The expectation here is that most of the time the queue is large
49 * enough so that a drop is virtually never required. Note that
50 * this value must be about as large as 'TOTAL_MSGS' in the
51 * 'test_transport_api_reliability.c', otherwise that testcase may
54 #define MAX_PENDING (128 * 1024)
58 * What type of client is the `struct TransportClient` about?
63 * We do not know yet (client is fresh).
68 * Is the CORE service, we need to forward traffic to it.
73 * It is a monitor, forward monitor data.
78 * It is a communicator, use for communication.
85 * Client connected to the transport service.
87 struct TransportClient;
91 * A neighbour that at least one communicator is connected to.
97 * List of available queues for a particular neighbour.
104 struct Queue *next_neighbour;
109 struct Queue *prev_neighbour;
114 struct Queue *prev_client;
119 struct Queue *next_client;
122 * Which neighbour is this queue for?
124 struct Neighbour *neighbour;
127 * Which communicator offers this queue?
129 struct TransportClient *tc;
132 * Address served by the queue.
137 * Unique identifier of this queue with the communicator.
142 * Network type offered by this queue.
144 enum GNUNET_ATS_Network_Type nt;
146 // FIXME: add ATS-specific fields here!
151 * A neighbour that at least one communicator is connected to.
157 * Which peer is this about?
159 struct GNUNET_PeerIdentity pid;
162 * Head of list of messages pending for this neighbour.
164 struct PendingMessage *pending_msg_head;
167 * Tail of list of messages pending for this neighbour.
169 struct PendingMessage *pending_msg_tail;
172 * Head of DLL of queues to this peer.
174 struct Queue *queue_head;
177 * Tail of DLL of queues to this peer.
179 struct Queue *queue_tail;
182 * Quota at which CORE is allowed to transmit to this peer
185 * FIXME: not yet used, tricky to get right given multiple queues!
186 * (=> Idea: let ATS set a quota per queue and we add them up here?)
187 * FIXME: how do we set this value initially when we tell CORE?
188 * Options: start at a minimum value or at literally zero (before ATS?)
189 * (=> Current thought: clean would be zero!)
191 struct GNUNET_BANDWIDTH_Value32NBO quota_out;
197 * Transmission request from CORE that is awaiting delivery.
199 struct PendingMessage
202 * Kept in a MDLL of messages for this @a target.
204 struct PendingMessage *next_neighbour;
207 * Kept in a MDLL of messages for this @a target.
209 struct PendingMessage *prev_neighbour;
212 * Kept in a MDLL of messages from this @a client.
214 struct PendingMessage *next_client;
217 * Kept in a MDLL of messages from this @a client.
219 struct PendingMessage *prev_client;
222 * Target of the request.
224 struct Neighbour *target;
227 * Client that issued the transmission request.
229 struct TransportClient *client;
232 * Size of the original message.
240 * One of the addresses of this peer.
242 struct AddressListEntry
248 struct AddressListEntry *next;
253 struct AddressListEntry *prev;
256 * Which communicator provides this address?
258 struct TransportClient *tc;
261 * The actual address.
266 * What is a typical lifetime the communicator expects this
267 * address to have? (Always from now.)
269 struct GNUNET_TIME_Relative expiration;
272 * Address identifier used by the communicator.
277 * Network type offered by this address.
279 enum GNUNET_ATS_Network_Type nt;
285 * Client connected to the transport service.
287 struct TransportClient
293 struct TransportClient *next;
298 struct TransportClient *prev;
301 * Handle to the client.
303 struct GNUNET_SERVICE_Client *client;
306 * Message queue to the client.
308 struct GNUNET_MQ_Handle *mq;
311 * What type of client is this?
313 enum ClientType type;
319 * Information for @e type #CT_CORE.
324 * Head of list of messages pending for this client.
326 struct PendingMessage *pending_msg_head;
329 * Tail of list of messages pending for this client.
331 struct PendingMessage *pending_msg_tail;
336 * Information for @e type #CT_MONITOR.
341 * Peer identity to monitor the addresses of.
342 * Zero to monitor all neighbours. Valid if
343 * @e type is #CT_MONITOR.
345 struct GNUNET_PeerIdentity peer;
348 * Is this a one-shot monitor?
356 * Information for @e type #CT_COMMUNICATOR.
360 * If @e type is #CT_COMMUNICATOR, this communicator
361 * supports communicating using these addresses.
363 char *address_prefix;
366 * Head of DLL of queues offered by this communicator.
368 struct Queue *queue_head;
371 * Tail of DLL of queues offered by this communicator.
373 struct Queue *queue_tail;
376 * Head of list of the addresses of this peer offered by this communicator.
378 struct AddressListEntry *addr_head;
381 * Tail of list of the addresses of this peer offered by this communicator.
383 struct AddressListEntry *addr_tail;
393 * Head of linked list of all clients to this service.
395 static struct TransportClient *clients_head;
398 * Tail of linked list of all clients to this service.
400 static struct TransportClient *clients_tail;
405 struct GNUNET_STATISTICS_Handle *GST_stats;
408 * Configuration handle.
410 const struct GNUNET_CONFIGURATION_Handle *GST_cfg;
415 struct GNUNET_PeerIdentity GST_my_identity;
420 struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key;
423 * Map from PIDs to `struct Neighbour` entries. A peer is
424 * a neighbour if we have an MQ to it from some communicator.
426 static struct GNUNET_CONTAINER_MultiPeerMap *neighbours;
430 * Lookup neighbour record for peer @a pid.
432 * @param pid neighbour to look for
433 * @return NULL if we do not have this peer as a neighbour
435 static struct Neighbour *
436 lookup_neighbour (const struct GNUNET_PeerIdentity *pid)
438 return GNUNET_CONTAINER_multipeermap_get (neighbours,
444 * Called whenever a client connects. Allocates our
445 * data structures associated with that client.
447 * @param cls closure, NULL
448 * @param client identification of the client
449 * @param mq message queue for the client
450 * @return our `struct TransportClient`
453 client_connect_cb (void *cls,
454 struct GNUNET_SERVICE_Client *client,
455 struct GNUNET_MQ_Handle *mq)
457 struct TransportClient *tc;
459 tc = GNUNET_new (struct TransportClient);
462 GNUNET_CONTAINER_DLL_insert (clients_head,
465 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
466 "Client %p connected\n",
473 * Called whenever a client is disconnected. Frees our
474 * resources associated with that client.
476 * @param cls closure, NULL
477 * @param client identification of the client
478 * @param app_ctx our `struct TransportClient`
481 client_disconnect_cb (void *cls,
482 struct GNUNET_SERVICE_Client *client,
485 struct TransportClient *tc = app_ctx;
487 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
488 "Client %p disconnected, cleaning up.\n",
490 GNUNET_CONTAINER_DLL_remove (clients_head,
499 struct PendingMessage *pm;
501 while (NULL != (pm = tc->details.core.pending_msg_head))
503 GNUNET_CONTAINER_MDLL_remove (client,
504 tc->details.core.pending_msg_head,
505 tc->details.core.pending_msg_tail,
513 case CT_COMMUNICATOR:
514 GNUNET_free (tc->details.communicator.address_prefix);
522 * Initialize a "CORE" client. We got a start message from this
523 * client, so add it to the list of clients for broadcasting of
526 * @param cls the client
527 * @param start the start message that was sent
530 handle_client_start (void *cls,
531 const struct StartMessage *start)
533 struct TransportClient *tc = cls;
536 options = ntohl (start->options);
537 if ( (0 != (1 & options)) &&
539 memcmp (&start->self,
541 sizeof (struct GNUNET_PeerIdentity)) ) )
543 /* client thinks this is a different peer, reject */
545 GNUNET_SERVICE_client_drop (tc->client);
548 if (CT_NONE != tc->type)
551 GNUNET_SERVICE_client_drop (tc->client);
555 GNUNET_SERVICE_client_continue (tc->client);
560 * Client asked for transmission to a peer. Process the request.
562 * @param cls the client
563 * @param obm the send message that was sent
566 check_client_send (void *cls,
567 const struct OutboundMessage *obm)
569 struct TransportClient *tc = cls;
571 const struct GNUNET_MessageHeader *obmm;
573 if (CT_CORE != tc->type)
576 return GNUNET_SYSERR;
578 size = ntohs (obm->header.size) - sizeof (struct OutboundMessage);
579 if (size < sizeof (struct GNUNET_MessageHeader))
582 return GNUNET_SYSERR;
584 obmm = (const struct GNUNET_MessageHeader *) &obm[1];
585 if (size != ntohs (obmm->size))
588 return GNUNET_SYSERR;
595 * Send a response to the @a pm that we have processed a
596 * "send" request with status @a success. We
597 * transmitted @a bytes_physical on the actual wire.
598 * Sends a confirmation to the "core" client responsible
599 * for the original request and free's @a pm.
601 * @param pm handle to the original pending message
602 * @param success status code, #GNUNET_OK on success, #GNUNET_SYSERR
603 * for transmission failure
604 * @param bytes_physical amount of bandwidth consumed
607 client_send_response (struct PendingMessage *pm,
609 uint32_t bytes_physical)
611 struct TransportClient *tc = pm->client;
612 struct Neighbour *target = pm->target;
613 struct GNUNET_MQ_Envelope *env;
614 struct SendOkMessage *som;
618 env = GNUNET_MQ_msg (som,
619 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK);
620 som->success = htonl ((uint32_t) success);
621 som->bytes_msg = htonl (pm->bytes_msg);
622 som->bytes_physical = htonl (bytes_physical);
623 som->peer = target->pid;
624 GNUNET_MQ_send (tc->mq,
626 GNUNET_CONTAINER_MDLL_remove (client,
627 tc->details.core.pending_msg_head,
628 tc->details.core.pending_msg_tail,
631 GNUNET_CONTAINER_MDLL_remove (neighbour,
632 target->pending_msg_head,
633 target->pending_msg_tail,
640 * Client asked for transmission to a peer. Process the request.
642 * @param cls the client
643 * @param obm the send message that was sent
646 handle_client_send (void *cls,
647 const struct OutboundMessage *obm)
649 struct TransportClient *tc = cls;
650 struct PendingMessage *pm;
651 const struct GNUNET_MessageHeader *obmm;
652 struct Neighbour *target;
655 GNUNET_assert (CT_CORE == tc->type);
656 obmm = (const struct GNUNET_MessageHeader *) &obm[1];
657 bytes_msg = ntohs (obmm->size);
658 target = lookup_neighbour (&obm->peer);
661 /* Failure: don't have this peer as a neighbour (anymore).
662 Might have gone down asynchronously, so this is NOT
663 a protocol violation by CORE. Still count the event,
664 as this should be rare. */
665 struct GNUNET_MQ_Envelope *env;
666 struct SendOkMessage *som;
668 env = GNUNET_MQ_msg (som,
669 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK);
670 som->success = htonl (GNUNET_SYSERR);
671 som->bytes_msg = htonl (bytes_msg);
672 som->bytes_physical = htonl (0);
673 som->peer = obm->peer;
674 GNUNET_MQ_send (tc->mq,
676 GNUNET_SERVICE_client_continue (tc->client);
677 GNUNET_STATISTICS_update (GST_stats,
678 "# messages dropped (neighbour unknown)",
683 pm = GNUNET_new (struct PendingMessage);
686 pm->bytes_msg = bytes_msg;
687 GNUNET_CONTAINER_MDLL_insert (neighbour,
688 target->pending_msg_head,
689 target->pending_msg_tail,
691 GNUNET_CONTAINER_MDLL_insert (client,
692 tc->details.core.pending_msg_head,
693 tc->details.core.pending_msg_tail,
695 // FIXME: do the work, continuation with:
696 client_send_response (pm,
703 * Communicator started. Test message is well-formed.
705 * @param cls the client
706 * @param cam the send message that was sent
709 check_communicator_available (void *cls,
710 const struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam)
712 struct TransportClient *tc = cls;
716 if (CT_NONE != tc->type)
719 return GNUNET_SYSERR;
721 tc->type = CT_COMMUNICATOR;
722 size = ntohs (cam->header.size) - sizeof (*cam);
724 return GNUNET_OK; /* receive-only communicator */
725 addr = (const char *) &cam[1];
726 if ('\0' != addr[size-1])
729 return GNUNET_SYSERR;
736 * Communicator started. Process the request.
738 * @param cls the client
739 * @param cam the send message that was sent
742 handle_communicator_available (void *cls,
743 const struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam)
745 struct TransportClient *tc = cls;
748 size = ntohs (cam->header.size) - sizeof (*cam);
750 return; /* receive-only communicator */
751 tc->details.communicator.address_prefix = GNUNET_strdup ((const char *) &cam[1]);
752 GNUNET_SERVICE_client_continue (tc->client);
757 * Address of our peer added. Test message is well-formed.
759 * @param cls the client
760 * @param aam the send message that was sent
763 check_add_address (void *cls,
764 const struct GNUNET_TRANSPORT_AddAddressMessage *aam)
766 struct TransportClient *tc = cls;
770 if (CT_COMMUNICATOR != tc->type)
773 return GNUNET_SYSERR;
775 size = ntohs (aam->header.size) - sizeof (*aam);
779 return GNUNET_SYSERR;
781 addr = (const char *) &aam[1];
782 if ('\0' != addr[size-1])
785 return GNUNET_SYSERR;
792 * Address of our peer added. Process the request.
794 * @param cls the client
795 * @param aam the send message that was sent
798 handle_add_address (void *cls,
799 const struct GNUNET_TRANSPORT_AddAddressMessage *aam)
801 struct TransportClient *tc = cls;
802 struct AddressListEntry *ale;
805 slen = ntohs (aam->header.size) - sizeof (*aam);
806 ale = GNUNET_malloc (sizeof (struct AddressListEntry) + slen);
808 ale->address = (const char *) &ale[1];
809 ale->expiration = GNUNET_TIME_relative_ntoh (aam->expiration);
811 ale->nt = (enum GNUNET_ATS_Network_Type) ntohl (aam->nt);
815 GNUNET_CONTAINER_DLL_insert (tc->details.communicator.addr_head,
816 tc->details.communicator.addr_tail,
818 // FIXME: notify somebody?!
819 GNUNET_SERVICE_client_continue (tc->client);
824 * Address of our peer deleted. Process the request.
826 * @param cls the client
827 * @param dam the send message that was sent
830 handle_del_address (void *cls,
831 const struct GNUNET_TRANSPORT_DelAddressMessage *dam)
833 struct TransportClient *tc = cls;
835 if (CT_COMMUNICATOR != tc->type)
838 GNUNET_SERVICE_client_drop (tc->client);
841 for (struct AddressListEntry *ale = tc->details.communicator.addr_head;
845 if (dam->aid != ale->aid)
847 GNUNET_assert (ale->tc == tc);
848 GNUNET_CONTAINER_DLL_remove (tc->details.communicator.addr_head,
849 tc->details.communicator.addr_tail,
851 // FIXME: notify somebody?
853 GNUNET_SERVICE_client_continue (tc->client);
856 GNUNET_SERVICE_client_drop (tc->client);
861 * Client notified us about transmission from a peer. Process the request.
863 * @param cls the client
864 * @param obm the send message that was sent
867 check_incoming_msg (void *cls,
868 const struct GNUNET_TRANSPORT_IncomingMessage *im)
870 struct TransportClient *tc = cls;
872 const struct GNUNET_MessageHeader *obmm;
874 if (CT_COMMUNICATOR != tc->type)
877 return GNUNET_SYSERR;
879 size = ntohs (im->header.size) - sizeof (*im);
880 if (size < sizeof (struct GNUNET_MessageHeader))
883 return GNUNET_SYSERR;
885 obmm = (const struct GNUNET_MessageHeader *) &im[1];
886 if (size != ntohs (obmm->size))
889 return GNUNET_SYSERR;
896 * Incoming meessage. Process the request.
898 * @param cls the client
899 * @param im the send message that was received
902 handle_incoming_msg (void *cls,
903 const struct GNUNET_TRANSPORT_IncomingMessage *im)
905 struct TransportClient *tc = cls;
907 GNUNET_SERVICE_client_continue (tc->client);
912 * New queue became available. Check message.
914 * @param cls the client
915 * @param aqm the send message that was sent
918 check_add_queue_message (void *cls,
919 const struct GNUNET_TRANSPORT_AddQueueMessage *aqm)
921 struct TransportClient *tc = cls;
925 if (CT_COMMUNICATOR != tc->type)
928 return GNUNET_SYSERR;
930 size = ntohs (aqm->header.size) - sizeof (*aqm);
934 return GNUNET_SYSERR;
936 addr = (const char *) &aqm[1];
937 if ('\0' != addr[size-1])
940 return GNUNET_SYSERR;
947 * New queue became available. Process the request.
949 * @param cls the client
950 * @param aqm the send message that was sent
953 handle_add_queue_message (void *cls,
954 const struct GNUNET_TRANSPORT_AddQueueMessage *aqm)
956 struct TransportClient *tc = cls;
958 struct Neighbour *neighbour;
962 neighbour = lookup_neighbour (&aqm->receiver);
963 if (NULL == neighbour)
965 neighbour = GNUNET_new (struct Neighbour);
966 neighbour->pid = aqm->receiver;
967 GNUNET_assert (GNUNET_OK ==
968 GNUNET_CONTAINER_multipeermap_put (neighbours,
971 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
972 // FIXME: notify ATS/COREs/monitors!
974 addr_len = ntohs (aqm->header.size) - sizeof (*aqm);
975 addr = (const char *) &aqm[1];
977 queue = GNUNET_malloc (sizeof (struct Queue) + addr_len);
978 queue->qid = aqm->qid;
979 queue->nt = (enum GNUNET_ATS_Network_Type) ntohl (aqm->nt);
981 queue->neighbour = neighbour;
982 queue->address = (const char *) &queue[1];
986 GNUNET_CONTAINER_MDLL_insert (neighbour,
987 neighbour->queue_head,
988 neighbour->queue_tail,
990 GNUNET_CONTAINER_MDLL_insert (client,
991 tc->details.communicator.queue_head,
992 tc->details.communicator.queue_tail,
994 // FIXME: possibly transmit queued messages?
995 GNUNET_SERVICE_client_continue (tc->client);
1000 * Release memory used by @a neighbour.
1002 * @param neighbour neighbour entry to free
1005 free_neighbour (struct Neighbour *neighbour)
1007 GNUNET_assert (NULL == neighbour->queue_head);
1008 GNUNET_assert (GNUNET_YES ==
1009 GNUNET_CONTAINER_multipeermap_remove (neighbours,
1012 GNUNET_free (neighbour);
1017 * Queue to a peer went down. Process the request.
1019 * @param cls the client
1020 * @param dqm the send message that was sent
1023 handle_del_queue_message (void *cls,
1024 const struct GNUNET_TRANSPORT_DelQueueMessage *dqm)
1026 struct TransportClient *tc = cls;
1028 if (CT_COMMUNICATOR != tc->type)
1031 GNUNET_SERVICE_client_drop (tc->client);
1034 for (struct Queue *queue = tc->details.communicator.queue_head;
1036 queue = queue->next_client)
1038 struct Neighbour *neighbour = queue->neighbour;
1040 if ( (dqm->qid != queue->qid) ||
1041 (0 != memcmp (&dqm->receiver,
1043 sizeof (struct GNUNET_PeerIdentity))) )
1045 GNUNET_CONTAINER_MDLL_remove (neighbour,
1046 neighbour->queue_head,
1047 neighbour->queue_tail,
1049 GNUNET_CONTAINER_MDLL_remove (client,
1050 tc->details.communicator.queue_head,
1051 tc->details.communicator.queue_tail,
1053 GNUNET_free (queue);
1054 if (NULL == neighbour->queue_head)
1056 // FIXME: notify cores/monitors!
1057 free_neighbour (neighbour);
1059 GNUNET_SERVICE_client_continue (tc->client);
1063 GNUNET_SERVICE_client_drop (tc->client);
1068 * Message was transmitted. Process the request.
1070 * @param cls the client
1071 * @param sma the send message that was sent
1074 handle_send_message_ack (void *cls,
1075 const struct GNUNET_TRANSPORT_SendMessageToAck *sma)
1077 struct TransportClient *tc = cls;
1079 if (CT_COMMUNICATOR != tc->type)
1082 GNUNET_SERVICE_client_drop (tc->client);
1085 GNUNET_SERVICE_client_continue (tc->client);
1090 * Initialize a monitor client.
1092 * @param cls the client
1093 * @param start the start message that was sent
1096 handle_monitor_start (void *cls,
1097 const struct GNUNET_TRANSPORT_MonitorStart *start)
1099 struct TransportClient *tc = cls;
1101 if (CT_NONE != tc->type)
1104 GNUNET_SERVICE_client_drop (tc->client);
1107 tc->type = CT_MONITOR;
1108 tc->details.monitor.peer = start->peer;
1109 tc->details.monitor.one_shot = ntohl (start->one_shot);
1111 GNUNET_SERVICE_client_continue (tc->client);
1116 * Free neighbour entry.
1120 * @param value a `struct Neighbour`
1121 * @return #GNUNET_OK (always)
1124 free_neighbour_cb (void *cls,
1125 const struct GNUNET_PeerIdentity *pid,
1128 struct Neighbour *neighbour = value;
1132 GNUNET_break (0); // should this ever happen?
1133 free_neighbour (neighbour);
1140 * Function called when the service shuts down. Unloads our plugins
1141 * and cancels pending validations.
1143 * @param cls closure, unused
1146 do_shutdown (void *cls)
1150 if (NULL != GST_stats)
1152 GNUNET_STATISTICS_destroy (GST_stats,
1156 if (NULL != GST_my_private_key)
1158 GNUNET_free (GST_my_private_key);
1159 GST_my_private_key = NULL;
1161 GNUNET_CONTAINER_multipeermap_iterate (neighbours,
1164 GNUNET_CONTAINER_multipeermap_destroy (neighbours);
1169 * Initiate transport service.
1171 * @param cls closure
1172 * @param c configuration to use
1173 * @param service the initialized service
1177 const struct GNUNET_CONFIGURATION_Handle *c,
1178 struct GNUNET_SERVICE_Handle *service)
1183 neighbours = GNUNET_CONTAINER_multipeermap_create (1024,
1185 GST_my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (GST_cfg);
1186 if (NULL == GST_my_private_key)
1188 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1189 _("Transport service is lacking key configuration settings. Exiting.\n"));
1190 GNUNET_SCHEDULER_shutdown ();
1193 GNUNET_CRYPTO_eddsa_key_get_public (GST_my_private_key,
1194 &GST_my_identity.public_key);
1195 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1196 "My identity is `%s'\n",
1197 GNUNET_i2s_full (&GST_my_identity));
1199 GST_stats = GNUNET_STATISTICS_create ("transport",
1201 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
1203 /* start subsystems */
1208 * Define "main" method using service macro.
1212 GNUNET_SERVICE_OPTION_NONE,
1215 &client_disconnect_cb,
1217 /* communication with core */
1218 GNUNET_MQ_hd_fixed_size (client_start,
1219 GNUNET_MESSAGE_TYPE_TRANSPORT_START,
1220 struct StartMessage,
1222 GNUNET_MQ_hd_var_size (client_send,
1223 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND,
1224 struct OutboundMessage,
1226 /* communication with communicators */
1227 GNUNET_MQ_hd_var_size (communicator_available,
1228 GNUNET_MESSAGE_TYPE_TRANSPORT_NEW_COMMUNICATOR,
1229 struct GNUNET_TRANSPORT_CommunicatorAvailableMessage,
1231 GNUNET_MQ_hd_var_size (add_address,
1232 GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_ADDRESS,
1233 struct GNUNET_TRANSPORT_AddAddressMessage,
1235 GNUNET_MQ_hd_fixed_size (del_address,
1236 GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_ADDRESS,
1237 struct GNUNET_TRANSPORT_DelAddressMessage,
1239 GNUNET_MQ_hd_var_size (incoming_msg,
1240 GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG,
1241 struct GNUNET_TRANSPORT_IncomingMessage,
1243 GNUNET_MQ_hd_var_size (add_queue_message,
1244 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_SETUP,
1245 struct GNUNET_TRANSPORT_AddQueueMessage,
1247 GNUNET_MQ_hd_fixed_size (del_queue_message,
1248 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_TEARDOWN,
1249 struct GNUNET_TRANSPORT_DelQueueMessage,
1251 GNUNET_MQ_hd_fixed_size (send_message_ack,
1252 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG_ACK,
1253 struct GNUNET_TRANSPORT_SendMessageToAck,
1255 /* communication with monitors */
1256 GNUNET_MQ_hd_fixed_size (monitor_start,
1257 GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_START,
1258 struct GNUNET_TRANSPORT_MonitorStart,
1260 GNUNET_MQ_handler_end ());
1263 /* end of file gnunet-service-transport.c */