/**
* 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.
}
-
-/**
- * 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.
*
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)
{
}
-/**
- * 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.
unsigned int buffer,
int fwd)
{
- struct MeshTunnel2 *t = ch->t;
+ struct MeshTunnel3 *t = ch->t;
struct MeshConnection *c;
struct MeshFlowControl *fc;
uint32_t allowed;
* @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;
{
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",
}
+/******************************************************************************/
+/******************************** 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);
}
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)
/**
* 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;
return;
}
- GMT_change_state (t, MESH_TUNNEL_READY);
-
GNUNET_STATISTICS_update (stats, "# data received", 1, GNUNET_NO);
mid = ntohl (msg->mid);
* @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);
* @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;
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 */
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);
}
/**
* 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) */
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);
+}
#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.
/**
* 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);
* @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);
* @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);
* @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);
* @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 */
{
#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 **********************************/
*/
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.
* @return String representation.
*/
static const char *
-GMC_DEBUG_state2s (enum MeshTunnelState s)
+GMC_state2s (enum MeshConnectionState s)
{
switch (s)
{
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");
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");
}
-/**
- * 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.
int fwd)
{
struct MeshConnection *c;
- struct MeshTunnel2 *t;
+ struct MeshTunnel3 *t;
struct MeshPeer *neighbor;
struct MeshFlowControl *fc;
uint32_t pid;
struct MeshConnection *
GMC_new (const struct GNUNET_HashCode *cid,
- struct MeshTunnel2 *t,
+ struct MeshTunnel3 *t,
struct MeshPeerPath *p,
unsigned int own_pos)
{
GNUNET_free (c);
}
+struct MeshConnection *
+GMC_next (struct MeshConnection *c)
+{
+ return c->next;
+}
+
/**
* Get the connection ID.
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.
}
-/**
- * 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.
* @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)
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
#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,
+};
/**
*/
struct MeshConnection *
GMC_new (const struct GNUNET_HashCode *cid,
- struct MeshTunnel2 *t,
+ struct MeshTunnel3 *t,
struct MeshPeerPath *p,
unsigned int own_pos);
void
GMC_destroy (struct MeshConnection *c);
+struct MeshConnection *
+GMC_next (struct MeshConnection *c);
+
/**
* Get the connection ID.
*
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.
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?
*
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 */
{
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).
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).
*
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.
*
* @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.
#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.
/**
* 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.
/**
* 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.
* @return String representation.
*/
static const char *
-GNUNET_MESH_DEBUG_TS2S (enum MeshTunnelState s)
+GMT_state2s (enum MeshTunnelState s)
{
static char buf[128];
}
+/**
+ * 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.
*
* @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;
}
}
}
* @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;
}
}
/* 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;
* @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;
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)
}
}
+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.
*
* @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)
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;
}
/**
* 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 !=
* @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;
}
* @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);
+}
/**
* @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)
* @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.
*
* @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);
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
* 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
* @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;
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;
}
* @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)
{
* @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)
{
/**
* 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;
}
*/
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)
{
#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 ***********************************/
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.
*
* @param state New state.
*/
void
-GMT_change_state (struct MeshTunnel2* t, enum MeshTunnelState state);
+GMT_change_state (struct MeshTunnel3* 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