2 This file is part of GNUnet.
3 (C) 2001 - 2011 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file mesh/gnunet-service-mesh.c
23 * @brief GNUnet MESH service
24 * @author Bartlomiej Polot
27 * - MESH NETWORK MESSAGES
30 * - MESH NETWORK HANDLES
31 * - MESH LOCAL HANDLES
32 * - MAIN FUNCTIONS (main & run)
35 * - soft stateing (keep-alive (CHANGE?) / timeout / disconnect) -- not a message issue
36 * - error reporting (CREATE/CHANGE/ADD/DEL?) -- new message!
37 * - partial disconnect reporting -- same as error reporting?
38 * - add vs create? change vs. keep-alive? same msg or different ones? -- thinking...
39 * - speed requirement specification (change?) in mesh API -- API call
43 #include "gnunet_common.h"
44 #include "gnunet_util_lib.h"
45 #include "gnunet_peer_lib.h"
46 #include "gnunet_core_service.h"
47 #include "gnunet_protocols.h"
50 #include "gnunet_dht_service.h"
52 /******************************************************************************/
53 /******************** MESH NETWORK MESSAGES **************************/
54 /******************************************************************************/
57 * Message for mesh path management
59 struct GNUNET_MESH_ManipulatePath
62 * Type: GNUNET_MESSAGE_TYPE_MESH_PATH_[CREATE|CHANGE|ADD|DEL]
64 * Size: sizeof(struct GNUNET_MESH_ManipulatePath) +
65 * path_length * sizeof (struct GNUNET_PeerIdentity)
67 struct GNUNET_MessageHeader header;
70 * Global id of the tunnel this path belongs to,
71 * unique in conjunction with the origin.
73 uint32_t tid GNUNET_PACKED;
76 * Information about speed requirements. If the tunnel cannot sustain the
77 * minimum bandwidth, packets are to be dropped.
79 uint32_t speed_min GNUNET_PACKED;
84 uint32_t reserved GNUNET_PACKED;
87 * path_length structs defining the *whole* path from the origin [0] to the
88 * final destination [path_length-1].
90 /* struct GNUNET_PeerIdentity peers[path_length]; */
94 * Message for mesh data traffic to all tunnel targets.
96 struct GNUNET_MESH_OriginMulticast
99 * Type: GNUNET_MESSAGE_TYPE_DATA_MULTICAST
101 struct GNUNET_MessageHeader header;
106 uint32_t tid GNUNET_PACKED;
111 struct GNUNET_PeerIdentity oid;
120 * Message for mesh data traffic to a particular destination from origin.
122 struct GNUNET_MESH_DataMessageFromOrigin
125 * Type: GNUNET_MESSAGE_TYPE_DATA_MESSAGE_FROM_ORIGIN
127 struct GNUNET_MessageHeader header;
132 uint32_t tid GNUNET_PACKED;
137 struct GNUNET_PeerIdentity oid;
142 struct GNUNET_PeerIdentity destination;
151 * Message for mesh data traffic from a tunnel participant to origin.
153 struct GNUNET_MESH_DataMessageToOrigin
156 * Type: GNUNET_MESSAGE_TYPE_DATA_MESSAGE_TO_ORIGIN
158 struct GNUNET_MessageHeader header;
163 uint32_t tid GNUNET_PACKED;
168 struct GNUNET_PeerIdentity oid;
171 * Sender of the message.
173 struct GNUNET_PeerIdentity sender;
181 * Message for mesh flow control
183 struct GNUNET_MESH_SpeedNotify
186 * Type: GNUNET_MESSAGE_TYPE_DATA_SPEED_NOTIFY
188 struct GNUNET_MessageHeader header;
193 uint32_t tid GNUNET_PACKED;
198 struct GNUNET_PeerIdentity oid;
201 * Slowest link down the path (above minimum speed requirement).
207 /******************************************************************************/
208 /************************ DATA STRUCTURES ****************************/
209 /******************************************************************************/
212 * All the states a peer participating in a tunnel can be in.
217 * Request sent, not yet answered.
222 * Peer connected and ready to accept data
227 * Peer connected previosly but not responding
229 MESH_PEER_RECONNECTING,
234 * Struct containing all information regarding a given peer
241 struct PeerInfo *next;
242 struct PeerInfo *prev;
250 * Is the peer reachable? Is the peer even connected?
252 enum PeerState state;
255 * When to try to establish contact again?
257 struct GNUNET_TIME_Absolute next_reconnect_attempt;
260 * Who to send the data to --- FIXME what about multiple (alternate) paths?
262 GNUNET_PEER_Id first_hop;
265 * Max data rate to this peer
271 typedef uint32_t MESH_PathID;
273 * Information regarding a path
284 * Id of the path, in case it's needed
289 * Whether the path is serving traffic in a tunnel or is a backup
294 * List of all the peers that form the path from origin to target
296 GNUNET_PEER_Id *peers;
305 struct MESH_queue *next;
306 struct MESH_queue *prev;
309 * Size of the message to transmit
314 * How old is the data?
316 struct GNUNET_TIME_Absolute timestamp;
321 struct GNUNET_MessageHeader *data;
325 struct Client; /* FWD declaration */
327 * Struct containing all information regarding a tunnel
328 * For an intermediate node the improtant info used will be:
329 * - OID \ To identify
331 * - paths[0] | To know where to send it next
332 * - metainfo: ready, speeds, accounting
333 * For an end node more fields will be needed (client-handling)
341 struct MESH_tunnel *next;
342 struct MESH_tunnel *prev;
345 * Origin ID: Node that created the tunnel
350 * Tunnel number (unique for a given oid)
355 * Minimal speed for this tunnel in kb/s
360 * Maximal speed for this tunnel in kb/s
365 * Last time the tunnel was used
367 struct GNUNET_TIME_Absolute timestamp;
370 * Peers in the tunnel, for future optimizations
372 struct PeerInfo *peers_head;
373 struct PeerInfo *peers_tail;
376 * Number of peers that are connected and potentially ready to receive data
378 unsigned int peers_ready;
381 * Number of peers that have been added to the tunnel
383 unsigned int peers_total;
386 * Paths (used and backup)
388 struct Path *paths_head;
389 struct Path *paths_tail;
392 * If this tunnel was created by a local client, what's its handle?
394 struct Client *client;
397 * Messages ready to transmit
399 struct MESH_queue *out_head;
400 struct MESH_queue *out_tail;
403 * Messages received and not processed
405 struct MESH_queue *in_head;
406 struct MESH_queue *in_tail;
411 * Struct containing information about a client of the service
422 * Tunnels that belong to this client, for convenience on disconnect
424 struct MESH_tunnel *tunnels_head;
425 struct MESH_tunnel *tunnels_tail;
428 * Handle to communicate with the client
430 struct GNUNET_SERVER_Client *handle;
433 * Messages that this client has declared interest in
435 GNUNET_MESH_ApplicationType *messages_subscribed;
436 unsigned int subscription_counter;
440 /******************************************************************************/
441 /*********************** GLOBAL VARIABLES ****************************/
442 /******************************************************************************/
447 static struct Client *clients_head;
448 static struct Client *clients_tail;
451 * Handle to communicate with core
453 static struct GNUNET_CORE_Handle *core_handle;
458 static struct GNUNET_DHT_Handle *dht_handle;
461 * Local peer own ID (memory efficient handle)
463 static GNUNET_PEER_Id myid;
465 /******************************************************************************/
466 /******************** MESH NETWORK HANDLERS **************************/
467 /******************************************************************************/
470 * Core handler for path creation
471 * struct GNUNET_CORE_MessageHandler
474 * @param message message
475 * @param peer peer identity this notification is about
476 * @param atsi performance data
477 * @return GNUNET_OK to keep the connection open,
478 * GNUNET_SYSERR to close it (signal serious error)
482 handle_mesh_path_create (void *cls,
483 const struct GNUNET_PeerIdentity *peer,
484 const struct GNUNET_MessageHeader *message,
485 const struct GNUNET_TRANSPORT_ATS_Information
489 /* Find origin & self */
490 /* Search for origin in local tunnels */
491 /* Create tunnel / add path */
492 /* Retransmit to next link in chain, if any (core_notify + callback) */
497 * Core handler for mesh network traffic
500 * @param message message
501 * @param peer peer identity this notification is about
502 * @param atsi performance data
503 * @return GNUNET_OK to keep the connection open,
504 * GNUNET_SYSERR to close it (signal serious error)
507 handle_mesh_network_traffic (void *cls,
508 const struct GNUNET_PeerIdentity *peer,
509 const struct GNUNET_MessageHeader *message,
510 const struct GNUNET_TRANSPORT_ATS_Information
513 if(GNUNET_MESSAGE_TYPE_MESH_DATA_GO == ntohs(message->type)) {
514 /* Retransmit to next in path of tunnel identified by message */
516 } else { /* GNUNET_MESSAGE_TYPE_MESH_DATA_BACK */
517 /* Retransmit to previous in path of tunnel identified by message */
523 * Functions to handle messages from core
525 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
526 {&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 0},
527 {&handle_mesh_network_traffic, GNUNET_MESSAGE_TYPE_MESH_DATA_GO, 0},
528 {&handle_mesh_network_traffic, GNUNET_MESSAGE_TYPE_MESH_DATA_BACK, 0},
534 /******************************************************************************/
535 /********************* MESH LOCAL HANDLES **************************/
536 /******************************************************************************/
539 * Check if client has registered with the service and has not disconnected
540 * @param client the client to check
541 * @return non-NULL if client exists in the global DLL
544 client_retrieve (struct GNUNET_SERVER_Client *client) {
548 if(c->handle == client) return c;
549 if(c == clients_tail)
558 * Handler for client disconnection
561 * @param client identification of the client; NULL
562 * for the last call when the server is destroyed
565 handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
567 struct Client *c, *next;
568 struct MESH_tunnel *t;
570 /* If there are no clients registered, something is wrong... or is it?
571 * FIXME: what happens if a client connects, doesn't send a MESH_Connect
572 * and disconnects? Does the service get a disconnect notification anyway?
574 GNUNET_assert(NULL != clients_head);
577 if (c->handle == client) {
578 GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, c);
579 while (NULL != (t = c->tunnels_head)) {
580 GNUNET_CONTAINER_DLL_remove (c->tunnels_head, c->tunnels_tail, t);
581 /* TODO free paths and other tunnel dynamic structures */
584 GNUNET_free (c->messages_subscribed);
591 if(c == clients_head) return; /* Tail already processed? */
597 * Handler for new clients
600 * @param client identification of the client
601 * @param message the actual message, which includes messages the client wants
604 handle_local_new_client (void *cls,
605 struct GNUNET_SERVER_Client *client,
606 const struct GNUNET_MessageHeader *message)
609 unsigned int payload_size;
611 /* Check data sanity */
612 payload_size = message->size - sizeof(struct GNUNET_MessageHeader);
613 if (0 != payload_size % sizeof(GNUNET_MESH_ApplicationType)) {
615 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
619 /* Create new client structure */
620 c = GNUNET_malloc(sizeof(struct Client));
622 c->tunnels_head = NULL;
623 c->tunnels_tail = NULL;
624 if(payload_size != 0) {
625 c->messages_subscribed = GNUNET_malloc(payload_size);
626 memcpy(c->messages_subscribed, &message[1], payload_size);
628 c->messages_subscribed = NULL;
630 c->subscription_counter = payload_size/sizeof(GNUNET_MESH_ApplicationType);
632 /* Insert new client in DLL */
633 GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, c);
635 GNUNET_SERVER_receive_done(client, GNUNET_OK);
639 * Handler for requests of new tunnels
642 * @param client identification of the client
643 * @param message the actual message
646 handle_local_tunnel_create (void *cls,
647 struct GNUNET_SERVER_Client *client,
648 const struct GNUNET_MessageHeader *message)
650 struct GNUNET_MESH_TunnelMessage *tunnel_msg;
651 struct MESH_tunnel *t;
654 /* Sanity check for client registration */
655 if(NULL == (c = client_retrieve(client))) {
657 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
661 /* Message sanity check */
662 if(sizeof(struct GNUNET_MESH_TunnelMessage) != ntohs(message->size)) {
664 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
668 tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
669 /* Sanity check for tunnel numbering */
670 if(0 == (ntohl(tunnel_msg->tunnel_id) & 0x80000000)) {
672 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
675 /* Sanity check for duplicate tunnel IDs */
678 if(t->tid == ntohl(tunnel_msg->tunnel_id)) {
680 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
683 if(t == c->tunnels_tail) break;
686 /* FIXME: calloc? Is NULL != 0 on any platform? */
687 t = GNUNET_malloc(sizeof(struct MESH_tunnel));
688 t->tid = ntohl(tunnel_msg->tunnel_id);
692 t->peers_head = NULL;
693 t->peers_tail = NULL;
694 t->paths_head = NULL;
695 t->paths_tail = NULL;
702 GNUNET_CONTAINER_DLL_insert(c->tunnels_head, c->tunnels_tail, t);
704 GNUNET_SERVER_receive_done(client, GNUNET_OK);
709 * Handler for requests of deleting tunnels
712 * @param client identification of the client
713 * @param message the actual message
716 handle_local_tunnel_destroy (void *cls,
717 struct GNUNET_SERVER_Client *client,
718 const struct GNUNET_MessageHeader *message)
720 struct GNUNET_MESH_TunnelMessage *tunnel_msg;
722 struct MESH_tunnel *t;
726 /* Sanity check for client registration */
727 if(NULL == (c = client_retrieve(client))) {
729 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
732 /* Message sanity check */
733 if(sizeof(struct GNUNET_MESH_TunnelMessage) != ntohs(message->size)) {
735 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
739 tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
742 tid = ntohl(tunnel_msg->tunnel_id);
743 if(NULL == (t = c->tunnels_head)) {
745 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
752 if(t == c->tunnels_tail) {
754 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
760 GNUNET_CONTAINER_DLL_remove(c->tunnels_head, c->tunnels_tail, t);
762 for(pi = t->peers_head; pi != NULL; pi = t->peers_head) {
763 GNUNET_PEER_change_rc(pi->id, -1);
764 GNUNET_CONTAINER_DLL_remove(t->peers_head, t->peers_tail, pi);
769 GNUNET_SERVER_receive_done(client, GNUNET_OK);
774 * Handler for connection requests to new peers
777 * @param client identification of the client
778 * @param message the actual message (PeerControl)
781 handle_local_connect_add (void *cls,
782 struct GNUNET_SERVER_Client *client,
783 const struct GNUNET_MessageHeader *message)
785 struct GNUNET_MESH_PeerControl *peer_msg;
787 struct MESH_tunnel *t;
789 struct PeerInfo *peer_info;
792 /* Sanity check for client registration */
793 if(NULL == (c = client_retrieve(client))) {
795 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
799 peer_msg = (struct GNUNET_MESH_PeerControl *)message;
800 /* Sanity check for message size */
801 if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(peer_msg->header.size)) {
803 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
808 tid = ntohl(peer_msg->tunnel_id);
809 if(NULL == (t = c->tunnels_head)) {
811 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
818 if(t == c->tunnels_tail) {
820 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
826 /* Does client own tunnel? */
827 if(t->client->handle != client) {
829 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
833 /* Ok, add peer to tunnel */
834 peer_info = (struct PeerInfo *) GNUNET_malloc(sizeof(struct PeerInfo));
835 peer_info->id = GNUNET_PEER_intern(&peer_msg->peer);
836 peer_info->state = MESH_PEER_WAITING;
838 GNUNET_CONTAINER_DLL_insert(t->peers_head, t->peers_tail, peer_info);
839 /* TODO MESH SEARCH FOR PEER */
841 GNUNET_SERVER_receive_done(client, GNUNET_OK);
847 * Handler for disconnection requests of peers in a tunnel
850 * @param client identification of the client
851 * @param message the actual message (PeerControl)
854 handle_local_connect_del (void *cls,
855 struct GNUNET_SERVER_Client *client,
856 const struct GNUNET_MessageHeader *message)
858 struct GNUNET_MESH_PeerControl *peer_msg;
860 struct MESH_tunnel *t;
862 struct Path *aux_path;
864 GNUNET_PEER_Id peer_id;
865 struct PeerInfo *peer_info;
866 struct PeerInfo *aux_peer_info;
868 /* Sanity check for client registration */
869 if(NULL == (c = client_retrieve(client))) {
871 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
874 peer_msg = (struct GNUNET_MESH_PeerControl *)message;
875 /* Sanity check for message size */
876 if(sizeof(struct GNUNET_MESH_PeerControl) != ntohs(peer_msg->header.size)) {
878 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
883 tid = ntohl(peer_msg->tunnel_id);
884 if(NULL == (t = c->tunnels_head)) {
886 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
893 if(t == c->tunnels_tail) {
895 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
901 /* Does client own tunnel? */
902 if(t->client->handle != client) {
904 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
908 /* Ok, delete peer from tunnel */
910 peer_id = GNUNET_PEER_intern(&peer_msg->peer);
914 if(p->peers[p->length-1] == peer_id) {
915 GNUNET_CONTAINER_DLL_remove(t->paths_head, t->paths_tail, p);
916 GNUNET_PEER_decrement_rcs(p->peers, p->length);
919 GNUNET_free(aux_path);
923 if(p == t->paths_head) {
928 /*Delete peer info */
929 peer_info = t->peers_head;
930 while(peer_info != NULL) {
931 if(peer_info->id == peer_id) {
932 GNUNET_CONTAINER_DLL_remove(t->peers_head,
935 aux_peer_info = peer_info;
936 peer_info = peer_info->next;
937 GNUNET_free(aux_peer_info);
939 peer_info = peer_info->next;
941 if(peer_info == t->peers_head) {
946 GNUNET_PEER_change_rc(peer_id, -1);
948 GNUNET_SERVER_receive_done(client, GNUNET_OK);
954 * Handler for connection requests to new peers by type
957 * @param client identification of the client
958 * @param message the actual message (ConnectPeerByType)
961 handle_local_connect_by_type (void *cls,
962 struct GNUNET_SERVER_Client *client,
963 const struct GNUNET_MessageHeader *message)
965 /* Sanity check for client registration */
966 if(NULL == client_retrieve(client)) {
968 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
971 GNUNET_SERVER_receive_done(client, GNUNET_OK);
977 * Handler for client traffic directed to one peer
980 * @param client identification of the client
981 * @param message the actual message
984 handle_local_network_traffic (void *cls,
985 struct GNUNET_SERVER_Client *client,
986 const struct GNUNET_MessageHeader *message)
988 /* Sanity check for client registration */
989 if(NULL == client_retrieve(client)) {
991 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
994 GNUNET_SERVER_receive_done(client, GNUNET_OK);
999 * Handler for client traffic directed to all peers in a tunnel
1001 * @param cls closure
1002 * @param client identification of the client
1003 * @param message the actual message
1006 handle_local_network_traffic_bcast (void *cls,
1007 struct GNUNET_SERVER_Client *client,
1008 const struct GNUNET_MessageHeader *message)
1010 /* Sanity check for client registration */
1011 if(NULL == client_retrieve(client)) {
1013 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1016 GNUNET_SERVER_receive_done(client, GNUNET_OK);
1021 * Functions to handle messages from clients
1023 static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = {
1024 {&handle_local_new_client, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT, 0},
1025 {&handle_local_tunnel_create, NULL,
1026 GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE, 0},
1027 {&handle_local_tunnel_destroy, NULL,
1028 GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY, 0},
1029 {&handle_local_connect_add, NULL,
1030 GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_ADD, 0},
1031 {&handle_local_connect_del, NULL,
1032 GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_DEL, 0},
1033 {&handle_local_connect_by_type, NULL,
1034 GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_BY_TYPE,
1035 sizeof(struct GNUNET_MESH_ConnectPeerByType)},
1036 {&handle_local_network_traffic, NULL,
1037 GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA, 0},
1038 {&handle_local_network_traffic_bcast, NULL,
1039 GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA_BROADCAST, 0},
1045 * To be called on core init/fail.
1047 * @param cls service closure
1048 * @param server handle to the server for this service
1049 * @param identity the public identity of this peer
1050 * @param publicKey the public key of this peer
1053 core_init (void *cls,
1054 struct GNUNET_CORE_Handle *server,
1055 const struct GNUNET_PeerIdentity *identity,
1056 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey)
1058 core_handle = server;
1059 myid = GNUNET_PEER_intern(identity);
1064 * Method called whenever a given peer connects.
1066 * @param cls closure
1067 * @param peer peer identity this notification is about
1068 * @param atsi performance data for the connection
1071 core_connect (void *cls,
1072 const struct GNUNET_PeerIdentity *peer,
1073 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1079 * Method called whenever a peer disconnects.
1081 * @param cls closure
1082 * @param peer peer identity this notification is about
1085 core_disconnect (void *cls,
1087 GNUNET_PeerIdentity *peer)
1092 /******************************************************************************/
1093 /************************ MAIN FUNCTIONS ****************************/
1094 /******************************************************************************/
1097 * Process mesh requests. FIXME NON FUNCTIONAL, SKELETON
1099 * @param cls closure
1100 * @param server the initialized server
1101 * @param c configuration to use
1105 struct GNUNET_SERVER_Handle *server,
1106 const struct GNUNET_CONFIGURATION_Handle *c)
1109 GNUNET_SERVER_add_handlers (server, plugin_handlers);
1110 GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
1111 core_handle = GNUNET_CORE_connect (c, /* Main configuration */
1112 32, /* queue size */
1113 NULL, /* Closure passed to MESH functions */
1114 &core_init, /* Call core_init once connected */
1115 &core_connect, /* Handle connects */
1116 &core_disconnect, /* remove peers on disconnects */
1117 NULL, /* Do we care about "status" updates? */
1118 NULL, /* Don't notify about all incoming messages */
1119 GNUNET_NO, /* For header only in notification */
1120 NULL, /* Don't notify about all outbound messages */
1121 GNUNET_NO, /* For header-only out notification */
1122 core_handlers); /* Register these handlers */
1124 if (core_handle == NULL) {
1128 dht_handle = GNUNET_DHT_connect(c, 100); /* FIXME ht len correct size? */
1129 if (dht_handle == NULL) {
1135 * The main function for the mesh service.
1137 * @param argc number of arguments from the command line
1138 * @param argv command line arguments
1139 * @return 0 ok, 1 on error
1142 main (int argc, char *const *argv)
1147 GNUNET_SERVICE_run (argc,
1150 GNUNET_SERVICE_OPTION_NONE,
1151 &run, NULL)) ? 0 : 1;