[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r28057 - gnunet/src/mesh
From: |
gnunet |
Subject: |
[GNUnet-SVN] r28057 - gnunet/src/mesh |
Date: |
Mon, 15 Jul 2013 21:05:28 +0200 |
Author: bartpolot
Date: 2013-07-15 21:05:28 +0200 (Mon, 15 Jul 2013)
New Revision: 28057
Modified:
gnunet/src/mesh/gnunet-service-mesh.c
Log:
Refactored code to eliminate duplicates depending on FWD/BCK traffic
Modified: gnunet/src/mesh/gnunet-service-mesh.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh.c 2013-07-15 17:54:23 UTC (rev
28056)
+++ gnunet/src/mesh/gnunet-service-mesh.c 2013-07-15 19:05:28 UTC (rev
28057)
@@ -25,7 +25,6 @@
*
* FIXME in progress:
* - when sending in-order buffered data, wait for client ACKs
- * - refactor unicast to make generic handling, assigning *rel and *fc
*
* TODO:
* - relay corking down to core
@@ -581,10 +580,6 @@
}
#endif
-/* FIXME */
-unsigned int debug_fwd_ack;
-unsigned int debug_bck_ack;
-
#endif
/******************************************************************************/
@@ -2097,35 +2092,39 @@
* Send an end-to-end FWD ACK message for the most recent in-sequence payload.
*
* @param t Tunnel this is about.
+ * @param fwd Is for FWD traffic? (ACK dest->owner)
*/
static void
-tunnel_send_fwd_data_ack (struct MeshTunnel *t)
+tunnel_send_data_ack (struct MeshTunnel *t, int fwd)
{
struct GNUNET_MESH_DataACK msg;
struct MeshTunnelReliability *rel;
struct MeshReliableMessage *copy;
+ GNUNET_PEER_Id hop;
uint64_t mask;
unsigned int delta;
+ rel = fwd ? t->bck_rel : t->fwd_rel;
+ hop = fwd ? t->prev_hop : t->next_hop;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "send_fwd_data_ack for %llu\n",
- t->bck_rel->mid_recv - 1);
+ "send_data_ack for %llu\n",
+ rel->mid_recv - 1);
if (GNUNET_NO == t->reliable)
{
GNUNET_break_op (0);
return;
}
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK);
+ msg.header.type = htons (fwd ? GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK :
+ GNUNET_MESSAGE_TYPE_MESH_TO_ORIG_ACK);
msg.header.size = htons (sizeof (msg));
msg.tid = htonl (t->id.tid);
GNUNET_PEER_resolve (t->id.oid, &msg.oid);
- msg.mid = GNUNET_htonll (t->bck_rel->mid_recv - 1);
+ msg.mid = GNUNET_htonll (rel->mid_recv - 1);
msg.futures = 0;
- rel = t->bck_rel;
for (copy = rel->head_recv; NULL != copy; copy = copy->next)
{
- delta = copy->mid - t->bck_rel->mid_recv;
+ delta = copy->mid - rel->mid_recv;
if (63 < delta)
break;
mask = 0x1LL << delta;
@@ -2136,33 +2135,12 @@
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " final futures %llX\n", msg.futures);
- send_prebuilt_message (&msg.header, t->prev_hop, t);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "send_fwd_data_ack END\n");
+ send_prebuilt_message (&msg.header, hop, t);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "send_data_ack END\n");
}
/**
- * Send an end-to-end BCK ACK message for the most recent in-sequence payload.
- *
- * @param t Tunnel this is about.
- */
-static void
-tunnel_send_bck_data_ack (struct MeshTunnel *t)
-{
- struct GNUNET_MESH_DataACK msg;
-
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TO_ORIG_ACK);
- msg.header.size = htons (sizeof (msg));
- msg.tid = htonl (t->id.tid);
- GNUNET_PEER_resolve (t->id.oid, &msg.oid);
- msg.mid = GNUNET_htonll (t->fwd_rel->mid_recv - 1);
- msg.futures = 0; // FIXME set bits of other newer messages received
-
- send_prebuilt_message (&msg.header, t->next_hop, t);
-}
-
-
-/**
* Send an ACK informing the predecessor about the available buffer space.
* In case there is no predecessor, inform the owning client.
* If buffering is off, send only on behalf of children or self if endpoint.
@@ -2172,28 +2150,42 @@
*
* @param t Tunnel on which to send the ACK.
* @param type Type of message that triggered the ACK transmission.
+ * @param fwd Is this FWD ACK? (Going dest->owner)
*/
static void
-tunnel_send_fwd_ack (struct MeshTunnel *t, uint16_t type)
+tunnel_send_ack (struct MeshTunnel *t, uint16_t type, int fwd)
{
- struct MeshTunnelReliability *rel = t->fwd_rel;
+ struct MeshTunnelReliability *rel;
+ struct MeshFlowControl *next_fc;
+ struct MeshFlowControl *prev_fc;
+ struct MeshClient *c;
+ struct MeshClient *o;
+ GNUNET_PEER_Id hop;
uint64_t delta_mid;
uint32_t ack;
int delta;
+ rel = fwd ? t->fwd_rel : t->bck_rel;
+ c = fwd ? t->client : t->owner;
+ o = fwd ? t->owner : t->client;
+ next_fc = fwd ? &t->next_fc : &t->prev_fc;
+ prev_fc = fwd ? &t->prev_fc : &t->next_fc;
+ hop = fwd ? t->prev_hop : t->next_hop;
+
/* Is it after unicast retransmission? */
switch (type)
{
case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
+ case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "ACK due to FWD DATA retransmission\n");
+ "ACK due to DATA retransmission\n");
if (GNUNET_YES == t->nobuffer)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, nobuffer\n");
return;
}
- if (GNUNET_YES == t->reliable && NULL != t->client)
- tunnel_send_fwd_data_ack (t);
+ if (GNUNET_YES == t->reliable && NULL != c)
+ tunnel_send_data_ack (t, fwd);
break;
case GNUNET_MESSAGE_TYPE_MESH_ACK:
case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
@@ -2208,126 +2200,58 @@
}
/* Check if we need to transmit the ACK */
- if (0 && NULL == t->owner &&
- t->queue_max > t->next_fc.queue_n * 4 &&
- GMC_is_pid_bigger(t->prev_fc.last_ack_sent, t->prev_fc.last_pid_recv) &&
+ /* FIXME unlock */
+ if (0 && NULL == o &&
+ t->queue_max > next_fc->queue_n * 4 &&
+ GMC_is_pid_bigger (prev_fc->last_ack_sent, prev_fc->last_pid_recv) &&
GNUNET_NO == t->force_ack)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending FWD ACK, buffer free\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, buffer free\n");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" t->qmax: %u, t->qn: %u\n",
- t->queue_max, t->next_fc.queue_n);
+ t->queue_max, next_fc->queue_n);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" t->pid: %u, t->ack: %u\n",
- t->prev_fc.last_pid_recv, t->prev_fc.last_ack_sent);
+ prev_fc->last_pid_recv, prev_fc->last_ack_sent);
return;
}
/* Ok, ACK might be necessary, what PID to ACK? */
- delta = t->queue_max - t->next_fc.queue_n;
- if (NULL != t->owner && GNUNET_YES == t->reliable && NULL != rel->head_sent)
+ delta = t->queue_max - next_fc->queue_n;
+ if (NULL != o && GNUNET_YES == t->reliable && NULL != rel->head_sent)
delta_mid = rel->mid_sent - rel->head_sent->mid;
else
delta_mid = 0;
if (0 > delta || (GNUNET_YES == t->reliable &&
- NULL != t->owner &&
+ NULL != o &&
(rel->n_sent > 10 || delta_mid > 64)))
delta = 0;
- if (NULL != t->owner && delta > 1)
+ if (NULL != o && delta > 1)
delta = 1;
- ack = t->prev_fc.last_pid_recv + delta;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " FWD ACK %u\n", ack);
+ ack = prev_fc->last_pid_recv + delta;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ACK %u\n", ack);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" last pid %u, last ack %u, qmax %u, q %u\n",
- t->prev_fc.last_pid_recv, t->prev_fc.last_ack_sent,
- t->queue_max, t->next_fc.queue_n);
- if (ack == t->prev_fc.last_ack_sent && GNUNET_NO == t->force_ack)
+ prev_fc->last_pid_recv, prev_fc->last_ack_sent,
+ t->queue_max, next_fc->queue_n);
+ if (ack == prev_fc->last_ack_sent && GNUNET_NO == t->force_ack)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending FWD ACK, not needed\n");
return;
}
- t->prev_fc.last_ack_sent = ack;
- if (NULL != t->owner)
- send_local_ack (t, t->owner, GNUNET_YES);
- else if (0 != t->prev_hop)
- send_ack (t, t->prev_hop, ack);
+ prev_fc->last_ack_sent = ack;
+ if (NULL != o)
+ send_local_ack (t, o, fwd);
+ else if (0 != hop)
+ send_ack (t, hop, ack);
else
GNUNET_break (0);
- debug_fwd_ack++;
t->force_ack = GNUNET_NO;
}
/**
- * Send an ACK informing the children node/client about the available
- * buffer space.
- * If buffering is off, send only on behalf of root (can be self).
- * If buffering is on, send when sent to predecessor and buffer space is free.
- * Note that although the name is bck_ack, the BCK mean backwards *traffic*,
- * the ACK itself goes "forward" (towards children/clients).
- *
- * @param t Tunnel on which to send the ACK.
- * @param type Type of message that triggered the ACK transmission.
- */
-static void
-tunnel_send_bck_ack (struct MeshTunnel *t, uint16_t type)
-{
- uint32_t ack;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending BCK ACK on tunnel %u [%u] due to %s\n",
- t->id.oid, t->id.tid, GNUNET_MESH_DEBUG_M2S(type));
- /* Is it after data to_origin retransmission? */
- switch (type)
- {
- case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
- if (GNUNET_YES == t->nobuffer)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " Not sending ACK, nobuffer + traffic\n");
- return;
- }
- if (GNUNET_YES == t->reliable && NULL != t->owner)
- tunnel_send_bck_data_ack (t);
- break;
- case GNUNET_MESSAGE_TYPE_MESH_ACK:
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
- break;
- case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
- case GNUNET_MESSAGE_TYPE_MESH_POLL:
- t->force_ack = GNUNET_YES;
- break;
- default:
- GNUNET_break (0);
- }
-
- /* TODO: Check if we need to transmit the ACK (as in fwd) */
-
- ack = t->next_fc.last_pid_recv + t->queue_max - t->prev_fc.queue_n;
-
- if (t->next_fc.last_ack_sent == ack && GNUNET_NO == t->force_ack)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " Not sending ACK, not needed, last ack sent was %u\n",
- t->next_fc.last_ack_sent);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " Sending BCK ACK %u (last sent: %u)\n",
- ack, t->next_fc.last_ack_sent);
- t->next_fc.last_ack_sent = ack;
-
- if (NULL != t->client)
- send_local_ack (t, t->client, GNUNET_NO);
- else if (0 != t->next_hop)
- send_ack (t, t->next_hop, ack);
- else
- GNUNET_break (0);
- t->force_ack = GNUNET_NO;
-}
-
-
-/**
* Modify the mesh message TID from global to local and send to client.
*
* @param t Tunnel on which to send the message.
@@ -2336,9 +2260,9 @@
* @param tid Tunnel ID to use (c can be both owner and client).
*/
static void
-tunnel_send_client_data (struct MeshTunnel *t,
- const struct GNUNET_MESH_Data *msg,
- struct MeshClient *c, MESH_TunnelNumber tid)
+tunnel_send_client_to_tid (struct MeshTunnel *t,
+ const struct GNUNET_MESH_Data *msg,
+ struct MeshClient *c, MESH_TunnelNumber tid)
{
struct GNUNET_MESH_LocalData *copy;
uint16_t size = ntohs (msg->header.size) - sizeof (struct GNUNET_MESH_Data);
@@ -2368,12 +2292,17 @@
*
* @param t Tunnel on which to send the message.
* @param msg Message to modify and send.
+ * @param fwd Forward?
*/
static void
-tunnel_send_client_ucast (struct MeshTunnel *t,
- const struct GNUNET_MESH_Data *msg)
+tunnel_send_client_data (struct MeshTunnel *t,
+ const struct GNUNET_MESH_Data *msg,
+ int fwd)
{
- tunnel_send_client_data (t, msg, t->client, t->local_tid_dest);
+ if (fwd)
+ tunnel_send_client_to_tid (t, msg, t->client, t->local_tid_dest);
+ else
+ tunnel_send_client_to_tid (t, msg, t->owner, t->local_tid);
}
@@ -2381,16 +2310,19 @@
* Send up to 64 buffered messages to the client for in order delivery.
*
* @param t Tunnel on which to empty the message buffer.
+ * @param c Client to send to.
+ * @param rel Reliability structure to corresponding peer.
+ * If rel == t->bck_rel, this is FWD data.
*/
static void
-tunnel_send_client_buffered_ucast (struct MeshTunnel *t)
+tunnel_send_client_buffered_data (struct MeshTunnel *t, struct MeshClient *c,
+ struct MeshTunnelReliability *rel)
{
- struct MeshTunnelReliability *rel;
+ ;
struct MeshReliableMessage *copy;
struct MeshReliableMessage *next;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_unicast\n");
- rel = t->bck_rel;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_data\n");
for (copy = rel->head_recv; NULL != copy; copy = next)
{
next = copy->next;
@@ -2401,7 +2333,7 @@
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" have %llu! now expecting %llu\n",
copy->mid, rel->mid_recv + 1LL);
- tunnel_send_client_ucast (t, msg);
+ tunnel_send_client_data (t, msg, (rel == t->bck_rel));
rel->mid_recv++;
GNUNET_CONTAINER_DLL_remove (rel->head_recv, rel->tail_recv, copy);
GNUNET_free (copy);
@@ -2409,34 +2341,37 @@
else
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " don't have %llu, (%llu)\n",
+ " don't have %llu, next is %llu\n",
rel->mid_recv,
copy->mid);
return;
}
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_unicast END\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_data END\n");
}
/**
* We have received a message out of order, buffer it until we receive
* the missing one and we can feed the rest to the client.
+ *
+ * @param t Tunnel to add to.
+ * @param msg Message to buffer.
+ * @param rel Reliability data to the corresponding direction.
*/
static void
-tunnel_add_buffer_ucast (struct MeshTunnel *t,
- const struct GNUNET_MESH_Data *msg)
+tunnel_add_buffered_data (struct MeshTunnel *t,
+ const struct GNUNET_MESH_Data *msg,
+ struct MeshTunnelReliability *rel)
{
- struct MeshTunnelReliability *rel;
struct MeshReliableMessage *copy;
struct MeshReliableMessage *prev;
uint64_t mid;
uint16_t size;
- rel = t->bck_rel;
size = ntohs (msg->header.size);
mid = GNUNET_ntohll (msg->mid);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "add_buffer_ucast %llu\n", mid);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "add_buffered_data %llu\n", mid);
copy = GNUNET_malloc (sizeof (*copy) + size);
copy->mid = mid;
@@ -2444,6 +2379,7 @@
memcpy (©[1], msg, size);
// FIXME do something better than O(n), although n < 64...
+ // FIXME start from the end (most messages are the latest ones)
for (prev = rel->head_recv; NULL != prev; prev = prev->next)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " prev %llu\n", prev->mid);
@@ -2457,7 +2393,7 @@
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " insert at tail!\n");
GNUNET_CONTAINER_DLL_insert_tail (rel->head_recv, rel->tail_recv, copy);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "add_buffer_ucast END\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "add_buffered_data END\n");
}
@@ -2498,12 +2434,13 @@
*
* @param t Tunnel whose sent buffer to clean.
* @param msg DataACK message with a bitfield of future ACK'd messages.
+ * @param rel Reliability data.
*/
static void
-tunnel_free_buffer_ucast (struct MeshTunnel *t,
- const struct GNUNET_MESH_DataACK *msg)
+tunnel_free_sent_reliable (struct MeshTunnel *t,
+ const struct GNUNET_MESH_DataACK *msg,
+ struct MeshTunnelReliability *rel)
{
- struct MeshTunnelReliability *rel;
struct MeshReliableMessage *copy;
struct MeshReliableMessage *next;
uint64_t bitfield;
@@ -2514,9 +2451,8 @@
bitfield = msg->futures;
mid = GNUNET_ntohll (msg->mid);
- rel = t->fwd_rel;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "free_sent_buffer %llu %llX\n",
+ "free_sent_reliable %llu %llX\n",
mid, bitfield);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" rel %p, head %p\n",
@@ -2562,25 +2498,11 @@
tunnel_free_reliable_message (copy);
copy = next;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "free_sent_buffer END\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "free_sent_reliable END\n");
}
/**
- * Modify the to_origin message TID from global to local and send to client.
- *
- * @param t Tunnel on which to send the message.
- * @param msg Message to modify and send.
- */
-static void
-tunnel_send_client_to_orig (struct MeshTunnel *t,
- const struct GNUNET_MESH_Data *msg)
-{
- tunnel_send_client_data (t, msg, t->owner, t->local_tid);
-}
-
-
-/**
* We haven't received an ACK after a certain time: restransmit the message.
*
* @param cls Closure (MeshReliableMessage with the message to restransmit)
@@ -2614,8 +2536,8 @@
/* Search the message to be retransmitted in the outgoing queue */
payload = (struct GNUNET_MESH_Data *) ©[1];
hop = rel == t->fwd_rel ? t->next_hop : t->prev_hop;
- fc = rel == t->fwd_rel ? &t->prev_fc : &t->next_fc;
- pi = peer_get_short (hop);
+ fc = rel == t->fwd_rel ? &t->prev_fc : &t->next_fc;
+ pi = peer_get_short (hop);
for (q = pi->queue_head; NULL != q; q = q->next)
{
if (ntohs (payload->header.type) == q->type)
@@ -3085,11 +3007,13 @@
* Resets the tunnel timeout. Starts it if no timeout was running.
*
* @param t Tunnel whose timeout to reset.
+ * @param fwd Is this forward?
*
* TODO use heap to improve efficiency of scheduler.
+ * FIXME use fwd, keep 2 timers
*/
static void
-tunnel_reset_timeout (struct MeshTunnel *t)
+tunnel_reset_timeout (struct MeshTunnel *t, int fwd)
{
if (NULL != t->owner || 0 != t->local_tid || 0 == t->prev_hop)
return;
@@ -3435,14 +3359,14 @@
{
case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
t->next_fc.last_pid_sent = pid;
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
+ tunnel_send_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST, GNUNET_YES);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"!!! SEND %llu\n",
GNUNET_ntohll ( ((struct GNUNET_MESH_Data *) buf)->mid ));
break;
case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
t->prev_fc.last_pid_sent = pid;
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
+ tunnel_send_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, GNUNET_NO);
break;
default:
break;
@@ -3683,7 +3607,7 @@
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " nobuffer:%d\n", t->nobuffer);
- tunnel_reset_timeout (t);
+ tunnel_reset_timeout (t, GNUNET_YES); // FIXME
}
t->state = MESH_TUNNEL_WAITING;
dest_peer_info =
@@ -3853,8 +3777,8 @@
GNUNET_DHT_get_stop (peer_info->dhtget);
peer_info->dhtget = NULL;
}
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK);
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK);
+ tunnel_send_ack (t, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK, GNUNET_YES);
+ tunnel_send_ack (t, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK, GNUNET_NO);
return GNUNET_OK;
}
@@ -3974,25 +3898,32 @@
/**
- * Core handler for mesh network traffic going from the origin to a peer
+ * Generic handler for mesh network payload traffic.
*
- * @param cls closure
- * @param peer peer identity this notification is about
- * @param message message
+ * @param peer Peer identity this notification is about.
+ * @param message Data message.
+ * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
+ *
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
-handle_mesh_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message)
+handle_mesh_data (const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_MessageHeader *message,
+ int fwd)
{
struct GNUNET_MESH_Data *msg;
+ struct MeshFlowControl *fc;
+ struct MeshTunnelReliability *rel;
struct MeshTunnel *t;
+ struct MeshClient *c;
+ GNUNET_PEER_Id hop;
uint32_t pid;
uint32_t ttl;
size_t size;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a unicast packet from %s\n",
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a %s message from %s\n",
+ GNUNET_MESH_DEBUG_M2S (ntohs (message->type)),
GNUNET_i2s (peer));
/* Check size */
size = ntohs (message->size);
@@ -4004,7 +3935,7 @@
return GNUNET_OK;
}
msg = (struct GNUNET_MESH_Data *) message;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " of type %s\n",
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " payload of type %s\n",
GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
/* Check tunnel */
t = tunnel_get (&msg->oid, ntohl (msg->tid));
@@ -4015,58 +3946,62 @@
GNUNET_break_op (0);
return GNUNET_OK;
}
+
+ /* Initialize FWD/BCK data */
pid = ntohl (msg->pid);
- if (GMC_is_pid_bigger (pid, t->prev_fc.last_ack_sent))
+ fc = fwd ? &t->prev_fc : &t->next_fc;
+ c = fwd ? t->client : t->owner;
+ rel = fwd ? t->bck_rel : t->fwd_rel;
+ hop = fwd ? t->next_hop : t->prev_hop;
+ if (GMC_is_pid_bigger (pid, fc->last_ack_sent))
{
- GNUNET_STATISTICS_update (stats, "# unsolicited unicast", 1, GNUNET_NO);
+ GNUNET_STATISTICS_update (stats, "# unsolicited data", 1, GNUNET_NO);
GNUNET_break_op (0);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received PID %u, (prev %u), ACK %u\n",
- pid, t->prev_fc.last_pid_recv, t->prev_fc.last_ack_sent);
+ pid, fc->last_pid_recv, fc->last_ack_sent);
return GNUNET_OK;
}
- tunnel_reset_timeout (t);
- if (t->dest == myid)
+ tunnel_reset_timeout (t, fwd);
+ if (NULL != c)
{
/* TODO signature verification */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " it's for us! sending to clients...\n");
- GNUNET_STATISTICS_update (stats, "# unicast received", 1, GNUNET_NO);
-// if (GMC_is_pid_bigger(pid, t->prev_fc.last_pid_recv)) FIXME use
- if (GMC_is_pid_bigger (pid, t->prev_fc.last_pid_recv))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " it's for us! sending to client\n");
+ GNUNET_STATISTICS_update (stats, "# data received", 1, GNUNET_NO);
+ if (GMC_is_pid_bigger (pid, fc->last_pid_recv))
{
uint64_t mid;
mid = GNUNET_ntohll (msg->mid);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" pid %u (%llu) not seen yet\n", pid, mid);
- t->prev_fc.last_pid_recv = pid;
+ fc->last_pid_recv = pid;
if (GNUNET_NO == t->reliable ||
- (mid >= t->bck_rel->mid_recv && mid <= t->bck_rel->mid_recv + 64))
+ (mid >= rel->mid_recv && mid <= rel->mid_recv + 64))
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "!!! RECV %llu\n", GNUNET_ntohll(msg->mid));
+ "!!! RECV %llu\n", GNUNET_ntohll (msg->mid));
if (GNUNET_YES == t->reliable)
{
/* Is this the exact next expected messasge? */
- if (mid == t->bck_rel->mid_recv)
+ if (mid == rel->mid_recv)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "as expected\n");
- t->bck_rel->mid_recv++;
- tunnel_send_client_ucast (t, msg);
- tunnel_send_client_buffered_ucast (t);
+ rel->mid_recv++;
+ tunnel_send_client_data (t, msg, fwd);
+ tunnel_send_client_buffered_data (t, c, rel);
}
else
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "save for later\n");
- tunnel_add_buffer_ucast (t, msg);
+ tunnel_add_buffered_data (t, msg, rel);
}
}
else /* Tunnel unreliable, send to clients directly */
{
- tunnel_send_client_ucast (t, msg);
+ tunnel_send_client_data (t, msg, fwd);
}
}
else
@@ -4074,7 +4009,7 @@
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" MID %llu not expected (%llu - %llu), dropping!\n",
GNUNET_ntohll (msg->mid),
- t->bck_rel->mid_recv, t->bck_rel->mid_recv + 64LL);
+ rel->mid_recv, rel->mid_recv + 64LL);
}
}
else
@@ -4082,13 +4017,13 @@
// GNUNET_STATISTICS_update (stats, "# duplicate PID", 1, GNUNET_NO);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" Pid %u not expected (%u), dropping!\n",
- pid, t->prev_fc.last_pid_recv + 1);
+ pid, fc->last_pid_recv + 1);
}
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
+ tunnel_send_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST, fwd);
return GNUNET_OK;
}
- t->prev_fc.last_pid_recv = pid;
- if (0 == t->next_hop)
+ fc->last_pid_recv = pid;
+ if (0 == hop)
{
GNUNET_break (0);
return GNUNET_OK;
@@ -4099,133 +4034,52 @@
{
GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n");
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
+ tunnel_send_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK, fwd);
return GNUNET_OK;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " not for us, retransmitting...\n");
- send_prebuilt_message (message, t->next_hop, t);
- GNUNET_STATISTICS_update (stats, "# unicast forwarded", 1, GNUNET_NO);
+ if (myid != hop)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " not for us, retransmitting...\n");
+ send_prebuilt_message (message, hop, t);
+ GNUNET_STATISTICS_update (stats, "# unicast forwarded", 1, GNUNET_NO);
+ }
return GNUNET_OK;
}
/**
- * Core handler for mesh network traffic toward the owner of a tunnel
+ * Core handler for mesh network traffic going from the origin to a peer
*
- * @param cls closure
- * @param message message
- * @param peer peer identity this notification is about
+ * @param cls Closure (unused).
+ * @param message Message received.
+ * @param peer Peer who sent the message.
*
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
+handle_mesh_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_MessageHeader *message)
+{
+ return handle_mesh_data (peer, message, GNUNET_YES);
+}
+
+/**
+ * Core handler for mesh network traffic towards the owner of a tunnel.
+ *
+ * @param cls Closure (unused).
+ * @param message Message received.
+ * @param peer Peer who sent the message.
+ *
+ * @return GNUNET_OK to keep the connection open,
+ * GNUNET_SYSERR to close it (signal serious error)
+ */
+static int
handle_mesh_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message)
+ const struct GNUNET_MessageHeader *message)
{
- struct GNUNET_MESH_Data *msg;
- struct MeshTunnel *t;
- size_t size;
- uint32_t pid;
- uint32_t ttl;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a ToOrigin packet from %s\n",
- GNUNET_i2s (peer));
- size = ntohs (message->size);
- if (size < sizeof (struct GNUNET_MESH_Data) + /* Payload must be */
- sizeof (struct GNUNET_MessageHeader)) /* at least a header */
- {
- GNUNET_break_op (0);
- return GNUNET_OK;
- }
- msg = (struct GNUNET_MESH_Data *) message;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " of type %s\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
- t = tunnel_get (&msg->oid, ntohl (msg->tid));
- pid = ntohl (msg->pid);
- if (NULL == t)
- {
- /* TODO notify that we dont know this tunnel (whom)? */
- GNUNET_STATISTICS_update (stats, "# data on unknown tunnel", 1, GNUNET_NO);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received to_origin with PID %u on unknown tunnel %s [%u]\n",
- pid, GNUNET_i2s (&msg->oid), ntohl (msg->tid));
- return GNUNET_OK;
- }
-
- if (GMC_is_pid_bigger (pid, t->next_fc.last_ack_sent))
- {
- GNUNET_STATISTICS_update (stats, "# unsolicited to_orig", 1, GNUNET_NO);
- GNUNET_break_op (0);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received PID %u, ACK %u\n",
- pid, t->next_fc.last_ack_sent);
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL);
- return GNUNET_OK;
- }
-
- if (myid == t->id.oid)
- {
- /* TODO signature verification */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " it's for us! sending to clients...\n");
- GNUNET_STATISTICS_update (stats, "# to origin received", 1, GNUNET_NO);
- if ( (GNUNET_NO == t->reliable &&
- GMC_is_pid_bigger(pid, t->next_fc.last_pid_recv))
- ||
- (GNUNET_YES == t->reliable &&
- pid == t->next_fc.last_pid_recv + 1) ) // FIXME use "futures" as
accepting
- {
- t->next_fc.last_pid_recv = pid;
- tunnel_send_client_to_orig (t, msg);
- }
- else
- {
-// GNUNET_STATISTICS_update (stats, "# duplicate PID drops BCK", 1,
GNUNET_NO);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- " Pid %u not expected, sending FWD ACK!\n", pid);
- }
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
- return GNUNET_OK;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " not for us, retransmitting...\n");
- t->next_fc.last_pid_recv = pid;
- if (0 == t->prev_hop) /* No owner AND no prev hop */
- {
- if (GNUNET_YES == t->destroy)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "to orig received on a dying tunnel %s [%X]\n",
- GNUNET_i2s (&msg->oid), ntohl(msg->tid));
- return GNUNET_OK;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "unknown to origin at %s\n",
- GNUNET_i2s (&my_full_id));
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "from peer %s\n",
- GNUNET_i2s (peer));
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "on tunnel %s [%X]\n",
- GNUNET_i2s (&msg->oid), ntohl(msg->tid));
- return GNUNET_OK;
- }
- ttl = ntohl (msg->ttl);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ttl: %u\n", ttl);
- if (ttl == 0)
- {
- GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n");
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
- return GNUNET_OK;
- }
- send_prebuilt_message (message, t->prev_hop, t);
- GNUNET_STATISTICS_update (stats, "# to origin forwarded", 1, GNUNET_NO);
-
- return GNUNET_OK;
+ return handle_mesh_data (peer, message, GNUNET_NO);
}
@@ -4279,7 +4133,7 @@
return GNUNET_OK;
}
rel = t->fwd_rel;
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
+ tunnel_send_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST, GNUNET_YES);
}
else if (t->prev_hop == id && GNUNET_MESSAGE_TYPE_MESH_TO_ORIG_ACK == type)
{
@@ -4290,7 +4144,7 @@
return GNUNET_OK;
}
rel = t->bck_rel;
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
+ tunnel_send_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, GNUNET_NO);
}
else
{
@@ -4304,7 +4158,7 @@
if (copy->mid > ack)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! head %llu, out!\n",
copy->mid);
- tunnel_free_buffer_ucast (t, msg);
+ tunnel_free_sent_reliable (t, msg, rel);
break;
}
work = GNUNET_YES;
@@ -4340,7 +4194,7 @@
}
else
GNUNET_break (0);
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK);
+ tunnel_send_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK, GNUNET_YES);
}
return GNUNET_OK;
}
@@ -4384,13 +4238,11 @@
id = GNUNET_PEER_search (peer);
if (t->next_hop == id)
{
- debug_fwd_ack++;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " FWD ACK\n");
fc = &t->next_fc;
}
else if (t->prev_hop == id)
{
- debug_bck_ack++;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " BCK ACK\n");
fc = &t->prev_fc;
}
@@ -4410,10 +4262,7 @@
fc->last_ack_recv = ack;
peer_unlock_queue (id);
- if (t->next_hop == id)
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
- else
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
+ tunnel_send_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK, t->next_hop == id);
return GNUNET_OK;
}
@@ -4466,7 +4315,7 @@
fc = &t->next_fc;
old = fc->last_pid_recv;
fc->last_pid_recv = pid;
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL);
+ tunnel_send_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL, GNUNET_NO);
}
else if (t->prev_hop == id)
{
@@ -4475,11 +4324,11 @@
fc = &t->prev_fc;
old = fc->last_pid_recv;
fc->last_pid_recv = pid;
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL);
+ tunnel_send_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL, GNUNET_YES);
}
else
GNUNET_break (0);
-
+
if (GNUNET_YES == t->reliable)
fc->last_pid_recv = old;
@@ -4519,7 +4368,7 @@
return GNUNET_OK;
}
- tunnel_reset_timeout (t);
+ tunnel_reset_timeout (t, GNUNET_YES); // FIXME
if (NULL != t->client || 0 == t->next_hop || myid == t->next_hop)
return GNUNET_OK;
@@ -5187,17 +5036,17 @@
}
/* Does client own tunnel? I.E: Is this an ACK for BCK traffic? */
- if (t->owner == c)
+ if (tid < GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
{
/* The client owns the tunnel, ACK is for data to_origin, send BCK ACK. */
t->prev_fc.last_ack_recv++;
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
+ tunnel_send_ack (t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK, GNUNET_NO);
}
else
{
/* The client doesn't own the tunnel, this ACK is for FWD traffic. */
t->next_fc.last_ack_recv++;
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
+ tunnel_send_ack (t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK, GNUNET_YES);
}
GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -5803,9 +5652,5 @@
INTERVAL_SHOW;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Mesh for peer [%s] FWD ACKs %u, BCK ACKs %u\n",
- GNUNET_i2s(&my_full_id), debug_fwd_ack, debug_bck_ack);
-
return ret;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r28057 - gnunet/src/mesh,
gnunet <=