#include "gnunet_fragmentation_lib.h"
/**
- * Header for a message fragment.
+ * Header for a message fragment. Followed by the
+ * original message.
*/
struct FragmentHeader
{
+ /**
+ * Message header.
+ */
struct GNUNET_MessageHeader header;
+ /**
+ * Unique fragment ID.
+ */
+ uint32_t fragment_id;
+
+ /**
+ * Total message size of the original message.
+ */
+ uint16_t total_size;
+
+ /**
+ * Absolute offset (in bytes) of this fragment in the original
+ * message. Will be a multiple of the MTU.
+ */
+ uint16_t offset;
+
};
struct FragmentAcknowledgement
{
+ /**
+ * Message header.
+ */
struct GNUNET_MessageHeader header;
+ /**
+ * Unique fragment ID.
+ */
+ uint32_t fragment_id;
+
/**
* Bits that are being acknowledged, in big-endian.
* (bits that are set correspond to fragments that
* @brief library to help fragment messages
* @author Christian Grothoff
*/
-
#include "platform.h"
#include "gnunet_fragmentation_lib.h"
+#include "gnunet_protocols.h"
#include "fragmentation.h"
+
/**
* Fragmentation context.
*/
*/
GNUNET_SCHEDULER_TaskIdentifier task;
+ /**
+ * Our fragmentation ID. (chosen at random)
+ */
+ uint32_t fragment_id;
+
/**
* Round-robin selector for the next transmission.
*/
fh = (struct FragmentHeader*) msg;
fh->header.size = htons (fsize);
fh->header.type = htons (GNUNET_MESSAGE_TYPE_FRAGMENT);
- /* FIXME: add specific ID info... */
+ fh->fragment_id = htonl (fc->fragment_id);
+ fh->total_size = fc->msg->size; /* already in big-endian */
+ fh->offset = htons (fc->mtu * bit);
memcpy (&fc[1],
&mbuf[bit * (fc->mtu - sizeof (struct FragmentHeader))],
fsize - sizeof (struct FragmentHeader));
fc->msg = (const struct GNUNET_MessageHeader*)&fc[1];
fc->proc = proc;
fc->proc_cls = proc_cls;
+ fc->fragment_id = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
+ UINT32_MAX);
memcpy (&fc[1], msg, size);
bits = (size + mtu - 1) / (mtu - sizeof (struct FragmentHeader));
GNUNET_assert (bits <= 64);
return GNUNET_SYSERR;
}
fa = (const struct FragmentAcknowledgement *) msg;
+ if (ntohl (fa->fragment_id) != fc->fragment_id)
+ return GNUNET_SYSERR; /* not our ACK */
abits = GNUNET_ntohll (fa->bits);
- /* FIXME: match FA to us... */
-
if (GNUNET_YES == fc->wack)
{
/* normal ACK, can update running average of delay... */
return ret;
}
+
/* end of fragmentation_new.c */