}
+/**
+ * Send an end-to-end FWD ACK message for the most recent in-sequence payload.
+ *
+ * @param t Tunnel this is about.
+ */
+static void
+tunnel_send_fwd_data_ack (struct MeshTunnel *t)
+{
+ struct GNUNET_MESH_DataACK msg;
+
+ msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_DATA_ACK);
+ msg.header.size = htons (sizeof (msg));
+ msg.tid = htonl (t->id.tid);
+ GNUNET_PEER_resolve (t->id.oid, &msg.oid);
+ msg.pid = htonl (t->prev_fc.last_pid_recv);
+ msg.futures = 0; // FIXME set bits of other newer messages received
+
+ send_prebuilt_message (&msg.header, t->prev_hop, t);
+}
+
+
+/**
+ * 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_DATA_ACK);
+ msg.header.size = htons (sizeof (msg));
+ msg.tid = htonl (t->id.tid);
+ GNUNET_PEER_resolve (t->id.oid, &msg.oid);
+ msg.pid = htonl (t->next_fc.last_pid_recv);
+ 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.
return;
case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
break;
+ case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
+ tunnel_send_fwd_data_ack (t);
+ /* fall through */
case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
case GNUNET_MESSAGE_TYPE_MESH_POLL:
- case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
t->force_ack = GNUNET_YES;
break;
default:
return;
case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
break;
+ case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
+ tunnel_send_bck_data_ack (t);
+ /* fall through */
case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
case GNUNET_MESSAGE_TYPE_MESH_POLL:
- case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
t->force_ack = GNUNET_YES;
break;
default:
tunnel_send_fwd_ack(t, GNUNET_MESSAGE_TYPE_MESH_POLL);
return GNUNET_OK;
}
- t->prev_fc.last_pid_recv = pid;
tunnel_reset_timeout (t);
if (t->dest == myid)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" pid %u not seen yet, forwarding\n", pid);
+ t->prev_fc.last_pid_recv = pid;
tunnel_send_client_ucast (t, msg);
tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
}
}
return GNUNET_OK;
}
+ t->prev_fc.last_pid_recv = pid;
if (0 == t->next_hop)
{
GNUNET_break (0);
tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL);
return GNUNET_OK;
}
- t->next_fc.last_pid_recv = pid;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " pid %u not seen yet, forwarding\n", pid);
if (myid == t->id.oid)
{
GNUNET_STATISTICS_update (stats, "# to origin received", 1, GNUNET_NO);
if (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);
tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
}
}
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)