From: Bart Polot Date: Wed, 9 Oct 2013 01:06:44 +0000 (+0000) Subject: - fixed _tunnel X-Git-Tag: initial-import-from-subversion-38251~6685 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=d1106ec22a4f714484ce964b24b4f10b397c720e;p=oweals%2Fgnunet.git - fixed _tunnel - solved data struct visibility --- diff --git a/src/mesh/gnunet-service-mesh_channel.c b/src/mesh/gnunet-service-mesh_channel.c index 8d1ccb0b9..6e99d2b30 100644 --- a/src/mesh/gnunet-service-mesh_channel.c +++ b/src/mesh/gnunet-service-mesh_channel.c @@ -163,13 +163,7 @@ struct MeshChannel /** * Tunnel this channel is in. */ - struct MeshTunnel2 *t; - - /** - * Double linked list. - */ - struct MeshChannel *next; - struct MeshChannel *prev; + struct MeshTunnel3 *t; /** * Destination port of the channel. @@ -368,33 +362,6 @@ channel_get_by_local_id (struct MeshClient *c, MESH_ChannelNumber chid) } - -/** - * Search for a channel by global ID using full PeerIdentities. - * - * @param t Tunnel containing the channel. - * @param chid Public channel number. - * - * @return channel handler, NULL if doesn't exist - */ -static struct MeshChannel * -channel_get (struct MeshTunnel2 *t, MESH_ChannelNumber chid) -{ - struct MeshChannel *ch; - - if (NULL == t) - return NULL; - - for (ch = t->channel_head; NULL != ch; ch = ch->next) - { - if (ch->gid == chid) - break; - } - - return ch; -} - - /** * Add a client to a channel, initializing all needed data structures. * @@ -404,7 +371,7 @@ channel_get (struct MeshTunnel2 *t, MESH_ChannelNumber chid) static void channel_add_client (struct MeshChannel *ch, struct MeshClient *c) { - struct MeshTunnel2 *t = ch->t; + struct MeshTunnel3 *t = ch->t; if (NULL != ch->dest) { @@ -474,34 +441,6 @@ channel_is_terminal (struct MeshChannel *ch, int fwd) } -/** - * Get free buffer space towards the client on a specific channel. - * - * @param ch Channel. - * @param fwd Is query about FWD traffic? - * - * @return Free buffer space [0 - 64] - */ -static unsigned int -channel_get_buffer (struct MeshChannel *ch, int fwd) -{ - struct MeshChannelReliability *rel; - - rel = fwd ? ch->dest_rel : ch->root_rel; - - /* If rel is NULL it means that the end is not yet created, - * most probably is a loopback channel at the point of sending - * the ChannelCreate to itself. - */ - if (NULL == rel) - return 64; - - return (64 - rel->n_recv); -} - - - - /** * Destroy all reliable messages queued for a channel, * during a channel destruction. @@ -696,7 +635,7 @@ channel_send_connections_ack (struct MeshChannel *ch, unsigned int buffer, int fwd) { - struct MeshTunnel2 *t = ch->t; + struct MeshTunnel3 *t = ch->t; struct MeshConnection *c; struct MeshFlowControl *fc; uint32_t allowed; @@ -983,7 +922,7 @@ channel_destroy (struct MeshChannel *ch) * @return A new initialized channel. NULL on error. */ static struct MeshChannel * -channel_new (struct MeshTunnel2 *t, +channel_new (struct MeshTunnel3 *t, struct MeshClient *owner, MESH_ChannelNumber lid_root) { struct MeshChannel *ch; @@ -1129,7 +1068,7 @@ channel_destroy_iterator (void *cls, { struct MeshChannel *ch = value; struct MeshClient *c = cls; - struct MeshTunnel2 *t; + struct MeshTunnel3 *t; LOG (GNUNET_ERROR_TYPE_DEBUG, " Channel %X (%X / %X) destroy, due to client %u shutdown.\n", @@ -1155,65 +1094,47 @@ channel_destroy_iterator (void *cls, } +/******************************************************************************/ +/******************************** API ***********************************/ +/******************************************************************************/ + /** - * Sends an already built message on a channel, properly registering - * all used resources and encrypting the message with the tunnel's key. + * Get channel ID. * - * @param message Message to send. Function makes a copy of it. - * @param ch Channel on which this message is transmitted. - * @param fwd Is this a fwd message? + * @param ch Channel. + * + * @return ID */ -static void -send (const struct GNUNET_MessageHeader *message, - struct MeshChannel *ch, int fwd) +MESH_ChannelNumber +GMCH_get_id (const struct MeshChannel *ch) { - struct GNUNET_MESH_Encrypted *msg; - size_t size = ntohs (message->size); - char *cbuf[sizeof (struct GNUNET_MESH_Encrypted) + size]; - uint16_t type; - uint64_t iv; - - LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Channel %s:%X %s\n", - peer2s (ch->t->peer), ch->gid, fwd ? "FWD" : "BCK"); - LOG (GNUNET_ERROR_TYPE_DEBUG, " %s\n", - GNUNET_MESH_DEBUG_M2S (ntohs (message->type))); - - if (channel_is_terminal (ch, fwd) || ch->t->peer->id == myid) - { - handle_decrypted (ch->t, message, fwd); - return; - } - - type = fwd ? GNUNET_MESSAGE_TYPE_MESH_FWD : GNUNET_MESSAGE_TYPE_MESH_BCK; - iv = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX); - - msg = (struct GNUNET_MESH_Encrypted *) cbuf; - msg->header.type = htons (type); - msg->header.size = htons (sizeof (struct GNUNET_MESH_Encrypted) + size); - msg->iv = GNUNET_htonll (iv); - GMT_encrypt (ch->t, &msg[1], message, size, iv, fwd); - GMT_send_prebuilt_message (msg, ch->t, ch, fwd); + return ch->gid; } -/******************************************************************************/ -/******************************** API ***********************************/ -/******************************************************************************/ - /** - * Count channels in a DLL. - * - * @param head Head of the DLL. + * Get free buffer space towards the client on a specific channel. + * + * @param ch Channel. + * @param fwd Is query about FWD traffic? + * + * @return Free buffer space [0 - 64] */ unsigned int -GMCH_count (const struct MeshChannel *head) +GMCH_get_buffer (struct MeshChannel *ch, int fwd) { - unsigned int count; - struct MeshChannel *iter; + struct MeshChannelReliability *rel; - for (count = 0, iter = head; NULL != iter; iter = iter->next, count++); + rel = fwd ? ch->dest_rel : ch->root_rel; + + /* If rel is NULL it means that the end is not yet created, + * most probably is a loopback channel at the point of sending + * the ChannelCreate to itself. + */ + if (NULL == rel) + return 64; - return count; + return (64 - rel->n_recv); } @@ -1226,7 +1147,7 @@ void GMCH_send_create (struct MeshChannel *ch) { struct GNUNET_MESH_ChannelMessage msg; - struct MeshTunnel2 *t = ch->t; + struct MeshTunnel3 *t = ch->t; uint32_t opt; if (NULL == ch->dest) @@ -1372,47 +1293,21 @@ GMCH_debug (struct MeshChannel *ch) /** * Handler for mesh network payload traffic. * - * @param t Tunnel on which we got this message. + * @param ch Channel for the message. * @param message Unencryted data message. * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; */ void -GMCH_handle_data (struct MeshTunnel2 *t, +GMCH_handle_data (struct MeshChannel *ch, const struct GNUNET_MESH_Data *msg, int fwd) { struct MeshChannelReliability *rel; - struct MeshChannel *ch; struct MeshClient *c; uint32_t mid; uint16_t type; size_t size; - /* Check size */ - size = ntohs (msg->header.size); - if (size < - sizeof (struct GNUNET_MESH_Data) + - sizeof (struct GNUNET_MessageHeader)) - { - GNUNET_break (0); - return; - } - type = ntohs (msg->header.type); - LOG (GNUNET_ERROR_TYPE_DEBUG, "got a %s message\n", - GNUNET_MESH_DEBUG_M2S (type)); - LOG (GNUNET_ERROR_TYPE_DEBUG, " payload of type %s\n", - GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type))); - - /* Check channel */ - ch = channel_get (t, ntohl (msg->chid)); - if (NULL == ch) - { - GNUNET_STATISTICS_update (stats, "# data on unknown channel", 1, GNUNET_NO); - LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n", - ntohl (msg->chid)); - return; - } - /* Initialize FWD/BCK data */ c = fwd ? ch->dest : ch->root; rel = fwd ? ch->dest_rel : ch->root_rel; @@ -1423,8 +1318,6 @@ GMCH_handle_data (struct MeshTunnel2 *t, return; } - GMT_change_state (t, MESH_TUNNEL_READY); - GNUNET_STATISTICS_update (stats, "# data received", 1, GNUNET_NO); mid = ntohl (msg->mid); @@ -1478,27 +1371,16 @@ GMCH_handle_data (struct MeshTunnel2 *t, * @param fwd Is this a fwd ACK? (dest->orig) */ void -GMCH_handle_data_ack (struct MeshTunnel2 *t, +GMCH_handle_data_ack (struct MeshChannel *ch, const struct GNUNET_MESH_DataACK *msg, int fwd) { struct MeshChannelReliability *rel; struct MeshReliableMessage *copy; struct MeshReliableMessage *next; - struct MeshChannel *ch; uint32_t ack; - uint16_t type; int work; - type = ntohs (msg->header.type); - LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a %s message!\n", - GNUNET_MESH_DEBUG_M2S (type)); - ch = channel_get (t, ntohl (msg->chid)); - if (NULL == ch) - { - GNUNET_STATISTICS_update (stats, "# ack on unknown channel", 1, GNUNET_NO); - return; - } ack = ntohl (msg->mid); LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! %s ACK %u\n", (GNUNET_YES == fwd) ? "FWD" : "BCK", ack); @@ -1572,9 +1454,8 @@ GMCH_handle_data_ack (struct MeshTunnel2 *t, * @param msg Message. * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; */ -void -GMCH_handle_create (struct MeshTunnel2 *t, - struct GNUNET_MESH_ChannelCreate *msg, +struct MeshChannel * +GMCH_handle_create (const struct GNUNET_MESH_ChannelCreate *msg, int fwd) { MESH_ChannelNumber chid; @@ -1582,41 +1463,18 @@ GMCH_handle_create (struct MeshTunnel2 *t, struct MeshClient *c; uint32_t port; - LOG (GNUNET_ERROR_TYPE_DEBUG, "Received Channel Create\n"); - /* Check message size */ - if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelCreate)) - { - GNUNET_break_op (0); - return; - } - /* Check if channel exists */ chid = ntohl (msg->chid); - LOG (GNUNET_ERROR_TYPE_DEBUG, " chid %u\n", chid); - ch = channel_get (t, chid); - if (NULL != ch) - { - /* Probably a retransmission, safe to ignore */ - LOG (GNUNET_ERROR_TYPE_DEBUG, " already exists...\n"); - if (NULL != ch->dest) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, " duplicate CC!!\n"); - GMCH_send_ack (ch, !fwd); - return; - } - } - else - { - /* Create channel */ - ch = channel_new (t, NULL, 0); - ch->gid = chid; - channel_set_options (ch, ntohl (msg->opt)); - } + + /* Create channel */ + ch = channel_new (NULL, NULL, 0); /* FIXME t */ + ch->gid = chid; + channel_set_options (ch, ntohl (msg->opt)); /* Find a destination client */ port = ntohl (msg->port); LOG (GNUNET_ERROR_TYPE_DEBUG, " port %u\n", port); - c = GNUNET_CONTAINER_multihashmap32_get (ports, port); + c = GML_client_get_by_port (port); if (NULL == c) { /* TODO send reject */ @@ -1632,42 +1490,23 @@ GMCH_handle_create (struct MeshTunnel2 *t, GMCH_send_create (ch); GMCH_send_ack (ch, fwd); GML_send_ack (ch, !fwd); + + return ch; } /** * Handler for channel ack messages. * - * @param t Tunnel this channel is to be created in. + * @param ch Channel. * @param msg Message. * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; */ void -GMCH_handle_ack (struct MeshTunnel2 *t, - struct GNUNET_MESH_ChannelManage *msg, +GMCH_handle_ack (struct MeshChannel *ch, + const struct GNUNET_MESH_ChannelManage *msg, int fwd) { - MESH_ChannelNumber chid; - struct MeshChannel *ch; - - LOG (GNUNET_ERROR_TYPE_DEBUG, "Received Channel ACK\n"); - /* Check message size */ - if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage)) - { - GNUNET_break_op (0); - return; - } - - /* Check if channel exists */ - chid = ntohl (msg->chid); - ch = channel_get (t, chid); - if (NULL == ch) - { - GNUNET_break_op (0); - LOG (GNUNET_ERROR_TYPE_DEBUG, " channel %u unknown!!\n", chid); - return; - } - channel_confirm (ch, !fwd); } @@ -1675,33 +1514,19 @@ GMCH_handle_ack (struct MeshTunnel2 *t, /** * Handler for channel destroy messages. * - * @param t Tunnel this channel is to be destroyed of. + * @param ch Channel to be destroyed of. * @param msg Message. * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; */ void -GMCH_handle_destroy (struct MeshTunnel2 *t, - struct GNUNET_MESH_ChannelManage *msg, +GMCH_handle_destroy (struct MeshChannel *ch, + const struct GNUNET_MESH_ChannelManage *msg, int fwd) { MESH_ChannelNumber chid; - struct MeshChannel *ch; - - /* Check message size */ - if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage)) - { - GNUNET_break_op (0); - return; - } /* Check if channel exists */ chid = ntohl (msg->chid); - ch = channel_get (t, chid); - if (NULL == ch) - { - /* Probably a retransmission, safe to ignore */ - return; - } if ( (fwd && NULL == ch->dest) || (!fwd && NULL == ch->root) ) { /* Not for us (don't destroy twice a half-open loopback channel) */ @@ -1712,3 +1537,43 @@ GMCH_handle_destroy (struct MeshTunnel2 *t, channel_destroy (ch); } + +/** + * Sends an already built message on a channel, properly registering + * all used resources and encrypting the message with the tunnel's key. + * + * @param message Message to send. Function makes a copy of it. + * @param ch Channel on which this message is transmitted. + * @param fwd Is this a fwd message? + */ +void +GMCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message, + struct MeshChannel *ch, int fwd) +{ + struct GNUNET_MESH_Encrypted *msg; + size_t size = ntohs (message->size); + char *cbuf[sizeof (struct GNUNET_MESH_Encrypted) + size]; + uint16_t type; + uint64_t iv; + + LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Channel %s:%X %s\n", + peer2s (ch->t->peer), ch->gid, fwd ? "FWD" : "BCK"); + LOG (GNUNET_ERROR_TYPE_DEBUG, " %s\n", + GNUNET_MESH_DEBUG_M2S (ntohs (message->type))); + + if (channel_is_terminal (ch, fwd) || ch->t->peer->id == myid) + { + GMT_handle_decrypted (ch->t, message, fwd); + return; + } + + type = fwd ? GNUNET_MESSAGE_TYPE_MESH_FWD : GNUNET_MESSAGE_TYPE_MESH_BCK; + iv = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX); + + msg = (struct GNUNET_MESH_Encrypted *) cbuf; + msg->header.type = htons (type); + msg->header.size = htons (sizeof (struct GNUNET_MESH_Encrypted) + size); + msg->iv = GNUNET_htonll (iv); + GMT_encrypt (ch->t, &msg[1], message, size, iv, fwd); + GMT_send_prebuilt_message (msg, ch->t, ch, fwd); +} diff --git a/src/mesh/gnunet-service-mesh_channel.h b/src/mesh/gnunet-service-mesh_channel.h index 5eadd60bd..8af9937b0 100644 --- a/src/mesh/gnunet-service-mesh_channel.h +++ b/src/mesh/gnunet-service-mesh_channel.h @@ -40,18 +40,33 @@ extern "C" #include "platform.h" #include "gnunet_util_lib.h" +#include "gnunet-service-mesh_tunnel.h" + /** * Struct containing all information regarding a channel to a remote client. */ struct MeshChannel; /** - * Count channels in a DLL. - * - * @param head Head of the DLL. + * Get channel ID. + * + * @param ch Channel. + * + * @return ID + */ +MESH_ChannelNumber +GMCH_get_id (const struct MeshChannel *ch); + +/** + * Get free buffer space towards the client on a specific channel. + * + * @param ch Channel. + * @param fwd Is query about FWD traffic? + * + * @return Free buffer space [0 - 64] */ unsigned int -GMCH_count (const struct MeshChannel *head); +GMCH_get_buffer (struct MeshChannel *ch, int fwd); /** * Send an end-to-end ACK message for the most recent in-sequence payload. @@ -110,12 +125,12 @@ GMCH_debug (struct MeshChannel *ch); /** * Handler for mesh network payload traffic. * - * @param t Tunnel on which we got this message. + * @param ch Channel for the message. * @param message Unencryted data message. * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; */ void -GMCH_handle_data (struct MeshTunnel2 *t, +GMCH_handle_data (struct MeshChannel *ch, const struct GNUNET_MESH_Data *msg, int fwd); @@ -128,7 +143,7 @@ GMCH_handle_data (struct MeshTunnel2 *t, * @param fwd Is this a fwd ACK? (dest->orig) */ void -GMCH_handle_data_ack (struct MeshTunnel2 *t, +GMCH_handle_data_ack (struct MeshChannel *ch, const struct GNUNET_MESH_DataACK *msg, int fwd); @@ -140,9 +155,8 @@ GMCH_handle_data_ack (struct MeshTunnel2 *t, * @param msg Message. * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; */ -void -GMCH_handle_create (struct MeshTunnel2 *t, - struct GNUNET_MESH_ChannelCreate *msg, +struct MeshChannel * +GMCH_handle_create (const struct GNUNET_MESH_ChannelCreate *msg, int fwd); @@ -154,8 +168,8 @@ GMCH_handle_create (struct MeshTunnel2 *t, * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; */ void -GMCH_handle_ack (struct MeshTunnel2 *t, - struct GNUNET_MESH_ChannelManage *msg, +GMCH_handle_ack (struct MeshChannel *ch, + const struct GNUNET_MESH_ChannelManage *msg, int fwd); @@ -167,12 +181,24 @@ GMCH_handle_ack (struct MeshTunnel2 *t, * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; */ void -GMCH_handle_destroy (struct MeshTunnel2 *t, - struct GNUNET_MESH_ChannelManage *msg, +GMCH_handle_destroy (struct MeshChannel *ch, + const struct GNUNET_MESH_ChannelManage *msg, int fwd); +/** + * Sends an already built message on a channel, properly registering + * all used resources and encrypting the message with the tunnel's key. + * + * @param message Message to send. Function makes a copy of it. + * @param ch Channel on which this message is transmitted. + * @param fwd Is this a fwd message? + */ +void +GMCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message, + struct MeshChannel *ch, int fwd); + #if 0 /* keep Emacsens' auto-indent happy */ { diff --git a/src/mesh/gnunet-service-mesh_connection.c b/src/mesh/gnunet-service-mesh_connection.c index d30eabf5c..77457fcb7 100644 --- a/src/mesh/gnunet-service-mesh_connection.c +++ b/src/mesh/gnunet-service-mesh_connection.c @@ -43,32 +43,6 @@ #define LOG(level, ...) GNUNET_log_from (level,"mesh-con",__VA_ARGS__) -/** - * All the states a connection can be in. - */ -enum MeshConnectionState -{ - /** - * Uninitialized status, should never appear in operation. - */ - MESH_CONNECTION_NEW, - - /** - * Connection create message sent, waiting for ACK. - */ - MESH_CONNECTION_SENT, - - /** - * Connection ACK sent, waiting for ACK. - */ - MESH_CONNECTION_ACK, - - /** - * Connection confirmed, ready to carry traffic. - */ - MESH_CONNECTION_READY, -}; - /******************************************************************************/ /******************************** STRUCTS **********************************/ @@ -189,16 +163,10 @@ struct MeshFlowControl */ struct MeshConnection { - /** - * DLL - */ - struct MeshConnection *next; - struct MeshConnection *prev; - /** * Tunnel this connection is part of. */ - struct MeshTunnel2 *t; + struct MeshTunnel3 *t; /** * Flow control information for traffic fwd. @@ -328,7 +296,7 @@ connection_debug (struct MeshConnection *c) * @return String representation. */ static const char * -GMC_DEBUG_state2s (enum MeshTunnelState s) +GMC_state2s (enum MeshConnectionState s) { switch (s) { @@ -451,7 +419,7 @@ connection_send_ack (struct MeshConnection *c, unsigned int buffer, int fwd) static void send_connection_ack (struct MeshConnection *connection, int fwd) { - struct MeshTunnel2 *t; + struct MeshTunnel3 *t; t = connection->t; LOG (GNUNET_ERROR_TYPE_DEBUG, "Send connection ack\n"); @@ -477,7 +445,7 @@ send_connection_ack (struct MeshConnection *connection, int fwd) static void send_connection_create (struct MeshConnection *connection) { - struct MeshTunnel2 *t; + struct MeshTunnel3 *t; t = connection->t; LOG (GNUNET_ERROR_TYPE_DEBUG, "Send connection create\n"); @@ -625,54 +593,6 @@ connection_bck_keepalive (void *cls, const struct GNUNET_SCHEDULER_TaskContext * } -/** - * Send a message to all peers in this connection that the connection - * is no longer valid. - * - * If some peer should not receive the message, it should be zero'ed out - * before calling this function. - * - * @param c The connection whose peers to notify. - */ -static void -connection_send_destroy (struct MeshConnection *c) -{ - struct GNUNET_MESH_ConnectionDestroy msg; - - msg.header.size = htons (sizeof (msg)); - msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY);; - msg.cid = c->id; - LOG (GNUNET_ERROR_TYPE_DEBUG, - " sending connection destroy for connection %s[%X]\n", - peer2s (c->t->peer), - c->id); - - if (GNUNET_NO == GMC_is_terminal (c, GNUNET_YES)) - send_prebuilt_message_connection (&msg.header, c, NULL, GNUNET_YES); - if (GNUNET_NO == GMC_is_terminal (c, GNUNET_NO)) - send_prebuilt_message_connection (&msg.header, c, NULL, GNUNET_NO); - c->destroy = GNUNET_YES; -} - - -/** - * Get free buffer space in a connection. - * - * @param c Connection. - * @param fwd Is query about FWD traffic? - * - * @return Free buffer space [0 - max_msgs_queue/max_connections] - */ -static unsigned int -connection_get_buffer (struct MeshConnection *c, int fwd) -{ - struct MeshFlowControl *fc; - - fc = fwd ? &c->fwd_fc : &c->bck_fc; - - return (fc->queue_max - fc->queue_n); -} - /** * Get the first transmittable message for a connection. @@ -1383,7 +1303,7 @@ handle_mesh_encrypted (const struct GNUNET_PeerIdentity *peer, int fwd) { struct MeshConnection *c; - struct MeshTunnel2 *t; + struct MeshTunnel3 *t; struct MeshPeer *neighbor; struct MeshFlowControl *fc; uint32_t pid; @@ -1838,7 +1758,7 @@ GMC_shutdown (void) struct MeshConnection * GMC_new (const struct GNUNET_HashCode *cid, - struct MeshTunnel2 *t, + struct MeshTunnel3 *t, struct MeshPeerPath *p, unsigned int own_pos) { @@ -1911,6 +1831,12 @@ GMC_destroy (struct MeshConnection *c) GNUNET_free (c); } +struct MeshConnection * +GMC_next (struct MeshConnection *c) +{ + return c->next; +} + /** * Get the connection ID. @@ -1925,6 +1851,58 @@ GMC_get_id (const struct MeshConnection *c) return &c->id; } + +/** + * Get the connection state. + * + * @param c Connection to get the state from. + * + * @return state of the connection. + */ +enum MeshConnectionState +GMC_get_state (const struct MeshConnection *c) +{ + return c->state; +} + + +/** + * Get free buffer space in a connection. + * + * @param c Connection. + * @param fwd Is query about FWD traffic? + * + * @return Free buffer space [0 - max_msgs_queue/max_connections] + */ +unsigned int +GMC_get_buffer (struct MeshConnection *c, int fwd) +{ + struct MeshFlowControl *fc; + + fc = fwd ? &c->fwd_fc : &c->bck_fc; + + return (fc->queue_max - fc->queue_n); +} + +/** + * Get messages queued in a connection. + * + * @param c Connection. + * @param fwd Is query about FWD traffic? + * + * @return Number of messages queued. + */ +unsigned int +GMC_get_qn (struct MeshConnection *c, int fwd) +{ + struct MeshFlowControl *fc; + + fc = fwd ? &c->fwd_fc : &c->bck_fc; + + return fc->queue_n; +} + + /** * Notify other peers on a connection of a broken link. Mark connections * to destroy after all traffic has been sent. @@ -1999,23 +1977,6 @@ GMC_is_terminal (struct MeshConnection *c, int fwd) } -/** - * Count connections in a DLL. - * - * @param head Head of the DLL. - */ -unsigned int -GMC_count (const struct MeshConnection *head) -{ - unsigned int count; - struct MeshConnection *iter; - - for (count = 0, iter = head; NULL != iter; iter = iter->next, count++); - - return count; -} - - /** * Sends an already built message on a connection, properly registering * all used resources. @@ -2027,7 +1988,7 @@ GMC_count (const struct MeshConnection *head) * @param fwd Is this a fwd message? */ void -GMC_send_prebuilt_message ( const struct GNUNET_MessageHeader *message, +GMC_send_prebuilt_message (const struct GNUNET_MessageHeader *message, struct MeshConnection *c, struct MeshChannel *ch, int fwd) @@ -2106,4 +2067,37 @@ GMC_send_prebuilt_message ( const struct GNUNET_MessageHeader *message, c, ch, fwd); +} + + +/** + * Send a message to all peers in this connection that the connection + * is no longer valid. + * + * If some peer should not receive the message, it should be zero'ed out + * before calling this function. + * + * @param c The connection whose peers to notify. + */ +void +GMC_send_destroy (struct MeshConnection *c) +{ + struct GNUNET_MESH_ConnectionDestroy msg; + + if (GNUNET_YES == c->destroy) + return; + + msg.header.size = htons (sizeof (msg)); + msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY);; + msg.cid = c->id; + LOG (GNUNET_ERROR_TYPE_DEBUG, + " sending connection destroy for connection %s[%X]\n", + peer2s (c->t->peer), + c->id); + + if (GNUNET_NO == GMC_is_terminal (c, GNUNET_YES)) + GMC_send_prebuilt_message (&msg.header, c, NULL, GNUNET_YES); + if (GNUNET_NO == GMC_is_terminal (c, GNUNET_NO)) + GMC_send_prebuilt_message (&msg.header, c, NULL, GNUNET_NO); + c->destroy = GNUNET_YES; } \ No newline at end of file diff --git a/src/mesh/gnunet-service-mesh_connection.h b/src/mesh/gnunet-service-mesh_connection.h index d3f7b0b84..638bda162 100644 --- a/src/mesh/gnunet-service-mesh_connection.h +++ b/src/mesh/gnunet-service-mesh_connection.h @@ -41,6 +41,34 @@ extern "C" #include "mesh_path.h" #include "gnunet-service-mesh_channel.h" +#include "gnunet-service-mesh_peer.h" + + +/** + * All the states a connection can be in. + */ +enum MeshConnectionState +{ + /** + * Uninitialized status, should never appear in operation. + */ + MESH_CONNECTION_NEW, + + /** + * Connection create message sent, waiting for ACK. + */ + MESH_CONNECTION_SENT, + + /** + * Connection ACK sent, waiting for ACK. + */ + MESH_CONNECTION_ACK, + + /** + * Connection confirmed, ready to carry traffic. + */ + MESH_CONNECTION_READY, +}; /** @@ -203,7 +231,7 @@ GMC_shutdown (void); */ struct MeshConnection * GMC_new (const struct GNUNET_HashCode *cid, - struct MeshTunnel2 *t, + struct MeshTunnel3 *t, struct MeshPeerPath *p, unsigned int own_pos); @@ -215,6 +243,9 @@ GMC_new (const struct GNUNET_HashCode *cid, void GMC_destroy (struct MeshConnection *c); +struct MeshConnection * +GMC_next (struct MeshConnection *c); + /** * Get the connection ID. * @@ -226,10 +257,36 @@ const struct GNUNET_HashCode * GMC_get_id (const struct MeshConnection *c); /** - * Count connections in a DLL. + * Get the connection state. + * + * @param c Connection to get the state from. + * + * @return state of the connection. + */ +enum MeshConnectionState +GMC_get_state (const struct MeshConnection *c); + +/** + * Get free buffer space in a connection. + * + * @param c Connection. + * @param fwd Is query about FWD traffic? + * + * @return Free buffer space [0 - max_msgs_queue/max_connections] + */ +unsigned int +GMC_get_buffer (struct MeshConnection *c, int fwd); + +/** + * Get messages queued in a connection. + * + * @param c Connection. + * @param fwd Is query about FWD traffic? + * + * @return Number of messages queued. */ unsigned int -GMC_count (const struct MeshConnection *head); +GMC_get_qn (struct MeshConnection *c, int fwd); /** * Send FWD keepalive packets for a connection. @@ -272,51 +329,6 @@ GMC_notify_broken (struct MeshConnection *c, struct MeshPeer *peer, struct GNUNET_PeerIdentity *my_full_id); -/** - * @brief Queue and pass message to core when possible. - * - * @param cls Closure (@c type dependant). It will be used by queue_send to - * build the message to be sent if not already prebuilt. - * @param type Type of the message, 0 for a raw message. - * @param size Size of the message. - * @param c Connection this message belongs to (cannot be NULL). - * @param ch Channel this message belongs to, if applicable (otherwise NULL). - * @param fwd Is this a message going root->dest? (FWD ACK are NOT FWD!) - */ -void -GMC_queue_add (void* cls, - uint16_t type, - size_t size, - struct MeshConnection* c, - struct MeshChannel* ch, - int fwd); - - -/** - * Free a transmission that was already queued with all resources - * associated to the request. - * - * @param queue Queue handler to cancel. - * @param clear_cls Is it necessary to free associated cls? - */ -void -GMC_queue_destroy (struct MeshPeerQueue *queue, int clear_cls); - - -/** - * Core callback to write a queued packet to core buffer - * - * @param cls Closure (peer info). - * @param size Number of bytes available in buf. - * @param buf Where the to write the message. - * - * @return number of bytes written to buf - */ -size_t -GMC_queue_send (void *cls, size_t size, void *buf); - - - /** * Is this peer the first one on the connection? * @@ -356,6 +368,17 @@ GMC_send_prebuilt_message (const struct GNUNET_MessageHeader *message, struct MeshChannel *ch, int fwd); +/** + * Send a message to all peers in this connection that the connection + * is no longer valid. + * + * If some peer should not receive the message, it should be zero'ed out + * before calling this function. + * + * @param c The connection whose peers to notify. + */ +void +GMC_send_destroy (struct MeshConnection *c); #if 0 /* keep Emacsens' auto-indent happy */ { diff --git a/src/mesh/gnunet-service-mesh_local.c b/src/mesh/gnunet-service-mesh_local.c index 9714034ba..e7a30df0f 100644 --- a/src/mesh/gnunet-service-mesh_local.c +++ b/src/mesh/gnunet-service-mesh_local.c @@ -862,6 +862,19 @@ GML_client_get (struct GNUNET_SERVER_Client *client) return GNUNET_SERVER_client_get_user_context (client, struct MeshClient); } +/** + * Find a client that has opened a port + * + * @param port Port to check. + * + * @return non-NULL if a client has the port. + */ +struct MeshClient * +GML_client_get_by_port (uint32_t port) +{ + return GNUNET_CONTAINER_multihashmap32_get (ports, port); +} + /** * Deletes a tunnel from a client (either owner or destination). diff --git a/src/mesh/gnunet-service-mesh_local.h b/src/mesh/gnunet-service-mesh_local.h index 5a22c66ab..9c0069d04 100644 --- a/src/mesh/gnunet-service-mesh_local.h +++ b/src/mesh/gnunet-service-mesh_local.h @@ -81,6 +81,16 @@ GML_shutdown (void); struct MeshClient * GML_client_get (struct GNUNET_SERVER_Client *client); +/** + * Find a client that has opened a port + * + * @param port Port to check. + * + * @return non-NULL if a client has the port. + */ +struct MeshClient * +GML_client_get_by_port (uint32_t port); + /** * Deletes a tunnel from a client (either owner or destination). * diff --git a/src/mesh/gnunet-service-mesh_peer.h b/src/mesh/gnunet-service-mesh_peer.h index 821daadff..3a336fb37 100644 --- a/src/mesh/gnunet-service-mesh_peer.h +++ b/src/mesh/gnunet-service-mesh_peer.h @@ -81,16 +81,6 @@ GMP_queue_add (void *cls, uint16_t type, size_t size, struct MeshChannel *ch, int fwd); -/** - * Free a transmission that was already queued with all resources - * associated to the request. - * - * @param queue Queue handler to cancel. - * @param clear_cls Is it necessary to free associated cls? - */ -void -GMP_queue_destroy (struct MeshPeerQueue *queue, int clear_cls); - /** * Set tunnel. * @@ -98,7 +88,7 @@ GMP_queue_destroy (struct MeshPeerQueue *queue, int clear_cls); * @param t Tunnel. */ void -GMP_set_tunnel (struct MeshPeer *peer, struct MeshTunnel2 *t); +GMP_set_tunnel (struct MeshPeer *peer, struct MeshTunnel3 *t); /** * Chech whether there is a direct (core level) connection to peer. diff --git a/src/mesh/gnunet-service-mesh_tunnel.c b/src/mesh/gnunet-service-mesh_tunnel.c index 44ac78567..62545b35c 100644 --- a/src/mesh/gnunet-service-mesh_tunnel.c +++ b/src/mesh/gnunet-service-mesh_tunnel.c @@ -33,47 +33,29 @@ #define LOG(level, ...) GNUNET_log_from(level,"mesh-tun",__VA_ARGS__) -/** - * All the states a tunnel can be in. - */ -enum MeshTunnelState -{ - /** - * Uninitialized status, should never appear in operation. - */ - MESH_TUNNEL_NEW, - - /** - * Path to the peer not known yet - */ - MESH_TUNNEL_SEARCHING, - - /** - * Request sent, not yet answered. - */ - MESH_TUNNEL_WAITING, - - /** - * Peer connected and ready to accept data - */ - MESH_TUNNEL_READY, - - /** - * Peer connected previosly but not responding - */ - MESH_TUNNEL_RECONNECTING -}; - - /******************************************************************************/ /******************************** STRUCTS **********************************/ /******************************************************************************/ +struct MeshTChannel +{ + struct MeshTChannel *next; + struct MeshTChannel *prev; + struct MeshChannel *ch; +}; + +struct MeshTConnection +{ + struct MeshTConnection *next; + struct MeshTConnection *prev; + struct MeshConnection *c; +}; + /** * Struct containing all information regarding a tunnel to a peer. */ -struct MeshTunnel2 +struct MeshTunnel3 { /** * Endpoint of the tunnel. @@ -113,8 +95,8 @@ struct MeshTunnel2 /** * Paths that are actively used to reach the destination peer. */ - struct MeshConnection *connection_head; - struct MeshConnection *connection_tail; + struct MeshTConnection *connection_head; + struct MeshTConnection *connection_tail; /** * Next connection number. @@ -124,8 +106,8 @@ struct MeshTunnel2 /** * Channels inside this tunnel. */ - struct MeshChannel *channel_head; - struct MeshChannel *channel_tail; + struct MeshTChannel *channel_head; + struct MeshTChannel *channel_tail; /** * Channel ID for the next created channel. @@ -219,7 +201,7 @@ const static struct GNUNET_CRYPTO_EccPrivateKey *my_private_key; * @return String representation. */ static const char * -GNUNET_MESH_DEBUG_TS2S (enum MeshTunnelState s) +GMT_state2s (enum MeshTunnelState s) { static char buf[128]; @@ -243,6 +225,32 @@ GNUNET_MESH_DEBUG_TS2S (enum MeshTunnelState s) } +/** + * Search for a channel by global ID using full PeerIdentities. + * + * @param t Tunnel containing the channel. + * @param chid Public channel number. + * + * @return channel handler, NULL if doesn't exist + */ +static struct MeshChannel * +get_channel (struct MeshTunnel3 *t, MESH_ChannelNumber chid) +{ + struct MeshTChannel *iter; + + if (NULL == t) + return NULL; + + for (iter = t->channel_head; NULL != iter; iter = iter->next) + { + if (GMCH_get_id (iter->ch) == chid) + break; + } + + return NULL == iter ? NULL : iter->ch; +} + + /** * Pick a connection on which send the next data message. * @@ -252,34 +260,28 @@ GNUNET_MESH_DEBUG_TS2S (enum MeshTunnelState s) * @return The connection on which to send the next message. */ static struct MeshConnection * -tunnel_get_connection (struct MeshTunnel2 *t, int fwd) +tunnel_get_connection (struct MeshTunnel3 *t, int fwd) { - struct MeshConnection *c; + struct MeshTConnection *iter; struct MeshConnection *best; - struct MeshFlowControl *fc; + unsigned int qn; unsigned int lowest_q; - LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel_get_connection %s\n", - peer2s (t->peer)); + LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel_get_connection %s\n", GMP_2s (t->peer)); best = NULL; lowest_q = UINT_MAX; - for (c = t->connection_head; NULL != c; c = c->next) + for (iter = t->connection_head; NULL != iter; iter = iter->next) { LOG (GNUNET_ERROR_TYPE_DEBUG, " connection %s: %u\n", - GNUNET_h2s (GMC_get_id (c)), c->state); - if (MESH_CONNECTION_READY == c->state) + GNUNET_h2s (GMC_get_id (iter->c)), GMC_get_state (iter->c)); + if (MESH_CONNECTION_READY == GMC_get_state (iter->c)) { - fc = fwd ? &c->fwd_fc : &c->bck_fc; - if (NULL == fc) - { - GNUNET_break (0); - continue; - } - LOG (GNUNET_ERROR_TYPE_DEBUG, " q_n %u, \n", fc->queue_n); - if (fc->queue_n < lowest_q) + qn = GMC_get_qn (iter->c, fwd); + LOG (GNUNET_ERROR_TYPE_DEBUG, " q_n %u, \n", qn); + if (qn < lowest_q) { - best = c; - lowest_q = fc->queue_n; + best = iter->c; + lowest_q = qn; } } } @@ -296,27 +298,26 @@ tunnel_get_connection (struct MeshTunnel2 *t, int fwd) * @return Buffer space offered by all connections in the tunnel. */ static unsigned int -tunnel_get_buffer (struct MeshTunnel2 *t, int fwd) +tunnel_get_buffer (struct MeshTunnel3 *t, int fwd) { - struct MeshConnection *c; - struct MeshFlowControl *fc; + struct MeshTConnection *iter; unsigned int buffer; - c = t->connection_head; + iter = t->connection_head; buffer = 0; /* If terminal, return biggest channel buffer */ - if (NULL == c || GMC_is_terminal (c, fwd)) + if (NULL == iter || GMC_is_terminal (iter->c, fwd)) { - struct MeshChannel *ch; + struct MeshTChannel *iter_ch; unsigned int ch_buf; if (NULL == t->channel_head) return 64; - for (ch = t->channel_head; NULL != ch; ch = ch->next) + for (iter_ch = t->channel_head; NULL != iter_ch; iter_ch = iter_ch->next) { - ch_buf = GMCH_get_buffer (ch, fwd); + ch_buf = GMCH_get_buffer (iter_ch->ch, fwd); if (ch_buf > buffer) buffer = ch_buf; } @@ -324,17 +325,16 @@ tunnel_get_buffer (struct MeshTunnel2 *t, int fwd) } /* If not terminal, return sum of connection buffers */ - while (NULL != c) + while (NULL != iter) { - if (c->state != MESH_CONNECTION_READY) + if (GMC_get_state (iter->c) != MESH_CONNECTION_READY) { - c = c->next; + iter = iter->next; continue; } - fc = fwd ? &c->fwd_fc : &c->bck_fc; - buffer += fc->queue_max - fc->queue_n; - c = c->next; + buffer += GMC_get_buffer (iter->c, fwd); + iter = iter->next; } return buffer; @@ -348,7 +348,7 @@ tunnel_get_buffer (struct MeshTunnel2 *t, int fwd) * @param fwd Is this fwd? */ static void -tunnel_send_queued_data (struct MeshTunnel2 *t, int fwd) +tunnel_send_queued_data (struct MeshTunnel3 *t, int fwd) { struct MeshTunnelQueue *tq; struct MeshTunnelQueue *next; @@ -356,7 +356,7 @@ tunnel_send_queued_data (struct MeshTunnel2 *t, int fwd) LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel_send_queued_data on tunnel %s\n", - peer2s (t->peer)); + GMP_2s (t->peer)); room = tunnel_get_buffer (t, fwd); LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer space: %u\n", room); for (tq = t->tq_head; NULL != tq && room > 0; tq = next) @@ -371,11 +371,228 @@ tunnel_send_queued_data (struct MeshTunnel2 *t, int fwd) } } +void +handle_data (struct MeshTunnel3 *t, + const struct GNUNET_MESH_Data *msg, + int fwd) +{ + struct MeshChannel *ch; + uint16_t type; + size_t size; + + /* Check size */ + size = ntohs (msg->header.size); + if (size < + sizeof (struct GNUNET_MESH_Data) + + sizeof (struct GNUNET_MessageHeader)) + { + GNUNET_break (0); + return; + } + type = ntohs (msg->header.type); + LOG (GNUNET_ERROR_TYPE_DEBUG, "got a %s message\n", + GNUNET_MESH_DEBUG_M2S (type)); + LOG (GNUNET_ERROR_TYPE_DEBUG, " payload of type %s\n", + GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type))); + + /* Check channel */ + ch = get_channel (t, ntohl (msg->chid)); + if (NULL == ch) + { + GNUNET_STATISTICS_update (stats, "# data on unknown channel", + 1, GNUNET_NO); + LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n", + ntohl (msg->chid)); + return; + } + + GMT_change_state (t, MESH_TUNNEL_READY); + GMCH_handle_data (ch, msg, fwd); +} + +void +handle_data_ack (struct MeshTunnel3 *t, + const struct GNUNET_MESH_DataACK *msg, + int fwd) +{ + struct MeshChannel *ch; + size_t size; + + /* Check size */ + size = ntohs (msg->header.size); + if (size != sizeof (struct GNUNET_MESH_DataACK)) + { + GNUNET_break (0); + return; + } + + /* Check channel */ + ch = get_channel (t, ntohl (msg->chid)); + if (NULL == ch) + { + GNUNET_STATISTICS_update (stats, "# data ack on unknown channel", + 1, GNUNET_NO); + LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n", + ntohl (msg->chid)); + return; + } + + GMCH_handle_data_ack (ch, msg, fwd); +} + +void +handle_ch_create (struct MeshTunnel3 *t, + const struct GNUNET_MESH_ChannelCreate *msg, + int fwd) +{ + struct MeshTChannel *tch; + struct MeshChannel *ch; + size_t size; + + /* Check size */ + size = ntohs (msg->header.size); + if (size != sizeof (struct GNUNET_MESH_ChannelCreate)) + { + GNUNET_break (0); + return; + } + + /* Check channel */ + ch = get_channel (t, ntohl (msg->chid)); + if (NULL != ch) + { + /* Probably a retransmission, safe to ignore */ + LOG (GNUNET_ERROR_TYPE_DEBUG, " already exists...\n"); + } + else + { + ch = GMCH_handle_create (msg, fwd); + } + + tch = GNUNET_new (struct MeshTChannel); + tch->ch = ch; + GNUNET_CONTAINER_DLL_insert (t->channel_head, t->channel_tail, tch); +} + +void +handle_ch_ack (struct MeshTunnel3 *t, + const struct GNUNET_MESH_ChannelManage *msg, + int fwd) +{ + struct MeshChannel *ch; + size_t size; + + /* Check size */ + size = ntohs (msg->header.size); + if (size != sizeof (struct GNUNET_MESH_ChannelManage)) + { + GNUNET_break (0); + return; + } + + /* Check channel */ + ch = get_channel (t, ntohl (msg->chid)); + if (NULL == ch) + { + GNUNET_STATISTICS_update (stats, "# channel ack on unknown channel", + 1, GNUNET_NO); + LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n", + ntohl (msg->chid)); + return; + } + + GMCH_handle_ack (ch, msg, fwd); +} + +void +handle_ch_destroy (struct MeshTunnel3 *t, + const struct GNUNET_MESH_ChannelManage *msg, + int fwd) +{ + struct MeshChannel *ch; + size_t size; + + /* Check size */ + size = ntohs (msg->header.size); + if (size != sizeof (struct GNUNET_MESH_ChannelManage)) + { + GNUNET_break (0); + return; + } + + /* Check channel */ + ch = get_channel (t, ntohl (msg->chid)); + if (NULL == ch) + { + /* Probably a retransmission, safe to ignore */ + return; + } + + GMCH_handle_destroy (ch, msg, fwd); +} /******************************************************************************/ /******************************** API ***********************************/ /******************************************************************************/ +/** + * Demultiplex by message type and call appropriate handler for a message + * towards a channel of a local tunnel. + * + * @param t Tunnel this message came on. + * @param msgh Message header. + * @param fwd Is this message fwd? + */ +void +GMT_handle_decrypted (struct MeshTunnel3 *t, + const struct GNUNET_MessageHeader *msgh, + int fwd) +{ + uint16_t type; + + type = ntohs (msgh->type); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Got a %s message!\n", + GNUNET_MESH_DEBUG_M2S (type)); + + switch (type) + { + case GNUNET_MESSAGE_TYPE_MESH_DATA: + /* Don't send hop ACK, wait for client to ACK */ + handle_data (t, (struct GNUNET_MESH_Data *) msgh, fwd); + break; + + case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK: + handle_data_ack (t, (struct GNUNET_MESH_DataACK *) msgh, fwd); + break; + + case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE: + handle_ch_create (t, + (struct GNUNET_MESH_ChannelCreate *) msgh, + fwd); + break; + + case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK: + handle_ch_ack (t, + (struct GNUNET_MESH_ChannelManage *) msgh, + fwd); + break; + + case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY: + handle_ch_destroy (t, + (struct GNUNET_MESH_ChannelManage *) msgh, + fwd); + break; + + default: + GNUNET_break_op (0); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "end-to-end message not known (%u)\n", + ntohs (msgh->type)); + } +} + + /** * Cache a message to be sent once tunnel is online. * @@ -385,7 +602,7 @@ tunnel_send_queued_data (struct MeshTunnel2 *t, int fwd) * @param fwd Is this fwd? */ void -GMT_queue_data (struct MeshTunnel2 *t, +GMT_queue_data (struct MeshTunnel3 *t, struct MeshChannel *ch, struct GNUNET_MessageHeader *msg, int fwd) @@ -420,7 +637,7 @@ GMT_init (const struct GNUNET_CONFIGURATION_Handle *c, GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DEFAULT_TTL", &default_ttl)) { - LOG_config_invalid (GNUNET_ERROR_TYPE_WARNING, + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, "MESH", "DEFAULT_TTL", "USING DEFAULT"); default_ttl = 64; } @@ -443,12 +660,12 @@ GMT_shutdown (void) /** * Create a tunnel. */ -struct MeshTunnel2 * +struct MeshTunnel3 * GMT_new (void) { - struct MeshTunnel2 *t; + struct MeshTunnel3 *t; - t = GNUNET_new (struct MeshTunnel2); + t = GNUNET_new (struct MeshTunnel3); t->next_chid = 0; t->next_local_chid = GNUNET_MESH_LOCAL_CHANNEL_ID_SERV; // if (GNUNET_OK != @@ -486,18 +703,18 @@ GMT_new (void) * @param state New state. */ void -GMT_change_state (struct MeshTunnel2* t, enum MeshTunnelState state) +GMT_change_state (struct MeshTunnel3* t, enum MeshTunnelState state) { if (NULL == t) return; LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s state was %s\n", - peer2s (t->peer), - GNUNET_MESH_DEBUG_TS2S (t->state)); + GMP_2s (t->peer), + GMT_state2s (t->state)); LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s state is now %s\n", - peer2s (t->peer), - GNUNET_MESH_DEBUG_TS2S (state)); + GMP_2s (t->peer), + GMT_state2s (state)); t->state = state; } @@ -509,17 +726,18 @@ GMT_change_state (struct MeshTunnel2* t, enum MeshTunnelState state) * @param c Connection. */ void -GMT_add_connection (struct MeshTunnel2 *t, struct MeshConnection *c) +GMT_add_connection (struct MeshTunnel3 *t, struct MeshConnection *c) { - struct MeshConnection *aux; - c->t = t; + struct MeshTConnection *aux; + for (aux = t->connection_head; aux != NULL; aux = aux->next) - if (aux == c) + if (aux->c == c) return; - GNUNET_CONTAINER_DLL_insert_tail (t->connection_head, t->connection_tail, c); -} - + aux = GNUNET_new (struct MeshTConnection); + aux->c = c; + GNUNET_CONTAINER_DLL_insert_tail (t->connection_head, t->connection_tail, aux); +} /** @@ -530,14 +748,13 @@ GMT_add_connection (struct MeshTunnel2 *t, struct MeshConnection *c) * @param t Tunnel to destroy. */ void -GMT_destroy_empty (struct MeshTunnel2 *t) +GMT_destroy_empty (struct MeshTunnel3 *t) { - struct MeshConnection *c; + struct MeshTConnection *iter; - for (c = t->connection_head; NULL != c; c = c->next) + for (iter = t->connection_head; NULL != iter; iter = iter->next) { - if (GNUNET_NO == c->destroy) - GMC_send_destroy (c); + GMC_send_destroy (iter->c); } if (0 == t->pending_messages) @@ -553,16 +770,15 @@ GMT_destroy_empty (struct MeshTunnel2 *t) * @param t Tunnel to destroy if empty. */ void -GMT_destroy_if_empty (struct MeshTunnel2 *t) +GMT_destroy_if_empty (struct MeshTunnel3 *t) { - if (1 < GMCH_count (t->channel_head)) + if (1 < GMT_count_channels (t)) return; GMT_destroy_empty (t); } - /** * Destroy the tunnel. * @@ -575,24 +791,24 @@ GMT_destroy_if_empty (struct MeshTunnel2 *t) * @param t The tunnel to destroy. */ void -GMT_destroy (struct MeshTunnel2 *t) +GMT_destroy (struct MeshTunnel3 *t) { - struct MeshConnection *c; - struct MeshConnection *next; + struct MeshTConnection *iter; + struct MeshTConnection *next; if (NULL == t) return; - LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s\n", - peer2s (t->peer)); + LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s\n", GMP_2s (t->peer)); // if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (tunnels, &t->id, t)) // GNUNET_break (0); - for (c = t->connection_head; NULL != c; c = next) + for (iter = t->connection_head; NULL != iter; iter = next) { - next = c->next; - GMC_destroy (c); + next = iter->next; + GMC_destroy (iter->c); + GNUNET_free (iter); } GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO); @@ -601,56 +817,6 @@ GMT_destroy (struct MeshTunnel2 *t) GNUNET_free (t); } -/** - * Demultiplex by message type and call appropriate handler for a message - * towards a channel of a local tunnel. - * - * @param t Tunnel this message came on. - * @param msgh Message header. - * @param fwd Is this message fwd? - */ -void -GMT_handle_decrypted (struct MeshTunnel2 *t, - const struct GNUNET_MessageHeader *msgh, - int fwd) -{ - switch (ntohs (msgh->type)) - { - case GNUNET_MESSAGE_TYPE_MESH_DATA: - /* Don't send hop ACK, wait for client to ACK */ - GMCH_handle_data (t, (struct GNUNET_MESH_Data *) msgh, fwd); - break; - - case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK: - GMCH_handle_data_ack (t, (struct GNUNET_MESH_DataACK *) msgh, fwd); - break; - - case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE: - GMCH_handle_create (t, - (struct GNUNET_MESH_ChannelCreate *) msgh, - fwd); - break; - - case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK: - GMCH_handle_ack (t, - (struct GNUNET_MESH_ChannelManage *) msgh, - fwd); - break; - - case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY: - GMCH_handle_destroy (t, - (struct GNUNET_MESH_ChannelManage *) msgh, - fwd); - break; - - default: - GNUNET_break_op (0); - LOG (GNUNET_ERROR_TYPE_DEBUG, - "end-to-end message not known (%u)\n", - ntohs (msgh->type)); - } -} - /** * Notifies a tunnel that a connection has broken that affects at least @@ -668,7 +834,7 @@ GMT_handle_decrypted (struct MeshTunnel2 *t, * 0 if the tunnel remained unaffected. */ GNUNET_PEER_Id -GMT_notify_connection_broken (struct MeshTunnel2* t, +GMT_notify_connection_broken (struct MeshTunnel3* t, GNUNET_PEER_Id p1, GNUNET_PEER_Id p2) { // if (myid != p1 && myid != p2) FIXME @@ -705,7 +871,7 @@ GMT_notify_connection_broken (struct MeshTunnel2* t, * @return Connection created. */ struct MeshConnection * -GMT_use_path (struct MeshTunnel2 *t, struct MeshPeerPath *p) +GMT_use_path (struct MeshTunnel3 *t, struct MeshPeerPath *p) { struct MeshConnection *c; struct GNUNET_HashCode cid; @@ -730,7 +896,7 @@ GMT_use_path (struct MeshTunnel2 *t, struct MeshPeerPath *p) GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, &cid); c = GMC_new (&cid, t, p, own_pos); - GNUNET_CONTAINER_DLL_insert (t->connection_head, t->connection_tail, c); + GMT_add_connection (t, c); return c; } @@ -747,7 +913,7 @@ GMT_use_path (struct MeshTunnel2 *t, struct MeshPeerPath *p) * @param fwd Is this a fwd message? */ void -GMT_encrypt (struct MeshTunnel2 *t, +GMT_encrypt (struct MeshTunnel3 *t, void *dst, const void *src, size_t size, uint64_t iv, int fwd) { @@ -767,7 +933,7 @@ GMT_encrypt (struct MeshTunnel2 *t, * @param fwd Is this a fwd message? */ void -GMT_decrypt (struct MeshTunnel2 *t, +GMT_decrypt (struct MeshTunnel3 *t, void *dst, const void *src, size_t size, uint64_t iv, int fwd) { @@ -778,14 +944,41 @@ GMT_decrypt (struct MeshTunnel2 *t, /** * Count established (ready) connections of a tunnel. * - * @param t Tunnel on which to send the message. + * @param t Tunnel on which to count. * * @return Number of connections. */ unsigned int -GMT_count_connections (struct MeshTunnel2 *t) +GMT_count_connections (struct MeshTunnel3 *t) +{ + struct MeshTConnection *iter; + unsigned int count; + + for (count = 0, iter = t->connection_head; + NULL != iter; + iter = iter->next, count++); + + return count; +} + +/** + * Count channels of a tunnel. + * + * @param t Tunnel on which to count. + * + * @return Number of channels. + */ +unsigned int +GMT_count_channels (struct MeshTunnel3 *t) { - return GMC_count (t->connection_head); + struct MeshTChannel *iter; + unsigned int count; + + for (count = 0, iter = t->channel_head; + NULL != iter; + iter = iter->next, count++); + + return count; } @@ -799,15 +992,14 @@ GMT_count_connections (struct MeshTunnel2 *t) */ void GMT_send_prebuilt_message (struct GNUNET_MESH_Encrypted *msg, - struct MeshTunnel2 *t, + struct MeshTunnel3 *t, struct MeshChannel *ch, int fwd) { struct MeshConnection *c; uint16_t type; - LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Tunnel %s\n", - peer2s (t->peer)); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Tunnel %s\n", GMP_2s (t->peer)); c = tunnel_get_connection (t, fwd); if (NULL == c) { diff --git a/src/mesh/gnunet-service-mesh_tunnel.h b/src/mesh/gnunet-service-mesh_tunnel.h index cd7c5670c..76b867cbc 100644 --- a/src/mesh/gnunet-service-mesh_tunnel.h +++ b/src/mesh/gnunet-service-mesh_tunnel.h @@ -40,11 +40,44 @@ extern "C" #include "platform.h" #include "gnunet_util_lib.h" +#include "gnunet-service-mesh_channel.h" + + /** - * Struct containing all information regarding a given peer + * All the states a tunnel can be in. */ -struct MeshTunnel2; +enum MeshTunnelState +{ + /** + * Uninitialized status, should never appear in operation. + */ + MESH_TUNNEL_NEW, + + /** + * Path to the peer not known yet + */ + MESH_TUNNEL_SEARCHING, + + /** + * Request sent, not yet answered. + */ + MESH_TUNNEL_WAITING, + + /** + * Peer connected and ready to accept data + */ + MESH_TUNNEL_READY, + + /** + * Peer connected previosly but not responding + */ + MESH_TUNNEL_RECONNECTING +}; +/** + * Struct containing all information regarding a given peer + */ +struct MeshTunnel3; /******************************************************************************/ /******************************** API ***********************************/ @@ -68,6 +101,38 @@ GMT_init (const struct GNUNET_CONFIGURATION_Handle *c, void GMT_shutdown (void); +/** + * Tunnel is empty: destroy it. + * + * Notifies all connections about the destruction. + * + * @param t Tunnel to destroy. + */ +void +GMT_destroy_empty (struct MeshTunnel3 *t); + +/** + * Destroy tunnel if empty (no more channels). + * + * @param t Tunnel to destroy if empty. + */ +void +GMT_destroy_if_empty (struct MeshTunnel3 *t); + +/** + * Destroy the tunnel. + * + * This function does not generate any warning traffic to clients or peers. + * + * Tasks: + * Cancel messages belonging to this tunnel queued to neighbors. + * Free any allocated resources linked to the tunnel. + * + * @param t The tunnel to destroy. + */ +void +GMT_destroy (struct MeshTunnel3 *t); + /** * Change the tunnel state. * @@ -75,7 +140,7 @@ GMT_shutdown (void); * @param state New state. */ void -GMT_change_state (struct MeshTunnel2* t, enum MeshTunnelState state); +GMT_change_state (struct MeshTunnel3* t, enum MeshTunnelState state); /** @@ -87,11 +152,31 @@ GMT_change_state (struct MeshTunnel2* t, enum MeshTunnelState state); * @param fwd Is this fwd? */ void -GMT_queue_data (struct MeshTunnel2 *t, +GMT_queue_data (struct MeshTunnel3 *t, struct MeshChannel *ch, struct GNUNET_MessageHeader *msg, int fwd); +/** + * Count established (ready) connections of a tunnel. + * + * @param t Tunnel on which to count. + * + * @return Number of connections. + */ +unsigned int +GMT_count_connections (struct MeshTunnel3 *t); + +/** + * Count channels of a tunnel. + * + * @param t Tunnel on which to count. + * + * @return Number of channels. + */ +unsigned int +GMT_count_channels (struct MeshTunnel3 *t); + #if 0 /* keep Emacsens' auto-indent happy */ { #endif