[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r23144 - gnunet/src/mesh
From: |
gnunet |
Subject: |
[GNUnet-SVN] r23144 - gnunet/src/mesh |
Date: |
Tue, 7 Aug 2012 01:43:59 +0200 |
Author: bartpolot
Date: 2012-08-07 01:43:59 +0200 (Tue, 07 Aug 2012)
New Revision: 23144
Modified:
gnunet/src/mesh/gnunet-service-mesh.c
Log:
- fixes, refactoring
Modified: gnunet/src/mesh/gnunet-service-mesh.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh.c 2012-08-06 17:03:05 UTC (rev
23143)
+++ gnunet/src/mesh/gnunet-service-mesh.c 2012-08-06 23:43:59 UTC (rev
23144)
@@ -287,25 +287,48 @@
MESH_TunnelNumber local_tid_dest;
/**
- * Local count ID of the last packet seen/sent.
+ * Is the speed on the tunnel limited to the slowest peer?
*/
- uint32_t pid;
+ int speed_min;
/**
+ * Is the tunnel bufferless (minimum latency)?
+ */
+ int nobuffer;
+
+ /**
+ * Packet ID of the last fwd packet seen (sent/retransmitted/received).
+ */
+ uint32_t fwd_pid;
+
+ /**
+ * Packet ID of the last bck packet sent (unique counter per hop).
+ */
+ uint32_t bck_pid;
+
+ /**
* SKIP value for this tunnel.
*/
uint32_t skip;
/**
* MeshTunnelChildInfo of all children, indexed by GNUNET_PEER_Id.
+ * Contains the Flow Control info: FWD ACK value received,
+ * last BCK ACK sent, PID and SKIP values.
*/
struct GNUNET_CONTAINER_MultiHashMap *children_fc;
/**
- * Last ACK sent towards the origin.
+ * Last ACK sent towards the origin (for traffic towards leaf node).
*/
- uint32_t last_ack;
+ uint32_t last_fwd_ack;
+ /**
+ * BCK ACK value received from the hop towards the owner of the tunnel,
+ * (previous node / owner): up to what message PID can we sent back to him.
+ */
+ uint32_t bck_ack;
+
/**
* How many messages are in the queue.
*/
@@ -317,23 +340,6 @@
unsigned int queue_max;
/**
- * Is the speed on the tunnel limited to the slowest peer?
- */
- int speed_min;
-
- /**
- * Is the tunnel bufferless (minimum latency)?
- */
- int nobuffer;
-
- /**
- * Flag to signal the destruction of the tunnel.
- * If this is set GNUNET_YES the tunnel will be destroyed
- * when the queue is empty.
- */
- int destroy;
-
- /**
* Last time the tunnel was used
*/
struct GNUNET_TIME_Absolute timestamp;
@@ -370,12 +376,6 @@
*/
uint32_t *clients_acks;
- /**
- * BCK ACK value of the root client, owner of the tunnel,
- * up to what message PID can we sent him.
- */
- uint32_t root_client_ack;
-
/**
* Number of elements in clients/clients_acks
*/
@@ -426,18 +426,25 @@
*/
struct MeshRegexSearchContext *regex_ctx;
- /**
- * Task to keep the used paths alive
- */
+ /**
+ * Task to keep the used paths alive
+ */
GNUNET_SCHEDULER_TaskIdentifier path_refresh_task;
- /**
- * Task to destroy the tunnel after timeout
- *
- * FIXME: merge the two? a tunnel will have either
- * a path refresh OR a timeout, never both!
- */
+ /**
+ * Task to destroy the tunnel after timeout
+ *
+ * FIXME: merge the two? a tunnel will have either
+ * a path refresh OR a timeout, never both!
+ */
GNUNET_SCHEDULER_TaskIdentifier timeout_task;
+
+ /**
+ * Flag to signal the destruction of the tunnel.
+ * If this is set GNUNET_YES the tunnel will be destroyed
+ * when the queue is empty.
+ */
+ int destroy;
};
@@ -1658,7 +1665,7 @@
* @param bigger Argument that should be bigger.
* @param smaller Argument that should be smaller.
*
- * @return True if big is bigger than small
+ * @return True if bigger (arg1) has a higher value than smaller (arg 2).
*/
static int
is_pid_bigger (uint32_t bigger, uint32_t smaller)
@@ -2072,11 +2079,11 @@
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ack);
- if (t->last_ack == ack)
+ if (t->last_fwd_ack == ack)
return;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending!\n");
- t->last_ack = ack;
+ t->last_fwd_ack = ack;
msg.header.size = htons (sizeof (msg));
msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
msg.tunnel_id = htonl (tid);
@@ -3330,7 +3337,44 @@
}
+/**
+ * @brief Get neighbor's Flow Control information.
+ *
+ * Retrieves the MeshTunnelChildInfo containing Flow Control data about a
direct
+ * descendant of the local node in a certain tunnel.
+ * If the info is not yet there (recently created path), creates the data
struct
+ * and inserts it into the tunnel info, initialized to the current tunnel ACK
+ * values.
+ *
+ * @param t Tunnel related.
+ * @param peer Neighbor whose Flow Control info is needed.
+ *
+ * @return Neighbor's Flow Control info.
+ */
+static struct MeshTunnelChildInfo *
+tunnel_get_neighbor_fc (const struct MeshTunnel *t,
+ const struct GNUNET_PeerIdentity *peer)
+{
+ struct MeshTunnelChildInfo *cinfo;
+ cinfo = GNUNET_CONTAINER_multihashmap_get (t->children_fc,
+ &peer->hashPubKey);
+ if (NULL == cinfo)
+ {
+ cinfo = GNUNET_malloc (sizeof (struct MeshTunnelChildInfo));
+ cinfo->id = GNUNET_PEER_intern (peer);
+ cinfo->skip = t->fwd_pid;
+ cinfo->max_pid = t->fwd_pid + t->queue_max - t->queue_n; // FIXME review
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CONTAINER_multihashmap_put (t->children_fc,
+ &peer->hashPubKey,
+ cinfo,
+
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
+ }
+ return cinfo;
+}
+
+
/**
* Iterator to get the appropiate ACK value from all children nodes.
*
@@ -3348,25 +3392,8 @@
uint32_t ack;
GNUNET_PEER_resolve (id, &peer_id);
- cinfo = GNUNET_CONTAINER_multihashmap_get (t->children_fc,
- &peer_id.hashPubKey);
- if (NULL == cinfo)
- {
- cinfo = GNUNET_malloc (sizeof (struct MeshTunnelChildInfo));
- cinfo->id = id;
- cinfo->pid = t->pid;
- cinfo->skip = t->pid;
- cinfo->max_pid = ack = t->pid + 1;
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CONTAINER_multihashmap_put(t->children_fc,
- &peer_id.hashPubKey,
- cinfo,
-
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
- }
- else
- {
- ack = cinfo->max_pid;
- }
+ cinfo = tunnel_get_neighbor_fc (t, &peer_id);
+ ack = cinfo->max_pid;
if (0 == ctx->max_child_ack)
ctx->max_child_ack = ack;
@@ -3421,7 +3448,7 @@
GNUNET_array_append (t->clients, t->nclients, c);
t->nclients--;
- ack = t->pid + 1;
+ ack = t->fwd_pid + 1;
GNUNET_array_append (t->clients_acks, t->nclients, ack);
}
@@ -3501,8 +3528,8 @@
}
}
- if (GNUNET_YES == t->nobuffer && ack > t->pid)
- ack = t->pid + 1;
+ if (GNUNET_YES == t->nobuffer && ack > t->fwd_pid)
+ ack = t->fwd_pid + 1;
return (uint32_t) ack;
}
@@ -3525,7 +3552,7 @@
int64_t client_ack;
uint32_t ack;
- count = t->pid - t->skip;
+ count = t->fwd_pid - t->skip;
buffer_free = t->queue_max - t->queue_n;
ack = count + buffer_free; // Might overflow 32bits, it's ok!
child_ack = tunnel_get_children_ack (t);
@@ -3614,13 +3641,13 @@
ack = tunnel_get_fwd_ack (t);
/* If speed_min and not all children have ack'd, dont send yet */
- if (ack == t->last_ack)
+ if (ack == t->last_fwd_ack)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, not ready\n");
return;
}
- t->last_ack = ack;
+ t->last_fwd_ack = ack;
msg.pid = htonl (ack);
GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &id);
@@ -3676,13 +3703,13 @@
ack = tunnel_get_bck_ack (t);
/* If speed_min and not all children have ack'd, dont send yet */
- if (ack == t->last_ack)
+ if (ack == t->last_fwd_ack)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, not ready\n");
return;
}
- t->last_ack = ack;
+ t->last_fwd_ack = ack;
msg.pid = htonl (ack);
GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &id);
@@ -3878,7 +3905,7 @@
t->queue_max = (max_msgs_queue / max_tunnels) + 1;
t->tree = tree_new (owner);
t->owner = client;
- t->root_client_ack = 1;
+ t->bck_ack = 1;
t->local_tid = local;
t->children_fc = GNUNET_CONTAINER_multihashmap_create (8);
n_tunnels++;
@@ -4763,6 +4790,7 @@
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a unicast packet from %s\n",
GNUNET_i2s (peer));
+ /* Check size */
size = ntohs (message->size);
if (size <
sizeof (struct GNUNET_MESH_Unicast) +
@@ -4774,6 +4802,7 @@
msg = (struct GNUNET_MESH_Unicast *) message;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " of type %u\n",
ntohs (msg[1].header.type));
+ /* Check tunnel */
t = tunnel_get (&msg->oid, ntohl (msg->tid));
if (NULL == t)
{
@@ -4783,9 +4812,9 @@
return GNUNET_OK;
}
pid = ntohl (msg->pid);
- if (t->pid == pid)
+ if (t->fwd_pid == pid)
{
- GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
+ GNUNET_STATISTICS_update (stats, "# PID drops", 1, GNUNET_NO);
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
" Already seen pid %u, DROPPING!\n", pid);
return GNUNET_OK;
@@ -4795,9 +4824,16 @@
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" pid %u not seen yet, forwarding\n", pid);
}
- t->skip += (pid - t->pid) - 1;
- t->pid = pid;
+ t->skip += (pid - t->fwd_pid) - 1;
+ t->fwd_pid = pid;
tunnel_reset_timeout (t);
+ if (is_pid_bigger (pid, t->last_fwd_ack))
+ {
+ GNUNET_STATISTICS_update (stats, "# not allowed unicast", 1, GNUNET_NO);
+ GNUNET_break_op (0);
+ return GNUNET_OK;
+ // FIXME peer sent unauthorized data. Break connection? Accept anyway?
+ }
dest_id = GNUNET_PEER_search (&msg->destination);
if (dest_id == myid)
{
@@ -4805,8 +4841,7 @@
" it's for us! sending to clients...\n");
GNUNET_STATISTICS_update (stats, "# unicast received", 1, GNUNET_NO);
send_subscribed_clients (message, (struct GNUNET_MessageHeader *) &msg[1]);
- // FIXME send after client processes the packet
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
+ // ACK sent by client, service retransmits.
return GNUNET_OK;
}
ttl = ntohl (msg->ttl);
@@ -4822,25 +4857,16 @@
GNUNET_STATISTICS_update (stats, "# unicast forwarded", 1, GNUNET_NO);
neighbor = tree_get_first_hop (t->tree, dest_id);
- cinfo = GNUNET_CONTAINER_multihashmap_get (t->children_fc,
- &neighbor->hashPubKey);
- if (NULL == cinfo)
- {
- cinfo = GNUNET_malloc (sizeof (struct MeshTunnelChildInfo));
- cinfo->id = GNUNET_PEER_intern (neighbor);
- cinfo->skip = pid;
- cinfo->max_pid = pid + t->queue_max - t->queue_n; // FIXME review
-
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CONTAINER_multihashmap_put (t->children_fc,
- &neighbor->hashPubKey,
- cinfo,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
- }
+ cinfo = tunnel_get_neighbor_fc (t, neighbor);
cinfo->pid = pid;
GNUNET_CONTAINER_multihashmap_iterate (t->children_fc,
&tunnel_add_skip,
&neighbor);
+ if (is_pid_bigger(pid, cinfo->max_pid))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_OK;
+ }
send_message (message, neighbor, t);
return GNUNET_OK;
}
@@ -4890,7 +4916,7 @@
return GNUNET_OK;
}
pid = ntohl (msg->pid);
- if (t->pid == pid)
+ if (t->fwd_pid == pid)
{
/* already seen this packet, drop */
GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
@@ -4903,8 +4929,8 @@
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" pid %u not seen yet, forwarding\n", pid);
}
- t->skip += (pid - t->pid) - 1;
- t->pid = pid;
+ t->skip += (pid - t->fwd_pid) - 1;
+ t->fwd_pid = pid;
tunnel_reset_timeout (t);
/* Transmit to locally interested clients */
@@ -5054,13 +5080,7 @@
return GNUNET_OK;
}
ack = ntohl (msg->pid);
- cinfo = GNUNET_CONTAINER_multihashmap_get (t->children_fc,
- &peer->hashPubKey);
- if (NULL == cinfo)
- {
- GNUNET_break_op (0);
- return GNUNET_OK;
- }
+ cinfo = tunnel_get_neighbor_fc (t, peer);
cinfo->max_pid = ack;
tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
return GNUNET_OK;
@@ -5287,8 +5307,8 @@
msg->oid = my_full_id;
msg->tid = htonl (t->id.tid);
msg->ttl = htonl (default_ttl);
- msg->pid = htonl (t->pid + 1);
- t->pid++;
+ msg->pid = htonl (t->fwd_pid + 1);
+ t->fwd_pid++;
payload = (struct GNUNET_MessageHeader *) &msg[1];
payload->size = htons (sizeof (struct GNUNET_MessageHeader));
payload->type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE);
@@ -5781,6 +5801,7 @@
struct GNUNET_MESH_TunnelMessage *t_msg;
struct MeshTunnel *t;
struct MeshClient *c;
+ MESH_TunnelNumber tid;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new tunnel requested\n");
@@ -5803,14 +5824,15 @@
t_msg = (struct GNUNET_MESH_TunnelMessage *) message;
/* Sanity check for tunnel numbering */
- if (0 == (ntohl (t_msg->tunnel_id) & GNUNET_MESH_LOCAL_TUNNEL_ID_CLI))
+ tid = ntohl (t_msg->tunnel_id);
+ if (0 == (tid & GNUNET_MESH_LOCAL_TUNNEL_ID_CLI))
{
GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
/* Sanity check for duplicate tunnel IDs */
- if (NULL != tunnel_get_by_local_id (c, ntohl (t_msg->tunnel_id)))
+ if (NULL != tunnel_get_by_local_id (c, tid))
{
GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
@@ -5819,7 +5841,7 @@
while (NULL != tunnel_get_by_pi (myid, next_tid))
next_tid = (next_tid + 1) & ~GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
- t = tunnel_new (myid, next_tid++, c, ntohl (t_msg->tunnel_id));
+ t = tunnel_new (myid, next_tid++, c, tid);
if (NULL == t)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Tunnel creation failed.\n");
@@ -6598,7 +6620,7 @@
copy->oid = my_full_id;
copy->tid = htonl (t->id.tid);
copy->ttl = htonl (default_ttl);
- copy->pid = htonl (t->pid + 1);
+ copy->pid = htonl (t->fwd_pid + 1);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" calling generic handler...\n");
handle_mesh_data_unicast (NULL, &my_full_id, ©->header, NULL, 0);
@@ -6757,7 +6779,7 @@
copy->oid = my_full_id;
copy->tid = htonl (t->id.tid);
copy->ttl = htonl (default_ttl);
- copy->pid = htonl (t->pid + 1);
+ copy->pid = htonl (t->fwd_pid + 1);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" calling generic handler...\n");
handle_mesh_data_multicast (client, &my_full_id, ©->header, NULL, 0);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r23144 - gnunet/src/mesh,
gnunet <=