2 This file is part of GNUnet.
3 (C) 2001-2013 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-enc.c
23 * @brief GNUnet MESH service with encryption
24 * @author Bartlomiej Polot
27 * - when sending in-order buffered data, wait for client ACKs
30 * - set connection IDs independently from tunnel, tunnel has no ID
33 * - relay corking down to core
34 * - set ttl relative to path length
38 * - peer: other mesh instance. If there is direct connection it's a neighbor.
39 * - tunnel: encrypted connection to a peer, neighbor or not.
40 * - channel: connection between two clients, on the same or different peers.
41 * have properties like reliability.
42 * - path: series of directly connected peer from one peer to another.
43 * - connection: path which is being used in a tunnel.
47 #include "gnunet_util_lib.h"
49 #include "block_mesh.h"
50 #include "gnunet_statistics_service.h"
52 #include "gnunet-service-mesh_local.h"
53 #include "gnunet-service-mesh_channel.h"
54 #include "gnunet-service-mesh_connection.h"
55 #include "gnunet-service-mesh_dht.h"
56 #include "gnunet-service-mesh_peer.h"
58 #define MESH_BLOOM_SIZE 128
61 #define MESH_DEBUG_TIMING __LINUX__ && GNUNET_NO
68 struct timespec __mesh_start;
69 struct timespec __mesh_end;
70 #define INTERVAL_START clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &(__mesh_start))
71 #define INTERVAL_END \
73 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &(__mesh_end));\
74 double __diff = __mesh_end.tv_nsec - __mesh_start.tv_nsec;\
75 if (__diff < 0) __diff += 1000000000;\
79 #define INTERVAL_SHOW \
81 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "AVG process time: %f ns\n", __sum/__count)
83 #define INTERVAL_START
89 * All the states a tunnel can be in.
94 * Uninitialized status, should never appear in operation.
99 * Path to the peer not known yet
101 MESH_TUNNEL_SEARCHING,
104 * Request sent, not yet answered.
109 * Peer connected and ready to accept data
114 * Peer connected previosly but not responding
116 MESH_TUNNEL_RECONNECTING
121 /******************************************************************************/
122 /************************ DATA STRUCTURES ****************************/
123 /******************************************************************************/
125 /** FWD declaration */
130 * Struct used to queue messages in a tunnel.
132 struct MeshTunnelQueue
137 struct MeshTunnelQueue *next;
138 struct MeshTunnelQueue *prev;
143 struct MeshChannel *ch;
148 /* struct GNUNET_MessageHeader *msg; */
153 * Struct containing all information regarding a tunnel to a peer.
158 * Endpoint of the tunnel.
160 struct MeshPeer *peer;
163 * State of the tunnel.
165 enum MeshTunnelState state;
168 * Local peer ephemeral private key
170 struct GNUNET_CRYPTO_EccPrivateKey *my_eph_key;
173 * Local peer ephemeral public key
175 struct GNUNET_CRYPTO_EccPublicSignKey *my_eph;
178 * Remote peer's public key.
180 struct GNUNET_CRYPTO_EccPublicSignKey *peers_eph;
183 * Encryption ("our") key.
185 struct GNUNET_CRYPTO_SymmetricSessionKey e_key;
188 * Decryption ("their") key.
190 struct GNUNET_CRYPTO_SymmetricSessionKey d_key;
193 * Paths that are actively used to reach the destination peer.
195 struct MeshConnection *connection_head;
196 struct MeshConnection *connection_tail;
199 * Next connection number.
204 * Channels inside this tunnel.
206 struct MeshChannel *channel_head;
207 struct MeshChannel *channel_tail;
210 * Channel ID for the next created channel.
212 MESH_ChannelNumber next_chid;
215 * Channel ID for the next incoming channel.
217 MESH_ChannelNumber next_local_chid;
220 * Pending message count.
222 int pending_messages;
225 * Destroy flag: if true, destroy on last message.
230 * Queued messages, to transmit once tunnel gets connected.
232 struct MeshTunnelQueue *tq_head;
233 struct MeshTunnelQueue *tq_tail;
238 /******************************************************************************/
239 /************************ DEBUG FUNCTIONS ****************************/
240 /******************************************************************************/
244 * GNUNET_SCHEDULER_Task for printing a message after some operation is done
245 * @param cls string to print
246 * @param success GNUNET_OK if the PUT was transmitted,
247 * GNUNET_NO on timeout,
248 * GNUNET_SYSERR on disconnect from service
249 * after the PUT message was transmitted
250 * (so we don't know if it was received or not)
255 mesh_debug (void *cls, int success)
259 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s (%d)\n", s, success);
265 /******************************************************************************/
266 /*********************** GLOBAL VARIABLES ****************************/
267 /******************************************************************************/
269 /************************** Configuration parameters **************************/
273 * Maximum time allowed to connect to a peer found by string.
275 static struct GNUNET_TIME_Relative connect_timeout;
278 * Default TTL for payload packets.
280 static unsigned long long default_ttl;
283 * Percentage of messages that will be dropped (for test purposes only).
285 static unsigned long long drop_percent;
287 /*************************** Static global variables **************************/
290 * Handle to the statistics service.
292 static struct GNUNET_STATISTICS_Handle *stats;
295 * Local peer own ID (memory efficient handle).
297 static GNUNET_PEER_Id myid;
300 * Local peer own ID (full value).
302 static struct GNUNET_PeerIdentity my_full_id;
307 static struct GNUNET_CRYPTO_EccPrivateKey *my_private_key;
310 /******************************************************************************/
311 /*********************** DECLARATIONS **************************/
312 /******************************************************************************/
315 * Function to process paths received for a new peer addition. The recorded
316 * paths form the initial tunnel, which can be optimized later.
317 * Called on each result obtained for the DHT search.
320 * @param exp when will this value expire
321 * @param key key of the result
322 * @param type type of the result
323 * @param size number of bytes in data
324 * @param data pointer to the result data
327 dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
328 const struct GNUNET_HashCode * key,
329 const struct GNUNET_PeerIdentity *get_path,
330 unsigned int get_path_length,
331 const struct GNUNET_PeerIdentity *put_path,
332 unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
333 size_t size, const void *data);
337 * Retrieve the MeshPeer stucture associated with the peer, create one
338 * and insert it in the appropriate structures if the peer is not known yet.
340 * @param peer Full identity of the peer.
342 * @return Existing or newly created peer info.
344 static struct MeshPeer *
345 peer_get (const struct GNUNET_PeerIdentity *peer);
349 * Retrieve the MeshPeer stucture associated with the peer, create one
350 * and insert it in the appropriate structures if the peer is not known yet.
352 * @param peer Short identity of the peer.
354 * @return Existing or newly created peer info.
356 static struct MeshPeer *
357 peer_get_short (const GNUNET_PEER_Id peer);
361 * Build a PeerPath from the paths returned from the DHT, reversing the paths
362 * to obtain a local peer -> destination path and interning the peer ids.
364 * @return Newly allocated and created path
366 static struct MeshPeerPath *
367 path_build_from_dht (const struct GNUNET_PeerIdentity *get_path,
368 unsigned int get_path_length,
369 const struct GNUNET_PeerIdentity *put_path,
370 unsigned int put_path_length);
374 * Adds a path to the data structs of all the peers in the path
376 * @param p Path to process.
377 * @param confirmed Whether we know if the path works or not.
380 path_add_to_peers (struct MeshPeerPath *p, int confirmed);
384 * Change the tunnel state.
386 * @param t Tunnel whose state to change.
387 * @param state New state.
390 tunnel_change_state (struct MeshTunnel2 *t, enum MeshTunnelState state);
394 * Notify a tunnel that a connection has broken that affects at least
397 * @param t Tunnel affected.
398 * @param p1 Peer that got disconnected from p2.
399 * @param p2 Peer that got disconnected from p1.
401 * @return Short ID of the peer disconnected (either p1 or p2).
402 * 0 if the tunnel remained unaffected.
404 static GNUNET_PEER_Id
405 tunnel_notify_connection_broken (struct MeshTunnel2 *t,
406 GNUNET_PEER_Id p1, GNUNET_PEER_Id p2);
409 * @brief Use the given path for the tunnel.
410 * Update the next and prev hops (and RCs).
411 * (Re)start the path refresh in case the tunnel is locally owned.
413 * @param t Tunnel to update.
414 * @param p Path to use.
416 * @return Connection created.
418 static struct MeshConnection *
419 tunnel_use_path (struct MeshTunnel2 *t, struct MeshPeerPath *p);
422 * Tunnel is empty: destroy it.
424 * Notifies all participants (peers, cleints) about the destruction.
426 * @param t Tunnel to destroy.
429 tunnel_destroy_empty (struct MeshTunnel2 *t);
432 * Destroy the tunnel.
434 * This function does not generate any warning traffic to clients or peers.
437 * Cancel messages belonging to this tunnel queued to neighbors.
438 * Free any allocated resources linked to the tunnel.
440 * @param t The tunnel to destroy.
443 tunnel_destroy (struct MeshTunnel2 *t);
447 * Demultiplex by message type and call appropriate handler for a message
448 * towards a channel of a local tunnel.
450 * @param t Tunnel this message came on.
451 * @param msgh Message header.
452 * @param fwd Is this message fwd?
455 handle_decrypted (struct MeshTunnel2 *t,
456 const struct GNUNET_MessageHeader *msgh,
461 * Dummy function to separate declarations from definitions in function list.
464 __mesh_divider______________________________________________________________();
468 * Get string description for tunnel state.
470 * @param s Tunnel state.
472 * @return String representation.
475 GNUNET_MESH_DEBUG_TS2S (enum MeshTunnelState s)
477 static char buf[128];
481 case MESH_TUNNEL_NEW:
482 return "MESH_TUNNEL_NEW";
483 case MESH_TUNNEL_SEARCHING:
484 return "MESH_TUNNEL_SEARCHING";
485 case MESH_TUNNEL_WAITING:
486 return "MESH_TUNNEL_WAITING";
487 case MESH_TUNNEL_READY:
488 return "MESH_TUNNEL_READY";
489 case MESH_TUNNEL_RECONNECTING:
490 return "MESH_TUNNEL_RECONNECTING";
493 sprintf (buf, "%u (UNKNOWN STATE)", s);
501 /******************************************************************************/
502 /****************** GENERAL HELPER FUNCTIONS ************************/
503 /******************************************************************************/
507 * Get the static string for a peer ID.
511 * @return Static string for it's ID.
514 peer2s (const struct MeshPeer *peer)
518 return GNUNET_i2s (GNUNET_PEER_resolve2 (peer->id));
524 * Count established (ready) connections of a tunnel.
526 * @param t Tunnel on which to send the message.
528 * @return Number of connections.
531 tunnel_count_connections (struct MeshTunnel2 *t)
533 struct MeshConnection *c;
536 for (c = t->connection_head, i = 0; NULL != c; c = c->next, i++);
543 * Pick a connection on which send the next data message.
545 * @param t Tunnel on which to send the message.
546 * @param fwd Is this a fwd message?
548 * @return The connection on which to send the next message.
550 static struct MeshConnection *
551 tunnel_get_connection (struct MeshTunnel2 *t, int fwd)
553 struct MeshConnection *c;
554 struct MeshConnection *best;
555 struct MeshFlowControl *fc;
556 unsigned int lowest_q;
558 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tunnel_get_connection %s\n",
562 for (c = t->connection_head; NULL != c; c = c->next)
564 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " connection %s: %u\n",
565 GNUNET_h2s (&c->id), c->state);
566 if (MESH_CONNECTION_READY == c->state)
568 fc = fwd ? &c->fwd_fc : &c->bck_fc;
574 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " q_n %u, \n", fc->queue_n);
575 if (fc->queue_n < lowest_q)
578 lowest_q = fc->queue_n;
589 * Get the total buffer space for a tunnel.
592 * @param fwd Is this for FWD traffic?
594 * @return Buffer space offered by all connections in the tunnel.
597 tunnel_get_buffer (struct MeshTunnel2 *t, int fwd)
599 struct MeshConnection *c;
600 struct MeshFlowControl *fc;
603 c = t->connection_head;
606 /* If terminal, return biggest channel buffer */
607 if (NULL == c || GMC_is_terminal (c, fwd))
609 struct MeshChannel *ch;
612 if (NULL == t->channel_head)
615 for (ch = t->channel_head; NULL != ch; ch = ch->next)
617 ch_buf = channel_get_buffer (ch, fwd);
624 /* If not terminal, return sum of connection buffers */
627 if (c->state != MESH_CONNECTION_READY)
633 fc = fwd ? &c->fwd_fc : &c->bck_fc;
634 buffer += fc->queue_max - fc->queue_n;
643 * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
644 * Encrypt data with the tunnel key.
646 * @param t Tunnel whose key to use.
647 * @param dst Destination for the encrypted data.
648 * @param src Source of the plaintext.
649 * @param size Size of the plaintext.
650 * @param iv Initialization Vector to use.
651 * @param fwd Is this a fwd message?
654 tunnel_encrypt (struct MeshTunnel2 *t,
655 void *dst, const void *src,
656 size_t size, uint64_t iv, int fwd)
658 memcpy (dst, src, size);
663 * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
664 * Decrypt data with the tunnel key.
666 * @param t Tunnel whose key to use.
667 * @param dst Destination for the plaintext.
668 * @param src Source of the encrypted data.
669 * @param size Size of the encrypted data.
670 * @param iv Initialization Vector to use.
671 * @param fwd Is this a fwd message?
674 tunnel_decrypt (struct MeshTunnel2 *t,
675 void *dst, const void *src,
676 size_t size, uint64_t iv, int fwd)
678 memcpy (dst, src, size);
683 * Sends an already built message on a tunnel, choosing the best connection.
685 * @param message Message to send. Function modifies it.
686 * @param t Tunnel on which this message is transmitted.
687 * @param ch Channel on which this message is transmitted.
688 * @param fwd Is this a fwd message?
691 send_prebuilt_message_tunnel (struct GNUNET_MESH_Encrypted *msg,
692 struct MeshTunnel2 *t,
693 struct MeshChannel *ch,
696 struct MeshConnection *c;
699 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send on Tunnel %s\n",
701 c = tunnel_get_connection (t, fwd);
704 GNUNET_break (GNUNET_YES == t->destroy);
707 type = ntohs (msg->header.type);
710 case GNUNET_MESSAGE_TYPE_MESH_FWD:
711 case GNUNET_MESSAGE_TYPE_MESH_BCK:
712 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
713 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
715 msg->ttl = htonl (default_ttl);
718 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "unkown type %s\n",
719 GNUNET_MESH_DEBUG_M2S (type));
724 send_prebuilt_message_connection (&msg->header, c, ch, fwd);
730 * Sends a CREATE CONNECTION message for a path to a peer.
731 * Changes the connection and tunnel states if necessary.
733 * @param connection Connection to create.
736 send_connection_create (struct MeshConnection *connection)
738 struct MeshTunnel2 *t;
741 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send connection create\n");
743 GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE,
744 sizeof (struct GNUNET_MESH_ConnectionCreate) +
745 (connection->path->length *
746 sizeof (struct GNUNET_PeerIdentity)),
751 (MESH_TUNNEL_SEARCHING == t->state || MESH_TUNNEL_NEW == t->state))
752 tunnel_change_state (t, MESH_TUNNEL_WAITING);
753 if (MESH_CONNECTION_NEW == connection->state)
754 connection_change_state (connection, MESH_CONNECTION_SENT);
759 * Sends a CONNECTION ACK message in reponse to a received CONNECTION_CREATE
762 * @param connection Connection to confirm.
763 * @param fwd Is this a fwd ACK? (First is bck (SYNACK), second is fwd (ACK))
766 send_connection_ack (struct MeshConnection *connection, int fwd)
768 struct MeshTunnel2 *t;
771 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send connection ack\n");
773 GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK,
774 sizeof (struct GNUNET_MESH_ConnectionACK),
778 if (MESH_TUNNEL_NEW == t->state)
779 tunnel_change_state (t, MESH_TUNNEL_WAITING);
780 if (MESH_CONNECTION_READY != connection->state)
781 connection_change_state (connection, MESH_CONNECTION_SENT);
786 * Core callback to write a pre-constructed data packet to core buffer
788 * @param cls Closure (MeshTransmissionDescriptor with data in "data" member).
789 * @param size Number of bytes available in buf.
790 * @param buf Where the to write the message.
792 * @return number of bytes written to buf
795 send_core_data_raw (void *cls, size_t size, void *buf)
797 struct GNUNET_MessageHeader *msg = cls;
800 GNUNET_assert (NULL != msg);
801 total_size = ntohs (msg->size);
803 if (total_size > size)
808 memcpy (buf, msg, total_size);
815 * Function to send a create connection message to a peer.
817 * @param c Connection to create.
818 * @param size number of bytes available in buf
819 * @param buf where the callee should write the message
820 * @return number of bytes written to buf
823 send_core_connection_create (struct MeshConnection *c, size_t size, void *buf)
825 struct GNUNET_MESH_ConnectionCreate *msg;
826 struct GNUNET_PeerIdentity *peer_ptr;
827 struct MeshPeerPath *p = c->path;
831 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending CONNECTION CREATE...\n");
833 sizeof (struct GNUNET_MESH_ConnectionCreate) +
834 p->length * sizeof (struct GNUNET_PeerIdentity);
836 if (size < size_needed || NULL == buf)
841 msg = (struct GNUNET_MESH_ConnectionCreate *) buf;
842 msg->header.size = htons (size_needed);
843 msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE);
846 peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1];
847 for (i = 0; i < p->length; i++)
849 GNUNET_PEER_resolve (p->peers[i], peer_ptr++);
852 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
853 "CONNECTION CREATE (%u bytes long) sent!\n", size_needed);
859 * Creates a path ack message in buf and frees all unused resources.
861 * @param c Connection to send an ACK on.
862 * @param size number of bytes available in buf
863 * @param buf where the callee should write the message
865 * @return number of bytes written to buf
868 send_core_connection_ack (struct MeshConnection *c, size_t size, void *buf)
870 struct GNUNET_MESH_ConnectionACK *msg = buf;
871 struct MeshTunnel2 *t = c->t;
873 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending CONNECTION ACK...\n");
874 GNUNET_assert (NULL != t);
875 if (sizeof (struct GNUNET_MESH_ConnectionACK) > size)
880 msg->header.size = htons (sizeof (struct GNUNET_MESH_ConnectionACK));
881 msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK);
885 /* TODO add signature */
887 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CONNECTION ACK sent!\n");
888 return sizeof (struct GNUNET_MESH_ConnectionACK);
894 * Adds a path to the peer_infos of all the peers in the path
896 * @param p Path to process.
897 * @param confirmed Whether we know if the path works or not.
900 path_add_to_peers (struct MeshPeerPath *p, int confirmed)
904 /* TODO: invert and add */
905 for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ;
906 for (i++; i < p->length; i++)
908 struct MeshPeer *aux;
909 struct MeshPeerPath *copy;
911 aux = peer_get_short (p->peers[i]);
912 copy = path_duplicate (p);
913 copy->length = i + 1;
914 peer_add_path (aux, copy, p->length < 3 ? GNUNET_NO : confirmed);
921 fc_debug (struct MeshFlowControl *fc)
923 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " IN: %u/%u\n",
924 fc->last_pid_recv, fc->last_ack_sent);
925 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " OUT: %u/%u\n",
926 fc->last_pid_sent, fc->last_ack_recv);
927 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " QUEUE: %u/%u\n",
928 fc->queue_n, fc->queue_max);
932 connection_debug (struct MeshConnection *c)
936 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*** DEBUG NULL CONNECTION ***\n");
939 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection %s:%X\n",
940 peer2s (c->t->peer), GNUNET_h2s (&c->id));
941 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " state: %u, pending msgs: %u\n",
942 c->state, c->pending_messages);
943 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " FWD FC\n");
944 fc_debug (&c->fwd_fc);
945 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " BCK FC\n");
946 fc_debug (&c->bck_fc);
953 * Change the tunnel state.
955 * @param t Tunnel whose state to change.
956 * @param state New state.
959 tunnel_change_state (struct MeshTunnel2* t, enum MeshTunnelState state)
963 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
964 "Tunnel %s state was %s\n",
966 GNUNET_MESH_DEBUG_TS2S (t->state));
967 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
968 "Tunnel %s state is now %s\n",
970 GNUNET_MESH_DEBUG_TS2S (state));
976 * Send all cached messages that we can, tunnel is online.
978 * @param t Tunnel that holds the messages.
979 * @param fwd Is this fwd?
982 tunnel_send_queued_data (struct MeshTunnel2 *t, int fwd)
984 struct MeshTunnelQueue *tq;
985 struct MeshTunnelQueue *next;
988 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
989 "tunnel_send_queued_data on tunnel %s\n",
991 room = tunnel_get_buffer (t, fwd);
992 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " buffer space: %u\n", room);
993 for (tq = t->tq_head; NULL != tq && room > 0; tq = next)
997 GNUNET_CONTAINER_DLL_remove (t->tq_head, t->tq_tail, tq);
998 send_prebuilt_message_channel ((struct GNUNET_MessageHeader *) &tq[1],
1007 * Cache a message to be sent once tunnel is online.
1009 * @param t Tunnel to hold the message.
1010 * @param ch Channel the message is about.
1011 * @param msg Message itself (copy will be made).
1012 * @param fwd Is this fwd?
1015 tunnel_queue_data (struct MeshTunnel2 *t,
1016 struct MeshChannel *ch,
1017 struct GNUNET_MessageHeader *msg,
1020 struct MeshTunnelQueue *tq;
1021 uint16_t size = ntohs (msg->size);
1023 tq = GNUNET_malloc (sizeof (struct MeshTunnelQueue) + size);
1026 memcpy (&tq[1], msg, size);
1027 GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tq);
1029 if (MESH_TUNNEL_READY == t->state)
1030 tunnel_send_queued_data (t, fwd);
1037 static struct MeshConnection *
1038 tunnel_use_path (struct MeshTunnel2 *t, struct MeshPeerPath *p)
1040 struct MeshConnection *c;
1041 struct GNUNET_HashCode cid;
1042 struct MeshPeer *peer;
1043 unsigned int own_pos;
1045 if (NULL == t || NULL == p)
1051 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, &cid);
1053 c = connection_new (&cid);
1055 GNUNET_CONTAINER_DLL_insert (t->connection_head, t->connection_tail, c);
1056 for (own_pos = 0; own_pos < p->length; own_pos++)
1058 if (p->peers[own_pos] == myid)
1061 if (own_pos > p->length - 1)
1064 connection_destroy (c);
1067 c->own_pos = own_pos;
1072 c->fwd_maintenance_task =
1073 GNUNET_SCHEDULER_add_delayed (refresh_connection_time,
1074 &connection_fwd_keepalive, c);
1077 peer = connection_get_next_hop (c);
1078 if (NULL == peer->connections)
1080 connection_destroy (c);
1083 GNUNET_CONTAINER_multihashmap_put (peer->connections, &c->id, c,
1084 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1085 peer = connection_get_prev_hop (c);
1086 if (NULL == peer->connections)
1088 connection_destroy (c);
1091 GNUNET_CONTAINER_multihashmap_put (peer->connections, &c->id, c,
1092 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1098 * Notifies a tunnel that a connection has broken that affects at least
1099 * some of its peers. Sends a notification towards the root of the tree.
1100 * In case the peer is the owner of the tree, notifies the client that owns
1101 * the tunnel and tries to reconnect.
1103 * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
1105 * @param t Tunnel affected.
1106 * @param p1 Peer that got disconnected from p2.
1107 * @param p2 Peer that got disconnected from p1.
1109 * @return Short ID of the peer disconnected (either p1 or p2).
1110 * 0 if the tunnel remained unaffected.
1112 static GNUNET_PEER_Id
1113 tunnel_notify_connection_broken (struct MeshTunnel2* t,
1114 GNUNET_PEER_Id p1, GNUNET_PEER_Id p2)
1116 // if (myid != p1 && myid != p2) FIXME
1121 // if (tree_get_predecessor (t->tree) != 0)
1123 // /* We are the peer still connected, notify owner of the disconnection. */
1124 // struct GNUNET_MESH_PathBroken msg;
1125 // struct GNUNET_PeerIdentity neighbor;
1127 // msg.header.size = htons (sizeof (msg));
1128 // msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN);
1129 // GNUNET_PEER_resolve (t->id.oid, &msg.oid);
1130 // msg.tid = htonl (t->id.tid);
1131 // msg.peer1 = my_full_id;
1132 // GNUNET_PEER_resolve (pid, &msg.peer2);
1133 // GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &neighbor);
1134 // send_prebuilt_message (&msg.header, &neighbor, t);
1143 * Send an ACK on the appropriate connection/channel, depending on
1144 * the direction and the position of the peer.
1146 * @param c Which connection to send the hop-by-hop ACK.
1147 * @param ch Channel, if any.
1148 * @param fwd Is this a fwd ACK? (will go dest->root)
1151 send_ack (struct MeshConnection *c, struct MeshChannel *ch, int fwd)
1153 unsigned int buffer;
1155 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1156 "send ack %s on %p %p\n",
1157 fwd ? "FWD" : "BCK", c, ch);
1158 if (NULL == c || GMC_is_terminal (c, fwd))
1160 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " getting from all connections\n");
1161 buffer = tunnel_get_buffer (NULL == c ? ch->t : c->t, fwd);
1165 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " getting from one connection\n");
1166 buffer = connection_get_buffer (c, fwd);
1168 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " buffer available: %u\n", buffer);
1170 if ( (NULL != ch && channel_is_origin (ch, fwd)) ||
1171 (NULL != c && connection_is_origin (c, fwd)) )
1173 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending on channel...\n");
1176 GNUNET_assert (NULL != ch);
1177 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " really sending!\n");
1178 send_local_ack (ch, fwd);
1183 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending on all connections\n");
1184 GNUNET_assert (NULL != ch);
1185 channel_send_connections_ack (ch, buffer, fwd);
1189 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending on connection\n");
1190 connection_send_ack (c, buffer, fwd);
1198 * Confirm we got a channel create.
1200 * @param ch The channel to confirm.
1201 * @param fwd Should we send the ACK fwd?
1204 channel_send_ack (struct MeshChannel *ch, int fwd)
1206 struct GNUNET_MESH_ChannelManage msg;
1208 msg.header.size = htons (sizeof (msg));
1209 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK);
1210 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1211 " sending channel %s ack for channel %s:%X\n",
1212 fwd ? "FWD" : "BCK", peer2s (ch->t->peer),
1215 msg.chid = htonl (ch->gid);
1216 send_prebuilt_message_channel (&msg.header, ch, !fwd);
1221 * Send a message to all clients (local and remote) of this channel
1222 * notifying that the channel is no longer valid.
1224 * If some peer or client should not receive the message,
1225 * should be zero'ed out before calling this function.
1227 * @param ch The channel whose clients to notify.
1230 channel_send_destroy (struct MeshChannel *ch)
1232 struct GNUNET_MESH_ChannelManage msg;
1234 msg.header.size = htons (sizeof (msg));
1235 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY);
1236 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1237 " sending channel destroy for channel %s:%X\n",
1238 peer2s (ch->t->peer),
1241 if (channel_is_terminal (ch, GNUNET_NO))
1243 if (NULL != ch->root && GNUNET_NO == ch->root->shutting_down)
1245 msg.chid = htonl (ch->lid_root);
1246 send_local_channel_destroy (ch, GNUNET_NO);
1251 msg.chid = htonl (ch->gid);
1252 send_prebuilt_message_channel (&msg.header, ch, GNUNET_NO);
1255 if (channel_is_terminal (ch, GNUNET_YES))
1257 if (NULL != ch->dest && GNUNET_NO == ch->dest->shutting_down)
1259 msg.chid = htonl (ch->lid_dest);
1260 send_local_channel_destroy (ch, GNUNET_YES);
1265 msg.chid = htonl (ch->gid);
1266 send_prebuilt_message_channel (&msg.header, ch, GNUNET_YES);
1274 static struct MeshTunnel2 *
1277 struct MeshTunnel2 *t;
1279 t = GNUNET_new (struct MeshTunnel2);
1281 t->next_local_chid = GNUNET_MESH_LOCAL_CHANNEL_ID_SERV;
1283 // GNUNET_CONTAINER_multihashmap_put (tunnels, tid, t,
1284 // GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
1286 // GNUNET_break (0);
1287 // tunnel_destroy (t);
1291 // char salt[] = "salt";
1292 // GNUNET_CRYPTO_kdf (&t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
1293 // salt, sizeof (salt),
1294 // &t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
1295 // &my_full_id, sizeof (struct GNUNET_PeerIdentity),
1296 // GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
1298 // GNUNET_CRYPTO_kdf (&t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
1299 // salt, sizeof (salt),
1300 // &t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
1301 // GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
1302 // &my_full_id, sizeof (struct GNUNET_PeerIdentity),
1310 * Add a connection to a tunnel.
1313 * @param c Connection.
1316 tunnel_add_connection (struct MeshTunnel2 *t, struct MeshConnection *c)
1318 struct MeshConnection *aux;
1320 for (aux = t->connection_head; aux != NULL; aux = aux->next)
1323 GNUNET_CONTAINER_DLL_insert_tail (t->connection_head, t->connection_tail, c);
1329 tunnel_destroy (struct MeshTunnel2 *t)
1331 struct MeshConnection *c;
1332 struct MeshConnection *next;
1337 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s\n",
1340 // if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (tunnels, &t->id, t))
1341 // GNUNET_break (0);
1343 for (c = t->connection_head; NULL != c; c = next)
1346 connection_destroy (c);
1349 GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO);
1350 t->peer->tunnel = NULL;
1357 * Tunnel is empty: destroy it.
1359 * Notifies all connections about the destruction.
1361 * @param t Tunnel to destroy.
1364 tunnel_destroy_empty (struct MeshTunnel2 *t)
1366 struct MeshConnection *c;
1368 for (c = t->connection_head; NULL != c; c = c->next)
1370 if (GNUNET_NO == c->destroy)
1371 connection_send_destroy (c);
1374 if (0 == t->pending_messages)
1377 t->destroy = GNUNET_YES;
1382 * Destroy tunnel if empty (no more channels).
1384 * @param t Tunnel to destroy if empty.
1387 tunnel_destroy_if_empty (struct MeshTunnel2 *t)
1389 if (NULL != t->channel_head)
1392 tunnel_destroy_empty (t);
1396 /******************************************************************************/
1397 /**************** MESH NETWORK HANDLER HELPERS ***********************/
1398 /******************************************************************************/
1405 /******************************************************************************/
1406 /******************** MESH NETWORK HANDLERS **************************/
1407 /******************************************************************************/
1411 * Generic handler for mesh network payload traffic.
1413 * @param t Tunnel on which we got this message.
1414 * @param message Unencryted data message.
1415 * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1418 handle_data (struct MeshTunnel2 *t, const struct GNUNET_MESH_Data *msg, int fwd)
1420 struct MeshChannelReliability *rel;
1421 struct MeshChannel *ch;
1422 struct MeshClient *c;
1428 size = ntohs (msg->header.size);
1430 sizeof (struct GNUNET_MESH_Data) +
1431 sizeof (struct GNUNET_MessageHeader))
1436 type = ntohs (msg->header.type);
1437 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a %s message\n",
1438 GNUNET_MESH_DEBUG_M2S (type));
1439 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " payload of type %s\n",
1440 GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
1443 ch = channel_get (t, ntohl (msg->chid));
1446 GNUNET_STATISTICS_update (stats, "# data on unknown channel", 1, GNUNET_NO);
1447 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
1452 /* Initialize FWD/BCK data */
1453 c = fwd ? ch->dest : ch->root;
1454 rel = fwd ? ch->dest_rel : ch->root_rel;
1462 tunnel_change_state (t, MESH_TUNNEL_READY);
1464 GNUNET_STATISTICS_update (stats, "# data received", 1, GNUNET_NO);
1466 mid = ntohl (msg->mid);
1467 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " mid %u\n", mid);
1469 if (GNUNET_NO == ch->reliable ||
1470 ( !GMC_is_pid_bigger (rel->mid_recv, mid) &&
1471 GMC_is_pid_bigger (rel->mid_recv + 64, mid) ) )
1473 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! RECV %u\n", mid);
1474 if (GNUNET_YES == ch->reliable)
1476 /* Is this the exact next expected messasge? */
1477 if (mid == rel->mid_recv)
1479 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "as expected\n");
1481 channel_send_client_data (ch, msg, fwd);
1485 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "save for later\n");
1486 channel_rel_add_buffered_data (msg, rel);
1491 /* Tunnel is unreliable: send to clients directly */
1492 /* FIXME: accept Out Of Order traffic */
1493 rel->mid_recv = mid + 1;
1494 channel_send_client_data (ch, msg, fwd);
1499 GNUNET_break_op (0);
1500 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1501 " MID %u not expected (%u - %u), dropping!\n",
1502 mid, rel->mid_recv, rel->mid_recv + 64);
1505 channel_send_data_ack (ch, fwd);
1509 * Handler for mesh network traffic end-to-end ACKs.
1511 * @param t Tunnel on which we got this message.
1512 * @param message Data message.
1513 * @param fwd Is this a fwd ACK? (dest->orig)
1516 handle_data_ack (struct MeshTunnel2 *t,
1517 const struct GNUNET_MESH_DataACK *msg, int fwd)
1519 struct MeshChannelReliability *rel;
1520 struct MeshReliableMessage *copy;
1521 struct MeshReliableMessage *next;
1522 struct MeshChannel *ch;
1527 type = ntohs (msg->header.type);
1528 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a %s message!\n",
1529 GNUNET_MESH_DEBUG_M2S (type));
1530 ch = channel_get (t, ntohl (msg->chid));
1533 GNUNET_STATISTICS_update (stats, "# ack on unknown channel", 1, GNUNET_NO);
1536 ack = ntohl (msg->mid);
1537 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! %s ACK %u\n",
1538 (GNUNET_YES == fwd) ? "FWD" : "BCK", ack);
1540 if (GNUNET_YES == fwd)
1554 for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next)
1556 if (GMC_is_pid_bigger (copy->mid, ack))
1558 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! head %u, out!\n", copy->mid);
1559 channel_rel_free_sent (rel, msg);
1563 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! id %u\n", copy->mid);
1565 rel_message_free (copy);
1567 /* ACK client if needed */
1568 // channel_send_ack (t, type, GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK == type);
1570 /* If some message was free'd, update the retransmission delay*/
1571 if (GNUNET_YES == work)
1573 if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task)
1575 GNUNET_SCHEDULER_cancel (rel->retry_task);
1576 if (NULL == rel->head_sent)
1578 rel->retry_task = GNUNET_SCHEDULER_NO_TASK;
1582 struct GNUNET_TIME_Absolute new_target;
1583 struct GNUNET_TIME_Relative delay;
1585 delay = GNUNET_TIME_relative_multiply (rel->retry_timer,
1586 MESH_RETRANSMIT_MARGIN);
1587 new_target = GNUNET_TIME_absolute_add (rel->head_sent->timestamp,
1589 delay = GNUNET_TIME_absolute_get_remaining (new_target);
1591 GNUNET_SCHEDULER_add_delayed (delay,
1592 &channel_retransmit_message,
1605 * Handler for channel create messages.
1607 * @param t Tunnel this channel is to be created in.
1608 * @param msg Message.
1609 * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1612 handle_channel_create (struct MeshTunnel2 *t,
1613 struct GNUNET_MESH_ChannelCreate *msg,
1616 MESH_ChannelNumber chid;
1617 struct MeshChannel *ch;
1618 struct MeshClient *c;
1621 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received Channel Create\n");
1622 /* Check message size */
1623 if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelCreate))
1625 GNUNET_break_op (0);
1629 /* Check if channel exists */
1630 chid = ntohl (msg->chid);
1631 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " chid %u\n", chid);
1632 ch = channel_get (t, chid);
1635 /* Probably a retransmission, safe to ignore */
1636 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " already exists...\n");
1637 if (NULL != ch->dest)
1639 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " duplicate CC!!\n");
1640 channel_send_ack (ch, !fwd);
1646 /* Create channel */
1647 ch = channel_new (t, NULL, 0);
1649 channel_set_options (ch, ntohl (msg->opt));
1652 /* Find a destination client */
1653 port = ntohl (msg->port);
1654 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " port %u\n", port);
1655 c = GNUNET_CONTAINER_multihashmap32_get (ports, port);
1658 /* TODO send reject */
1659 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " no client has port registered\n");
1664 channel_add_client (ch, c);
1665 if (GNUNET_YES == ch->reliable)
1666 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! Reliable\n");
1668 send_local_channel_create (ch);
1669 channel_send_ack (ch, fwd);
1670 send_local_ack (ch, !fwd);
1675 * Handler for channel ack messages.
1677 * @param t Tunnel this channel is to be created in.
1678 * @param msg Message.
1679 * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1682 handle_channel_ack (struct MeshTunnel2 *t,
1683 struct GNUNET_MESH_ChannelManage *msg,
1686 MESH_ChannelNumber chid;
1687 struct MeshChannel *ch;
1689 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received Channel ACK\n");
1690 /* Check message size */
1691 if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage))
1693 GNUNET_break_op (0);
1697 /* Check if channel exists */
1698 chid = ntohl (msg->chid);
1699 ch = channel_get (t, chid);
1702 GNUNET_break_op (0);
1703 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " channel %u unknown!!\n", chid);
1707 channel_confirm (ch, !fwd);
1712 * Handler for channel destroy messages.
1714 * @param t Tunnel this channel is to be destroyed of.
1715 * @param msg Message.
1716 * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1719 handle_channel_destroy (struct MeshTunnel2 *t,
1720 struct GNUNET_MESH_ChannelManage *msg,
1723 MESH_ChannelNumber chid;
1724 struct MeshChannel *ch;
1726 /* Check message size */
1727 if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage))
1729 GNUNET_break_op (0);
1733 /* Check if channel exists */
1734 chid = ntohl (msg->chid);
1735 ch = channel_get (t, chid);
1738 /* Probably a retransmission, safe to ignore */
1741 if ( (fwd && NULL == ch->dest) || (!fwd && NULL == ch->root) )
1743 /* Not for us (don't destroy twice a half-open loopback channel) */
1747 send_local_channel_destroy (ch, fwd);
1748 channel_destroy (ch);
1753 handle_decrypted (struct MeshTunnel2 *t,
1754 const struct GNUNET_MessageHeader *msgh,
1757 switch (ntohs (msgh->type))
1759 case GNUNET_MESSAGE_TYPE_MESH_DATA:
1760 /* Don't send hop ACK, wait for client to ACK */
1761 handle_data (t, (struct GNUNET_MESH_Data *) msgh, fwd);
1764 case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
1765 handle_data_ack (t, (struct GNUNET_MESH_DataACK *) msgh, fwd);
1768 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
1769 handle_channel_create (t,
1770 (struct GNUNET_MESH_ChannelCreate *) msgh,
1774 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
1775 handle_channel_ack (t,
1776 (struct GNUNET_MESH_ChannelManage *) msgh,
1780 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
1781 handle_channel_destroy (t,
1782 (struct GNUNET_MESH_ChannelManage *) msgh,
1787 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1788 "end-to-end message not known (%u)\n",
1789 ntohs (msgh->type));
1795 * Function to process paths received for a new peer addition. The recorded
1796 * paths form the initial tunnel, which can be optimized later.
1797 * Called on each result obtained for the DHT search.
1799 * @param cls closure
1803 search_handler (void *cls, struct MeshPeerPath *path)
1805 struct MeshConnection *c;
1806 unsigned int connection_count;
1808 path_add_to_peers (path, GNUNET_NO);
1810 /* Count connections */
1811 connection_count = GMC_count (peer->tunnel->connection_head);
1813 /* If we already have 3 (or more (?!)) connections, it's enough */
1814 if (3 <= connection_count)
1817 if (peer->tunnel->state == MESH_TUNNEL_SEARCHING)
1819 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ... connect!\n");
1820 peer_connect (peer);
1826 /******************************************************************************/
1827 /************************ MAIN FUNCTIONS ****************************/
1828 /******************************************************************************/
1834 * Task run during shutdown.
1840 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1842 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutting down\n");
1849 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n");
1854 * Process mesh requests.
1856 * @param cls closure
1857 * @param server the initialized server
1858 * @param c configuration to use
1861 run (void *cls, struct GNUNET_SERVER_Handle *server,
1862 const struct GNUNET_CONFIGURATION_Handle *c)
1864 struct GNUNET_CRYPTO_EccPrivateKey *pk;
1866 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting to run\n");
1869 GNUNET_CONFIGURATION_get_value_time (c, "MESH", "CONNECT_TIMEOUT",
1872 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
1873 "MESH", "CONNECT_TIMEOUT", "MISSING");
1874 GNUNET_SCHEDULER_shutdown ();
1879 GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DEFAULT_TTL",
1882 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1883 "MESH", "DEFAULT_TTL", "USING DEFAULT");
1888 GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DROP_PERCENT",
1895 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1896 "\n***************************************\n"
1897 "Mesh is running with drop mode enabled.\n"
1898 "This is NOT a good idea!\n"
1899 "Remove the DROP_PERCENT option from your configuration.\n"
1900 "***************************************\n");
1904 stats = GNUNET_STATISTICS_create ("mesh", c);
1906 /* Scheduled the task to clean up when shutdown is called */
1907 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
1909 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "reading key\n");
1910 pk = GNUNET_CRYPTO_ecc_key_create_from_configuration (c);
1911 GNUNET_assert (NULL != pk);
1912 my_private_key = pk;
1913 GNUNET_CRYPTO_ecc_key_get_public_for_signature (my_private_key,
1914 &my_full_id.public_key);
1915 myid = GNUNET_PEER_intern (&my_full_id);
1916 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1917 "Mesh for peer [%s] starting\n",
1918 GNUNET_i2s(&my_full_id));
1920 GML_init (server); /* Local clients */
1921 GMC_init (c); /* Connections */
1922 GMP_init (c); /* Peers */
1923 GMD_init (c, &my_full_id); /* DHT */
1925 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mesh service running\n");
1930 * The main function for the mesh service.
1932 * @param argc number of arguments from the command line
1933 * @param argv command line arguments
1934 * @return 0 ok, 1 on error
1937 main (int argc, char *const *argv)
1942 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main()\n");
1943 r = GNUNET_SERVICE_run (argc, argv, "mesh", GNUNET_SERVICE_OPTION_NONE, &run,
1945 ret = (GNUNET_OK == r) ? 0 : 1;
1946 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main() END\n");