GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 2, or (at your
+ by the Free Software Foundation; either version 3, or (at your
option) any later version.
GNUnet is distributed in the hope that it will be useful, but
* fragmented packet at any given point in time (prevents
* DoS attacks). Fragmented messages that have not been
* completed after a certain amount of time are discarded.
- * @author Christian Grothoff
+ * @author Ji Lu
*/
#include "platform.h"
#include "gnunet_fragmentation_lib.h"
#include "gnunet_protocols.h"
#include "gnunet_util_lib.h"
+
/**
* Message fragment. This header is followed
* by the actual data of the fragment.
*/
+
struct Fragment
{
/**
* Fragment offset.
*/
- uint32_t off GNUNET_PACKED;
+ uint16_t off GNUNET_PACKED;
/**
- * "unique" id for the fragment
+ * "unique" id for the fragment
*/
- uint64_t id GNUNET_PACKED;
+ uint32_t id GNUNET_PACKED;
+ uint16_t mtu;
+ uint16_t totalNum;
+ uint16_t totalSize;
- size_t mtu;
- uint32_t totalNum;
- uint64_t totalSize;
};
struct GNUNET_FRAGEMENT_Ctxbuffer{
struct GNUNET_FRAGEMENT_Ctxbuffer *next;
- uint64_t id;
+ uint32_t id;
uint16_t size;
char * buff;
int counter;
struct GNUNET_TIME_Absolute receivedTime;
- struct GNUNET_PeerIdentity *peerID;
+ struct GNUNET_PeerIdentity peerID;
int * num;
};
{
uint32_t id = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, 256);
size_t size = sizeof(struct Fragment);
+
if(ntohs(msg->size) > mtu-size){
uint16_t lastSize;
uint16_t num;
{
struct Fragment *frag;
if(actualNum != num){
- if(i!=actualNum-1){
- frag = GNUNET_malloc(mtu);
- }
- else{
- frag = GNUNET_malloc(lastSize+size);
- }
- }
+ if(i!=actualNum-1){
+ frag = (struct Fragment *)GNUNET_malloc(mtu);
+ }
+ else{
+ frag = (struct Fragment *)GNUNET_malloc(lastSize+size);
+ }
+ }
else{
- frag = GNUNET_malloc(mtu);
+ frag = (struct Fragment *)GNUNET_malloc(mtu);
}
frag->header.type = htons(GNUNET_MESSAGE_TYPE_FRAGMENT);
frag->id = htonl(id);
frag->mtu = htons(mtu);
frag->totalNum = htons(actualNum);
frag->totalSize = msg->size;
+ char *tmpMsg = (char *)msg;
if(actualNum != num){
if(i!=actualNum-1){
frag->header.size = htons(mtu);
- memcpy(&frag[1], msg + ntohs(frag->off), mtu - size);
+ memcpy(&frag[1], tmpMsg + (mtu-size)*i, mtu - size);
}
else{
frag->header.size = htons(lastSize+size);
- memcpy(&frag[1], msg + ntohs(frag->off), lastSize);
+ memcpy(&frag[1], tmpMsg + (mtu-size)*i, lastSize);
}
}
else{
frag->header.size = htons(mtu);
- memcpy(&frag[1], msg + ntohs(frag->off), mtu - size);
+ memcpy(&frag[1], tmpMsg + (mtu-size)*i, mtu - size);
}
proc(proc_cls, &frag->header);
GNUNET_free(frag);
}
}
-
/**
* Create a defragmentation context.
*
GNUNET_FRAGMENT_context_destroy (struct GNUNET_FRAGMENT_Context *ctx)
{
struct GNUNET_FRAGEMENT_Ctxbuffer *buffer;
- for(buffer = ctx->buffer; buffer!=NULL; buffer = buffer->next){
- GNUNET_free(buffer->num);
- GNUNET_free(buffer);
- }
+ struct GNUNET_FRAGEMENT_Ctxbuffer *temp;
+ buffer = ctx->buffer;
+
+ while (buffer != NULL)
+ {
+ temp = buffer->next;
+ GNUNET_free(buffer->num);
+ GNUNET_free(buffer);
+ buffer = temp;
+ }
GNUNET_free(ctx);
GNUNET_assert (0);
}
buffer = ctx->buffer;
while (buffer != NULL)
{
-//for(buffer = ctx->buffer; buffer != NULL; buffer = buffer->next){
- if(buffer->id == ntohl(frag->id)&&(buffer->peerID==sender)){
+ if ((buffer->id == ntohl(frag->id))&&(0 == memcmp (&buffer->peerID,
+ sender, sizeof (struct GNUNET_PeerIdentity)))){
exist = 1;
break;
}
if(!exist){
buffer = GNUNET_malloc(sizeof(struct GNUNET_FRAGEMENT_Ctxbuffer));
- buffer->num = (int*)GNUNET_malloc(ntohs(frag->totalNum)*sizeof(int));
+ buffer->num = GNUNET_malloc(ntohs(frag->totalNum)*sizeof(int));
int j;
for(j = 0; j<ntohs(frag->totalNum); j++){
buffer->num[j] = -10;
}
- buffer->peerID = sender;
+ buffer->peerID = *sender;
buffer->id = ntohl(frag->id);
buffer->receivedTime = GNUNET_TIME_absolute_get ();
- uint64_t si = ntohs(frag->totalSize);
+ uint16_t si = ntohs(frag->totalSize);
buffer->size = si;
- buffer->buff = (char *)GNUNET_malloc(si);
+ buffer->buff = GNUNET_malloc(si);
buffer->next = ctx->buffer;
ctx->buffer = buffer;
}
/**
* Hashtable *with* collision management!
*/
-static FC *defragmentationCache[DEFRAG_BUCKET_COUNT];
+static struct FC *defragmentationCache[DEFRAG_BUCKET_COUNT];
/**
* Lock for the defragmentation cache.