[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r30889 - gnunet/src/mesh
From: |
gnunet |
Subject: |
[GNUnet-SVN] r30889 - gnunet/src/mesh |
Date: |
Wed, 27 Nov 2013 05:19:13 +0100 |
Author: bartpolot
Date: 2013-11-27 05:19:13 +0100 (Wed, 27 Nov 2013)
New Revision: 30889
Modified:
gnunet/src/mesh/gnunet-service-mesh_channel.c
gnunet/src/mesh/gnunet-service-mesh_connection.c
gnunet/src/mesh/gnunet-service-mesh_peer.c
gnunet/src/mesh/gnunet-service-mesh_tunnel.c
gnunet/src/mesh/gnunet-service-mesh_tunnel.h
Log:
- tunnels need separate connectivity state and encryption/handshake states
Modified: gnunet/src/mesh/gnunet-service-mesh_channel.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh_channel.c 2013-11-27 01:59:58 UTC
(rev 30888)
+++ gnunet/src/mesh/gnunet-service-mesh_channel.c 2013-11-27 04:19:13 UTC
(rev 30889)
@@ -1506,7 +1506,7 @@
if (GMP_get_short_id (peer) == myid)
{
- GMT_change_state (t, MESH_TUNNEL3_READY);
+ GMT_change_cstate (t, MESH_TUNNEL3_READY);
}
else
{
Modified: gnunet/src/mesh/gnunet-service-mesh_connection.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh_connection.c 2013-11-27 01:59:58 UTC
(rev 30888)
+++ gnunet/src/mesh/gnunet-service-mesh_connection.c 2013-11-27 04:19:13 UTC
(rev 30889)
@@ -710,8 +710,8 @@
sizeof (struct GNUNET_MESH_ConnectionACK),
connection, fwd, &message_sent, NULL);
connection->pending_messages++;
- if (MESH_TUNNEL3_NEW == GMT_get_state (t))
- GMT_change_state (t, MESH_TUNNEL3_WAITING);
+ if (MESH_TUNNEL3_NEW == GMT_get_cstate (t))
+ GMT_change_cstate (t, MESH_TUNNEL3_WAITING);
if (MESH_CONNECTION_READY != connection->state)
connection_change_state (connection, MESH_CONNECTION_SENT);
}
@@ -803,7 +803,7 @@
static void
connection_maintain (struct MeshConnection *c, int fwd)
{
- if (MESH_TUNNEL3_SEARCHING == GMT_get_state (c->t))
+ if (MESH_TUNNEL3_SEARCHING == GMT_get_cstate (c->t))
{
/* TODO DHT GET with RO_BART */
return;
@@ -1284,8 +1284,8 @@
GMP_add_path_to_origin (orig_peer, path_duplicate (path), GNUNET_YES);
add_to_peer (c, orig_peer);
- if (MESH_TUNNEL3_NEW == GMT_get_state (c->t))
- GMT_change_state (c->t, MESH_TUNNEL3_WAITING);
+ if (MESH_TUNNEL3_NEW == GMT_get_cstate (c->t))
+ GMT_change_cstate (c->t, MESH_TUNNEL3_WAITING);
send_connection_ack (c, GNUNET_NO);
if (MESH_CONNECTION_SENT == c->state)
@@ -1395,8 +1395,8 @@
/* Change connection and tunnel state */
connection_change_state (c, MESH_CONNECTION_READY);
- if (MESH_TUNNEL3_WAITING == GMT_get_state (c->t))
- GMT_change_state (c->t, MESH_TUNNEL3_READY);
+ if (MESH_TUNNEL3_WAITING == GMT_get_cstate (c->t))
+ GMT_change_cstate (c->t, MESH_TUNNEL3_READY);
/* Send ACK (~TCP ACK)*/
send_connection_ack (c, GNUNET_YES);
@@ -1418,8 +1418,8 @@
connection_reset_timeout (c, GNUNET_NO);
/* Change tunnel state */
- if (MESH_TUNNEL3_WAITING == GMT_get_state (c->t))
- GMT_change_state (c->t, MESH_TUNNEL3_READY);
+ if (MESH_TUNNEL3_WAITING == GMT_get_cstate (c->t))
+ GMT_change_cstate (c->t, MESH_TUNNEL3_READY);
return GNUNET_OK;
}
@@ -1734,8 +1734,8 @@
connection_reset_timeout (c, fwd);
if (NULL != c->t)
{
- if (MESH_TUNNEL3_WAITING == GMT_get_state (c->t))
- GMT_change_state (c->t, MESH_TUNNEL3_READY);
+ if (MESH_TUNNEL3_WAITING == GMT_get_cstate (c->t))
+ GMT_change_cstate (c->t, MESH_TUNNEL3_READY);
}
/* Is this message for us? */
@@ -2652,7 +2652,7 @@
void
GMC_send_create (struct MeshConnection *connection)
{
- enum MeshTunnel3State state;
+ enum MeshTunnel3CState state;
size_t size;
size = sizeof (struct GNUNET_MESH_ConnectionCreate);
@@ -2664,9 +2664,9 @@
LOG (GNUNET_ERROR_TYPE_DEBUG, " C_P+ %p %u (create)\n",
connection, connection->pending_messages);
connection->pending_messages++;
- state = GMT_get_state (connection->t);
+ state = GMT_get_cstate (connection->t);
if (MESH_TUNNEL3_SEARCHING == state || MESH_TUNNEL3_NEW == state)
- GMT_change_state (connection->t, MESH_TUNNEL3_WAITING);
+ GMT_change_cstate (connection->t, MESH_TUNNEL3_WAITING);
if (MESH_CONNECTION_NEW == connection->state)
connection_change_state (connection, MESH_CONNECTION_SENT);
}
@@ -2765,6 +2765,9 @@
const char *
GMC_2s (struct MeshConnection *c)
{
+ if (NULL == c)
+ return "NULL";
+
if (NULL != c->t)
{
static char buf[128];
Modified: gnunet/src/mesh/gnunet-service-mesh_peer.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh_peer.c 2013-11-27 01:59:58 UTC (rev
30888)
+++ gnunet/src/mesh/gnunet-service-mesh_peer.c 2013-11-27 04:19:13 UTC (rev
30889)
@@ -436,7 +436,7 @@
GNUNET_PEER_resolve (p->peers[i], peer_ptr++);
}
- LOG (GNUNET_ERROR_TYPE_DEBUG,
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
"CONNECTION CREATE (%u bytes long) sent!\n",
size_needed);
return size_needed;
@@ -738,7 +738,7 @@
if (3 <= connection_count)
return;
- if (MESH_TUNNEL3_SEARCHING == GMT_get_state (peer->tunnel))
+ if (MESH_TUNNEL3_SEARCHING == GMT_get_cstate (peer->tunnel))
{
LOG (GNUNET_ERROR_TYPE_DEBUG, " ... connect!\n");
GMP_connect (peer);
@@ -755,7 +755,7 @@
* @param buf Where the to write the message.
*
* @return number of bytes written to buf
- *
+ *
* FIXME add GNUNET_MESSAGE_TYPE_MESH_KEEPALIVE
*/
static size_t
@@ -787,6 +787,7 @@
dst_id = GNUNET_PEER_resolve2 (peer->id);
LOG (GNUNET_ERROR_TYPE_DEBUG, "* towards %s\n", GNUNET_i2s (dst_id));
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "* on connection %s\n", GMC_2s (c));
/* Check if buffer size is enough for the message */
if (queue->size > size)
{
@@ -1341,7 +1342,7 @@
{
GMD_search_stop (peer->search_h);
peer->search_h = NULL;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
" Stopping DHT GET for peer %s\n",
GMP_2s (peer));
}
@@ -1354,8 +1355,8 @@
LOG (GNUNET_ERROR_TYPE_DEBUG,
" Starting DHT GET for peer %s\n", GMP_2s (peer));
peer->search_h = GMD_search (id, &search_handler, peer);
- if (MESH_TUNNEL3_NEW == GMT_get_state (t))
- GMT_change_state (t, MESH_TUNNEL3_SEARCHING);
+ if (MESH_TUNNEL3_NEW == GMT_get_cstate (t))
+ GMT_change_cstate (t, MESH_TUNNEL3_SEARCHING);
}
}
@@ -1709,4 +1710,4 @@
if (NULL == peer)
return "(NULL)";
return GNUNET_i2s (GNUNET_PEER_resolve2 (peer->id));
-}
\ No newline at end of file
+}
Modified: gnunet/src/mesh/gnunet-service-mesh_tunnel.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh_tunnel.c 2013-11-27 01:59:58 UTC
(rev 30888)
+++ gnunet/src/mesh/gnunet-service-mesh_tunnel.c 2013-11-27 04:19:13 UTC
(rev 30889)
@@ -82,11 +82,16 @@
struct MeshPeer *peer;
/**
- * State of the tunnel.
+ * State of the tunnel connectivity.
*/
- enum MeshTunnel3State state;
+ enum MeshTunnel3CState cstate;
/**
+ * State of the tunnel encryption.
+ */
+ enum MeshTunnel3EState estate;
+
+ /**
* Key eXchange context.
*/
struct MeshTunnelKXCtx *kx_ctx;
@@ -247,18 +252,18 @@
/******************************************************************************/
/**
- * Get string description for tunnel state.
+ * Get string description for tunnel connectivity state.
*
- * @param s Tunnel state.
+ * @param cs Tunnel state.
*
* @return String representation.
*/
static const char *
-GMT_state2s (enum MeshTunnel3State s)
+cstate2s (enum MeshTunnel3CState cs)
{
static char buf[128];
- switch (s)
+ switch (cs)
{
case MESH_TUNNEL3_NEW:
return "MESH_TUNNEL3_NEW";
@@ -266,23 +271,67 @@
return "MESH_TUNNEL3_SEARCHING";
case MESH_TUNNEL3_WAITING:
return "MESH_TUNNEL3_WAITING";
- case MESH_TUNNEL3_KEY_SENT:
- return "MESH_TUNNEL3_KEY_SENT";
case MESH_TUNNEL3_READY:
return "MESH_TUNNEL3_READY";
- case MESH_TUNNEL3_RECONNECTING:
- return "MESH_TUNNEL3_RECONNECTING";
- case MESH_TUNNEL3_REKEY:
- return "MESH_TUNNEL3_REKEY";
default:
- sprintf (buf, "%u (UNKNOWN STATE)", s);
+ sprintf (buf, "%u (UNKNOWN STATE)", cs);
return buf;
}
+ return "";
}
/**
+ * Get string description for tunnel encryption state.
+ *
+ * @param es Tunnel state.
+ *
+ * @return String representation.
+ */
+static const char *
+estate2s (enum MeshTunnel3EState es)
+{
+ static char buf[128];
+
+ switch (es)
+ {
+ case MESH_TUNNEL3_KEY_UNINITIALIZED:
+ return "MESH_TUNNEL3_KEY_UNINITIALIZED";
+ case MESH_TUNNEL3_KEY_SENT:
+ return "MESH_TUNNEL3_KEY_SENT";
+ case MESH_TUNNEL3_KEY_PING:
+ return "MESH_TUNNEL3_KEY_PING";
+ case MESH_TUNNEL3_KEY_OK:
+ return "MESH_TUNNEL3_KEY_OK";
+
+ default:
+ sprintf (buf, "%u (UNKNOWN STATE)", es);
+ return buf;
+ }
+ return "";
+}
+
+
+/**
+ * @brief Check if tunnel is ready to send traffic.
+ *
+ * Tunnel must be connected and with encryption correctly set up.
+ *
+ * @param t Tunnel to check.
+ *
+ * @return #GNUNET_YES if ready, #GNUNET_NO otherwise
+ */
+static int
+is_ready (struct MeshTunnel3 *t)
+{
+ return (MESH_TUNNEL3_READY == t->cstate
+ && MESH_TUNNEL3_KEY_OK == t->estate)
+ || GMT_is_loopback (t);
+}
+
+
+/**
* Ephemeral key message purpose size.
*
* @return Size of the part of the ephemeral key message that must be signed.
@@ -531,7 +580,7 @@
for (iter = t->connection_head; NULL != iter; iter = iter->next)
{
LOG (GNUNET_ERROR_TYPE_DEBUG, " connection %s: %u\n",
- GNUNET_h2s (GMC_get_id (iter->c)), GMC_get_state (iter->c));
+ GMC_2s (iter->c), GMC_get_state (iter->c));
if (MESH_CONNECTION_READY == GMC_get_state (iter->c))
{
qn = GMC_get_qn (iter->c, GMC_is_origin (iter->c, GNUNET_YES));
@@ -543,6 +592,7 @@
}
}
}
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " selected: connection %s\n", GMC_2s (best));
return best;
}
@@ -569,6 +619,13 @@
return;
}
+ if (GNUNET_NO == is_ready (t))
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " not ready yet: %s/%s\n",
+ estate2s (t->estate), cstate2s (t->cstate));
+ return;
+ }
+
room = GMT_get_connections_buffer (t);
LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer space: %u\n", room);
for (tq = t->tq_head; NULL != tq && room > 0; tq = next)
@@ -606,7 +663,9 @@
struct MeshTunnelDelayed *tq;
uint16_t size = ntohs (msg->size);
- if (MESH_TUNNEL3_READY == t->state)
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "queue data on Tunnel %s\n", GMT_2s (t));
+
+ if (GNUNET_YES == is_ready (t))
{
GNUNET_break (0);
return;
@@ -696,7 +755,7 @@
{
LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __FUNCTION__);
- kx_msg.sender_status = htonl (t->state);
+ kx_msg.sender_status = htonl (t->estate);
send_kx (t, &kx_msg.header);
}
@@ -777,19 +836,21 @@
t->kx_ctx->d_key_old = t->d_key;
}
send_ephemeral (t);
- if (MESH_TUNNEL3_READY == t->state || MESH_TUNNEL3_REKEY == t->state)
+ switch (t->estate)
{
- send_ping (t);
- t->state = MESH_TUNNEL3_REKEY;
+ case MESH_TUNNEL3_KEY_UNINITIALIZED:
+ t->estate = MESH_TUNNEL3_KEY_SENT;
+ break;
+ case MESH_TUNNEL3_KEY_SENT:
+ break;
+ case MESH_TUNNEL3_KEY_PING:
+ case MESH_TUNNEL3_KEY_OK:
+ send_ping (t);
+ t->estate = MESH_TUNNEL3_KEY_PING;
+ break;
+ default:
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Unexpected state %u\n", t->estate);
}
- else if (MESH_TUNNEL3_WAITING == t->state)
- {
- t->state = MESH_TUNNEL3_KEY_SENT;
- }
- else
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Unexpected state %u\n", t->state);
- }
LOG (GNUNET_ERROR_TYPE_DEBUG, " next call in %s\n",
GNUNET_STRINGS_relative_time_to_string (REKEY_WAIT, GNUNET_YES));
@@ -932,7 +993,7 @@
return;
}
- GMT_change_state (t, MESH_TUNNEL3_READY);
+ GMT_change_cstate (t, MESH_TUNNEL3_READY);
GMCH_handle_data (ch, msg, fwd);
}
@@ -1154,11 +1215,11 @@
LOG (GNUNET_ERROR_TYPE_DEBUG, " km is %s\n", GNUNET_h2s (&km));
derive_symmertic (&t->e_key, &my_full_id, GMP_get_id (t->peer), &km);
derive_symmertic (&t->d_key, GMP_get_id (t->peer), &my_full_id, &km);
- if (MESH_TUNNEL3_KEY_SENT == t->state)
+ if (MESH_TUNNEL3_KEY_SENT == t->estate)
{
LOG (GNUNET_ERROR_TYPE_DEBUG, " our key was sent, send ping\n");
send_ping (t);
- t->state = MESH_TUNNEL3_REKEY;
+ t->estate = MESH_TUNNEL3_KEY_PING;
}
}
@@ -1232,8 +1293,7 @@
t->rekey_task = GNUNET_SCHEDULER_NO_TASK;
GNUNET_free (t->kx_ctx);
t->kx_ctx = NULL;
- t->state = MESH_TUNNEL3_READY;
- send_queued_data (t);
+ GMT_change_estate (t, MESH_TUNNEL3_KEY_OK);
}
@@ -1450,45 +1510,66 @@
/**
- * Change the tunnel state.
+ * Change the tunnel's connection state.
*
- * @param t Tunnel whose state to change.
- * @param state New state.
+ * @param t Tunnel whose connection state to change.
+ * @param cstate New connection state.
*/
void
-GMT_change_state (struct MeshTunnel3* t, enum MeshTunnel3State state)
+GMT_change_cstate (struct MeshTunnel3* t, enum MeshTunnel3CState state)
{
if (NULL == t)
return;
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Tunnel %s state was %s\n",
- GMP_2s (t->peer),
- GMT_state2s (t->state));
+ "Tunnel %s cstate was %s\n",
+ GMP_2s (t->peer), cstate2s (t->cstate));
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Tunnel %s state is now %s\n",
- GMP_2s (t->peer),
- GMT_state2s (state));
+ "Tunnel %s cstate is now %s\n",
+ GMP_2s (t->peer), cstate2s (state));
if (myid != GMP_get_short_id (t->peer) &&
- MESH_TUNNEL3_WAITING == t->state && MESH_TUNNEL3_READY == state)
+ MESH_TUNNEL3_READY != t->cstate &&
+ MESH_TUNNEL3_READY == state &&
+ MESH_TUNNEL3_KEY_UNINITIALIZED == t->estate)
{
LOG (GNUNET_ERROR_TYPE_DEBUG, " triggered rekey\n");
rekey_tunnel (t, NULL);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Tunnel %s state is now %s\n",
- GMP_2s (t->peer),
- GMT_state2s (t->state));
}
- else
- {
- t->state = state;
- }
+ t->cstate = state;
+
if (MESH_TUNNEL3_READY == state && 3 <= GMT_count_connections (t))
{
GMP_stop_search (t->peer);
}
}
+/**
+ * Change the tunnel encryption state.
+ *
+ * @param t Tunnel whose encryption state to change.
+ * @param state New encryption state.
+ */
+void
+GMT_change_estate (struct MeshTunnel3* t, enum MeshTunnel3EState state)
+{
+ if (NULL == t)
+ return;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Tunnel %s estate was %s\n",
+ GMP_2s (t->peer), estate2s (t->estate));
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Tunnel %s estate is now %s\n",
+ GMP_2s (t->peer), estate2s (state));
+ if (myid != GMP_get_short_id (t->peer) &&
+ MESH_TUNNEL3_KEY_OK != t->estate && MESH_TUNNEL3_KEY_OK == state)
+ {
+ t->estate = state;
+ send_queued_data (t);
+ return;
+ }
+ t->estate = state;
+}
+
/**
* Add a connection to a tunnel.
*
@@ -1781,21 +1862,21 @@
/**
- * Get the state of a tunnel.
+ * Get the connectivity state of a tunnel.
*
* @param t Tunnel.
*
- * @return Tunnel's state.
+ * @return Tunnel's connectivity state.
*/
-enum MeshTunnel3State
-GMT_get_state (struct MeshTunnel3 *t)
+enum MeshTunnel3CState
+GMT_get_cstate (struct MeshTunnel3 *t)
{
if (NULL == t)
{
GNUNET_break (0);
- return (enum MeshTunnel3State) -1;
+ return (enum MeshTunnel3CState) -1;
}
- return t->state;
+ return t->cstate;
}
@@ -2050,6 +2131,7 @@
/* message_sent() will be called and free q */
}
+
/**
* Sends an already built message on a tunnel, encrypting it and
* choosing the best connection.
@@ -2078,13 +2160,14 @@
uint32_t iv;
uint16_t type;
- if (MESH_TUNNEL3_READY != t->state)
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT Send on Tunnel %s\n", GMT_2s (t));
+
+ if (GNUNET_NO == is_ready (t))
{
queue_data (t, ch, message);
/* FIXME */
return NULL;
}
- LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT Send on Tunnel %s\n", GMT_2s (t));
if (GMT_is_loopback (t))
{
Modified: gnunet/src/mesh/gnunet-service-mesh_tunnel.h
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh_tunnel.h 2013-11-27 01:59:58 UTC
(rev 30888)
+++ gnunet/src/mesh/gnunet-service-mesh_tunnel.h 2013-11-27 04:19:13 UTC
(rev 30889)
@@ -41,9 +41,9 @@
#include "gnunet_util_lib.h"
/**
- * All the states a tunnel can be in.
+ * All the connectivity states a tunnel can be in.
*/
-enum MeshTunnel3State
+enum MeshTunnel3CState
{
/**
* Uninitialized status, should never appear in operation.
@@ -61,26 +61,38 @@
MESH_TUNNEL3_WAITING,
/**
- * Ephemeral key sent, waiting for peer's key.
- */
- MESH_TUNNEL3_KEY_SENT,
-
- /**
* Peer connected and ready to accept data.
*/
MESH_TUNNEL3_READY,
+};
- /**
- * Peer connected previosly but not responding.
- */
- MESH_TUNNEL3_RECONNECTING,
- /**
- * New ephemeral key and ping sent, waiting for pong.
- * This means that we DO have the peer's ephemeral key, otherwise the
- * state would be KEY_SENT.
- */
- MESH_TUNNEL3_REKEY,
+/**
+ * All the encryption states a tunnel can be in.
+ */
+enum MeshTunnel3EState
+{
+ /**
+ * Uninitialized status, should never appear in operation.
+ */
+ MESH_TUNNEL3_KEY_UNINITIALIZED,
+
+ /**
+ * Ephemeral key sent, waiting for peer's key.
+ */
+ MESH_TUNNEL3_KEY_SENT,
+
+ /**
+ * New ephemeral key and ping sent, waiting for pong.
+ * This means that we DO have the peer's ephemeral key, otherwise the
+ * state would be KEY_SENT.
+ */
+ MESH_TUNNEL3_KEY_PING,
+
+ /**
+ * Handshake completed: session key available.
+ */
+ MESH_TUNNEL3_KEY_OK,
};
/**
@@ -172,16 +184,27 @@
void
GMT_destroy (struct MeshTunnel3 *t);
+
/**
- * Change the tunnel state.
+ * Change the tunnel's connection state.
*
- * @param t Tunnel whose state to change.
- * @param state New state.
+ * @param t Tunnel whose connection state to change.
+ * @param cstate New connection state.
*/
void
-GMT_change_state (struct MeshTunnel3* t, enum MeshTunnel3State state);
+GMT_change_cstate (struct MeshTunnel3* t, enum MeshTunnel3CState state);
+
/**
+ * Change the tunnel encryption state.
+ *
+ * @param t Tunnel whose encryption state to change.
+ * @param state New encryption state.
+ */
+void
+GMT_change_estate (struct MeshTunnel3* t, enum MeshTunnel3EState state);
+
+/**
* Add a connection to a tunnel.
*
* @param t Tunnel.
@@ -284,14 +307,14 @@
GMT_count_channels (struct MeshTunnel3 *t);
/**
- * Get the state of a tunnel.
+ * Get the connectivity state of a tunnel.
*
* @param t Tunnel.
*
- * @return Tunnel's state.
+ * @return Tunnel's connectivity state.
*/
-enum MeshTunnel3State
-GMT_get_state (struct MeshTunnel3 *t);
+enum MeshTunnel3CState
+GMT_get_cstate (struct MeshTunnel3 *t);
/**
* Get the maximum buffer space for a tunnel towards a local client.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r30889 - gnunet/src/mesh,
gnunet <=