aboutsummaryrefslogtreecommitdiff
path: root/src/fragmentation
diff options
context:
space:
mode:
authorJi Lu <jilu@140774ce-b5e7-0310-ab8b-a85725594a96>2010-03-18 20:33:07 +0000
committerJi Lu <jilu@140774ce-b5e7-0310-ab8b-a85725594a96>2010-03-18 20:33:07 +0000
commit40ff2323130e2cbe383f9b00fdb5ddfef995d347 (patch)
treeadce84a86320e2ccad5264dc3c913a81e8b53e7b /src/fragmentation
parent558fa8b012469c0ada0c4fac6d05c01a727ef764 (diff)
downloadgnunet-40ff2323130e2cbe383f9b00fdb5ddfef995d347.tar.gz
gnunet-40ff2323130e2cbe383f9b00fdb5ddfef995d347.zip
to be continued
Diffstat (limited to 'src/fragmentation')
-rw-r--r--src/fragmentation/Makefile.am2
-rw-r--r--src/fragmentation/fragmentation.c1016
-rw-r--r--src/fragmentation/test_frag_ji.c51
3 files changed, 571 insertions, 498 deletions
diff --git a/src/fragmentation/Makefile.am b/src/fragmentation/Makefile.am
index d3a47d920..47915a35f 100644
--- a/src/fragmentation/Makefile.am
+++ b/src/fragmentation/Makefile.am
@@ -21,7 +21,7 @@ check_PROGRAMS = \
21TESTS = $(check_PROGRAMS) 21TESTS = $(check_PROGRAMS)
22 22
23test_fragmentation_SOURCES = \ 23test_fragmentation_SOURCES = \
24 test_fragmentation.c 24 test_frag_ji.c
25test_fragmentation_LDADD = \ 25test_fragmentation_LDADD = \
26 $(top_builddir)/src/fragmentation/libgnunetfragmentation.la \ 26 $(top_builddir)/src/fragmentation/libgnunetfragmentation.la \
27 $(top_builddir)/src/util/libgnunetutil.la 27 $(top_builddir)/src/util/libgnunetutil.la
diff --git a/src/fragmentation/fragmentation.c b/src/fragmentation/fragmentation.c
index 49680bf42..c67059f34 100644
--- a/src/fragmentation/fragmentation.c
+++ b/src/fragmentation/fragmentation.c
@@ -16,7 +16,7 @@
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19 */
20/** 20/**
21 * @file fragmentation/fragmentation.c 21 * @file fragmentation/fragmentation.c
22 * @brief fragmentation and defragmentation, this code allows 22 * @brief fragmentation and defragmentation, this code allows
@@ -42,31 +42,31 @@
42struct Fragment 42struct Fragment
43{ 43{
44 44
45 struct GNUNET_MessageHeader header; 45 struct GNUNET_MessageHeader header;
46
47 /**
48 * Fragment offset.
49 */
50 uint32_t off GNUNET_PACKED;
51 46
52 /** 47 /**
53 * "unique" id for the fragment 48 * Fragment offset.
54 */ 49 */
55 uint64_t id GNUNET_PACKED; 50 uint32_t off GNUNET_PACKED;
56 51
57 size_t mtu; 52 /**
58 uint32_t totalNum; 53 * "unique" id for the fragment
54 */
55 uint64_t id GNUNET_PACKED;
59 56
57 size_t mtu;
58 uint32_t totalNum;
59 uint64_t totalSize;
60}; 60};
61 61
62struct GNUNET_FRAGEMENT_Ctxbuffer{ 62struct GNUNET_FRAGEMENT_Ctxbuffer{
63 uint64_t id;
64 uint16_t size;
65 char * buff;
66 int counter;
67 struct GNUNET_TIME_Absolute receivedTime;
68 struct GNUNET_PeerIdentity *peerID;
69 struct GNUNET_FRAGEMENT_Ctxbuffer *next; 63 struct GNUNET_FRAGEMENT_Ctxbuffer *next;
64 uint64_t id;
65 uint16_t size;
66 char * buff;
67 int counter;
68 struct GNUNET_TIME_Absolute receivedTime;
69 struct GNUNET_PeerIdentity *peerID;
70 int * num; 70 int * num;
71}; 71};
72 72
@@ -78,6 +78,8 @@ struct GNUNET_FRAGMENT_Context
78{ 78{
79 uint32_t maxNum; 79 uint32_t maxNum;
80 struct GNUNET_FRAGEMENT_Ctxbuffer *buffer; 80 struct GNUNET_FRAGEMENT_Ctxbuffer *buffer;
81 GNUNET_FRAGMENT_MessageProcessor proc;
82 void *proc_cls;
81}; 83};
82 84
83 85
@@ -91,38 +93,59 @@ struct GNUNET_FRAGMENT_Context
91 */ 93 */
92void 94void
93GNUNET_FRAGMENT_fragment (const struct GNUNET_MessageHeader *msg, 95GNUNET_FRAGMENT_fragment (const struct GNUNET_MessageHeader *msg,
94 uint16_t mtu, 96 uint16_t mtu,
95 GNUNET_FRAGMENT_MessageProcessor proc, 97 GNUNET_FRAGMENT_MessageProcessor proc,
96 void *proc_cls) 98 void *proc_cls)
97{ 99{
98 uint32_t id = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, 256); 100 uint32_t id = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, 256);
99 size_t size = sizeof(struct Fragment); 101 size_t size = sizeof(struct Fragment);
100 if(msg->size > mtu){ 102 if(ntohs(msg->size) > mtu-size){
101 uint16_t lastSize = (msg->size) % (mtu-size); 103 uint16_t lastSize;
102 int num = ceil(msg->size / mtu - size); 104 uint16_t num;
103 int i; 105 uint16_t i;
104 for(i = 0; i<num; i++){ 106 uint16_t actualNum;
105 struct Fragment *frag = (struct Fragment *)GNUNET_malloc(size); 107 lastSize = ntohs(msg->size) % (mtu-size);
108 num = ntohs(msg->size) / (mtu - size);
109 actualNum = num;
110 if(lastSize!=0){
111 actualNum = num+1;
112 }
113 for(i = 0; i<actualNum; i++)
114 {
115 struct Fragment *frag;
116 if(actualNum != num){
117 if(i!=actualNum-1){
118 frag = GNUNET_malloc(mtu);
119 }
120 else{
121 frag = GNUNET_malloc(lastSize+size);
122 }
123 }
124 else{
125 frag = GNUNET_malloc(mtu);
126 }
106 frag->header.type = htons(GNUNET_MESSAGE_TYPE_FRAGMENT); 127 frag->header.type = htons(GNUNET_MESSAGE_TYPE_FRAGMENT);
107 frag->id = htonl(id); 128 frag->id = htonl(id);
108 frag->off = htons(mtu*i); 129 frag->off = htons((mtu-size)*i);
109 frag->mtu = htons(mtu); 130 frag->mtu = htons(mtu);
110 if(lastSize!=0){ 131 frag->totalNum = htons(actualNum);
111 frag->totalNum = htons(num+1); 132 frag->totalSize = msg->size;
133 if(actualNum != num){
134 if(i!=actualNum-1){
135 frag->header.size = htons(mtu);
136 memcpy(&frag[1], msg + ntohs(frag->off), mtu - size);
137 }
138 else{
139 frag->header.size = htons(lastSize+size);
140 memcpy(&frag[1], msg + ntohs(frag->off), lastSize);
141 }
112 } 142 }
113 else{ 143 else{
114 frag->totalNum = htons(num); 144 frag->header.size = htons(mtu);
145 memcpy(&frag[1], msg + ntohs(frag->off), mtu - size);
115 } 146 }
116 if(i!=num-1){ 147 proc(proc_cls, &frag->header);
117 frag->header.size = htons(mtu - size); 148 GNUNET_free(frag);
118 memcpy((char*)&frag[1], (char *)&msg[1]+frag->off, mtu - size);
119 }
120 else{
121 frag->header.size = htons(lastSize);
122 memcpy((char*)&frag[1], (char *)&msg[1]+frag->off, lastSize);
123 }
124 proc(proc_cls, &frag->header);
125 free(frag);
126 } 149 }
127 } 150 }
128} 151}
@@ -138,14 +161,16 @@ GNUNET_FRAGMENT_fragment (const struct GNUNET_MessageHeader *msg,
138 */ 161 */
139struct GNUNET_FRAGMENT_Context * 162struct GNUNET_FRAGMENT_Context *
140GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats, 163GNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats,
141 GNUNET_FRAGMENT_MessageProcessor proc, 164 GNUNET_FRAGMENT_MessageProcessor proc,
142 void *proc_cls) 165 void *proc_cls)
143{ 166 {
144 struct GNUNET_FRAGMENT_Context *ctx = (struct GNUNET_FRAGMENT_Context*)GNUNET_malloc(sizeof(struct GNUNET_FRAGMENT_Context)); 167 struct GNUNET_FRAGMENT_Context *ctx = (struct GNUNET_FRAGMENT_Context*)GNUNET_malloc(sizeof(struct GNUNET_FRAGMENT_Context));
145 ctx->maxNum = 100; 168 ctx->maxNum = 100;
169 ctx->proc = proc;
170 ctx->proc_cls = proc_cls;
146 ctx->buffer = NULL; 171 ctx->buffer = NULL;
147 return ctx; 172 return ctx;
148} 173 }
149 174
150 175
151/** 176/**
@@ -173,46 +198,77 @@ GNUNET_FRAGMENT_context_destroy (struct GNUNET_FRAGMENT_Context *ctx)
173 */ 198 */
174void 199void
175GNUNET_FRAGMENT_process (struct GNUNET_FRAGMENT_Context *ctx, 200GNUNET_FRAGMENT_process (struct GNUNET_FRAGMENT_Context *ctx,
176 const struct GNUNET_PeerIdentity *sender, 201 const struct GNUNET_PeerIdentity *sender,
177 const struct GNUNET_MessageHeader *msg) 202 const struct GNUNET_MessageHeader *msg)
178{ 203{
179 uint16_t type = ntohs(msg->type); 204 uint16_t type = ntohs(msg->type);
180 int exited = 0, received = 0; 205 int exist = 0, received = 0;
181 if(type!=GNUNET_MESSAGE_TYPE_FRAGMENT){ 206 if(type!=GNUNET_MESSAGE_TYPE_FRAGMENT){
182 return; 207 return;
183 } 208 }
184 struct Fragment *frag = (struct Fragment *)msg; 209 struct Fragment *frag = (struct Fragment *)msg;
185 struct GNUNET_FRAGEMENT_Ctxbuffer* buffer; 210 struct GNUNET_FRAGEMENT_Ctxbuffer* buffer;
186 for(buffer = ctx->buffer; buffer!= NULL; buffer = buffer->next){ 211 struct GNUNET_FRAGEMENT_Ctxbuffer* prev;
187 if(ctx->buffer->counter == ntohs(frag->totalNum)){return;} 212 prev = NULL;
188 if(buffer->id == ntohl(frag->id)&&(buffer->peerID==sender)){ 213 buffer = ctx->buffer;
189 exited = 1; 214 while (buffer != NULL)
190 int i; 215 {
191 for(i = 0; i<ntohs(frag->totalNum); i++){ 216//for(buffer = ctx->buffer; buffer != NULL; buffer = buffer->next){
192 if(buffer->num[i]==ntohs(frag->off)/ntohs(frag->mtu)){ 217 if(buffer->id == ntohl(frag->id)&&(buffer->peerID==sender)){
193 received = 1; 218 exist = 1;
194 break; 219 break;
195 } 220 }
196 } 221 prev = buffer;
197 if(!received){ 222 buffer = buffer->next;
198 buffer->num[buffer->counter++]=ntohs(frag->off)/ntohs(frag->mtu); 223 }
199 } 224
200 buffer->receivedTime = GNUNET_TIME_absolute_get (); 225 if (exist)
201 uint16_t size = ntohs(frag->header.size); 226 {
202 memcpy(&buffer->buff[ntohs(frag->off)], &frag[1], size); 227 int i;
203 break; 228 for(i = 0; i<ntohs(frag->totalNum); i++){
204 } 229 if(buffer->num[i]==ntohs(frag->off)/(ntohs(frag->mtu)-sizeof(struct Fragment))){
205 } 230 received = 1;
206 if(!exited){ 231 break;
207 buffer = (struct GNUNET_FRAGEMENT_Ctxbuffer* )GNUNET_malloc(sizeof(struct GNUNET_FRAGEMENT_Ctxbuffer)); 232 }
208 buffer->num = (int*)GNUNET_malloc(ntohs(frag->totalNum)*sizeof(int)); 233 }
209 buffer->num[buffer->counter++]=ntohs(frag->off)/ntohs(frag->mtu); 234 }
210 memcpy(buffer->peerID,sender,sizeof(struct GNUNET_PeerIdentity)); 235
211 buffer->receivedTime = GNUNET_TIME_absolute_get (); 236 if(!exist){
212 uint16_t size = ntohs(frag->header.size); 237 buffer = GNUNET_malloc(sizeof(struct GNUNET_FRAGEMENT_Ctxbuffer));
213 memcpy(&buffer->buff[ntohs(frag->off)], &frag[1], size); 238 buffer->num = (int*)GNUNET_malloc(ntohs(frag->totalNum)*sizeof(int));
214 } 239 int j;
240 for(j = 0; j<ntohs(frag->totalNum); j++){
241 buffer->num[j] = -10;
242 }
243 buffer->peerID = sender;
244 buffer->id = ntohl(frag->id);
245 buffer->receivedTime = GNUNET_TIME_absolute_get ();
246 uint64_t si = ntohs(frag->totalSize);
247 buffer->size = si;
248 buffer->buff = (char *)GNUNET_malloc(si);
249 buffer->next = ctx->buffer;
250 ctx->buffer = buffer;
251 }
252
253 if(!received){
254 buffer->num[buffer->counter++]=ntohs(frag->off)/(ntohs(frag->mtu)-sizeof(struct Fragment));
255 uint16_t sizeoffrag = ntohs(frag->header.size) - sizeof(struct Fragment);
256 memcpy(&buffer->buff[ntohs(frag->off)], &frag[1], sizeoffrag);
257 buffer->receivedTime = GNUNET_TIME_absolute_get ();
258 }
215 259
260 if(buffer->counter == ntohs(frag->totalNum))
261 {
262 ctx->proc(ctx->proc_cls, (struct GNUNET_MessageHeader *)buffer->buff);
263 if(prev==NULL){
264 ctx->buffer = buffer->next;
265 }
266 else{
267 prev->next = buffer->next;
268 }
269 GNUNET_free(buffer);
270 return;
271 }
216} 272}
217 273
218 274
@@ -237,8 +293,8 @@ GNUNET_FRAGMENT_process (struct GNUNET_FRAGMENT_Context *ctx,
237 */ 293 */
238typedef struct FL 294typedef struct FL
239{ 295{
240 struct FL *link; 296 struct FL *link;
241 P2P_fragmentation_MESSAGE *frag; 297 P2P_fragmentation_MESSAGE *frag;
242} FL; 298} FL;
243 299
244/** 300/**
@@ -246,11 +302,11 @@ typedef struct FL
246 */ 302 */
247typedef struct FC 303typedef struct FC
248{ 304{
249 struct FC *next; 305 struct FC *next;
250 FL *head; 306 FL *head;
251 GNUNET_PeerIdentity sender; 307 GNUNET_PeerIdentity sender;
252 int id; 308 int id;
253 GNUNET_CronTime ttl; 309 GNUNET_CronTime ttl;
254} FC; 310} FC;
255 311
256#define FRAGSIZE(fl) ((ntohs(fl->frag->header.size)-sizeof(P2P_fragmentation_MESSAGE))) 312#define FRAGSIZE(fl) ((ntohs(fl->frag->header.size)-sizeof(P2P_fragmentation_MESSAGE)))
@@ -278,15 +334,15 @@ static struct GNUNET_Mutex *defragCacheLock;
278static void 334static void
279freeFL (FL * fl, int c) 335freeFL (FL * fl, int c)
280{ 336{
281 while (fl != NULL) 337 while (fl != NULL)
282 { 338 {
283 FL *link = fl->link; 339 FL *link = fl->link;
284 if (stats != NULL) 340 if (stats != NULL)
285 stats->change (stat_discarded, c); 341 stats->change (stat_discarded, c);
286 GNUNET_free (fl->frag); 342 GNUNET_free (fl->frag);
287 GNUNET_free (fl); 343 GNUNET_free (fl);
288 fl = link; 344 fl = link;
289 } 345 }
290} 346}
291 347
292/** 348/**
@@ -302,38 +358,38 @@ freeFL (FL * fl, int c)
302static void 358static void
303defragmentationPurgeCron (void *unused) 359defragmentationPurgeCron (void *unused)
304{ 360{
305 int i; 361 int i;
306 FC *smf; 362 FC *smf;
307 FC *next; 363 FC *next;
308 FC *last; 364 FC *last;
309 365
310 GNUNET_mutex_lock (defragCacheLock); 366 GNUNET_mutex_lock (defragCacheLock);
311 for (i = 0; i < DEFRAG_BUCKET_COUNT; i++) 367 for (i = 0; i < DEFRAG_BUCKET_COUNT; i++)
312 { 368 {
313 last = NULL; 369 last = NULL;
314 smf = defragmentationCache[i]; 370 smf = defragmentationCache[i];
315 while (smf != NULL) 371 while (smf != NULL)
316 { 372 {
317 if (smf->ttl < GNUNET_get_time ()) 373 if (smf->ttl < GNUNET_get_time ())
318 { 374 {
319 /* free linked list of fragments */ 375 /* free linked list of fragments */
320 freeFL (smf->head, 1); 376 freeFL (smf->head, 1);
321 next = smf->next; 377 next = smf->next;
322 GNUNET_free (smf); 378 GNUNET_free (smf);
323 if (last == NULL) 379 if (last == NULL)
324 defragmentationCache[i] = next; 380 defragmentationCache[i] = next;
325 else 381 else
326 last->next = next; 382 last->next = next;
327 smf = next; 383 smf = next;
328 } 384 }
329 else 385 else
330 { 386 {
331 last = smf; 387 last = smf;
332 smf = smf->next; 388 smf = smf->next;
333 } 389 }
334 } /* while smf != NULL */ 390 } /* while smf != NULL */
335 } /* for all buckets */ 391 } /* for all buckets */
336 GNUNET_mutex_unlock (defragCacheLock); 392 GNUNET_mutex_unlock (defragCacheLock);
337} 393}
338 394
339/** 395/**
@@ -347,52 +403,52 @@ defragmentationPurgeCron (void *unused)
347static void 403static void
348checkComplete (FC * pep) 404checkComplete (FC * pep)
349{ 405{
350 FL *pos; 406 FL *pos;
351 unsigned short off; 407 unsigned short off;
352 unsigned short len; 408 unsigned short len;
353 char *msg; 409 char *msg;
354 410
355 GNUNET_GE_ASSERT (NULL, pep != NULL); 411 GNUNET_GE_ASSERT (NULL, pep != NULL);
356 pos = pep->head; 412 pos = pep->head;
357 if (pos == NULL) 413 if (pos == NULL)
358 return; 414 return;
359 len = ntohs (pos->frag->len); 415 len = ntohs (pos->frag->len);
360 if (len == 0) 416 if (len == 0)
361 goto CLEANUP; /* really bad error! */ 417 goto CLEANUP; /* really bad error! */
362 off = 0; 418 off = 0;
363 while ((pos != NULL) && (ntohs (pos->frag->off) <= off)) 419 while ((pos != NULL) && (ntohs (pos->frag->off) <= off))
364 { 420 {
365 if (off >= off + FRAGSIZE (pos)) 421 if (off >= off + FRAGSIZE (pos))
366 goto CLEANUP; /* error! */ 422 goto CLEANUP; /* error! */
367 if (ntohs (pos->frag->off) + FRAGSIZE (pos) > off) 423 if (ntohs (pos->frag->off) + FRAGSIZE (pos) > off)
368 off = ntohs (pos->frag->off) + FRAGSIZE (pos); 424 off = ntohs (pos->frag->off) + FRAGSIZE (pos);
369 else 425 else
370 goto CLEANUP; /* error! */ 426 goto CLEANUP; /* error! */
371 pos = pos->link; 427 pos = pos->link;
372 } 428 }
373 if (off < len) 429 if (off < len)
374 return; /* some fragment is still missing */ 430 return; /* some fragment is still missing */
375 431
376 msg = GNUNET_malloc (len); 432 msg = GNUNET_malloc (len);
377 pos = pep->head; 433 pos = pep->head;
378 while (pos != NULL) 434 while (pos != NULL)
379 { 435 {
380 memcpy (&msg[ntohs (pos->frag->off)], &pos->frag[1], FRAGSIZE (pos)); 436 memcpy (&msg[ntohs (pos->frag->off)], &pos->frag[1], FRAGSIZE (pos));
381 pos = pos->link; 437 pos = pos->link;
382 } 438 }
383 if (stats != NULL) 439 if (stats != NULL)
384 stats->change (stat_defragmented, 1); 440 stats->change (stat_defragmented, 1);
385#if 0 441#if 0
386 printf ("Finished defragmentation!\n"); 442 printf ("Finished defragmentation!\n");
387#endif 443#endif
388 /* handle message! */ 444 /* handle message! */
389 coreAPI->loopback_send (&pep->sender, msg, len, GNUNET_YES, NULL); 445 coreAPI->loopback_send (&pep->sender, msg, len, GNUNET_YES, NULL);
390 GNUNET_free (msg); 446 GNUNET_free (msg);
391CLEANUP: 447 CLEANUP:
392 /* free fragment buffers */ 448 /* free fragment buffers */
393 freeFL (pep->head, 0); 449 freeFL (pep->head, 0);
394 pep->head = NULL; 450 pep->head = NULL;
395 pep->ttl = 0; 451 pep->ttl = 0;
396} 452}
397 453
398/** 454/**
@@ -408,140 +464,140 @@ CLEANUP:
408 */ 464 */
409static int 465static int
410tryJoin (FC * entry, 466tryJoin (FC * entry,
411 const GNUNET_PeerIdentity * sender, 467 const GNUNET_PeerIdentity * sender,
412 const P2P_fragmentation_MESSAGE * packet) 468 const P2P_fragmentation_MESSAGE * packet)
413{ 469{
414 /* frame before ours; may end in the middle of 470 /* frame before ours; may end in the middle of
415 our frame or before it starts; NULL if we are 471 our frame or before it starts; NULL if we are
416 the earliest position we have received so far */ 472 the earliest position we have received so far */
417 FL *before; 473 FL *before;
418 /* frame after ours; may start in the middle of 474 /* frame after ours; may start in the middle of
419 our frame or after it; NULL if we are the last 475 our frame or after it; NULL if we are the last
420 fragment we have received so far */ 476 fragment we have received so far */
421 FL *after; 477 FL *after;
422 /* current position in the frame-list */ 478 /* current position in the frame-list */
423 FL *pos; 479 FL *pos;
424 /* the new entry that we're inserting */ 480 /* the new entry that we're inserting */
425 FL *pep; 481 FL *pep;
426 FL *tmp; 482 FL *tmp;
427 unsigned short end; 483 unsigned short end;
428 484
429 GNUNET_GE_ASSERT (NULL, entry != NULL); 485 GNUNET_GE_ASSERT (NULL, entry != NULL);
430 if (0 != memcmp (sender, &entry->sender, sizeof (GNUNET_PeerIdentity))) 486 if (0 != memcmp (sender, &entry->sender, sizeof (GNUNET_PeerIdentity)))
431 return GNUNET_SYSERR; /* wrong fragment list, try another! */ 487 return GNUNET_SYSERR; /* wrong fragment list, try another! */
432 if (ntohl (packet->id) != entry->id) 488 if (ntohl (packet->id) != entry->id)
433 return GNUNET_SYSERR; /* wrong fragment list, try another! */ 489 return GNUNET_SYSERR; /* wrong fragment list, try another! */
434#if 0 490#if 0
435 printf ("Received fragment %u from %u to %u\n", 491 printf ("Received fragment %u from %u to %u\n",
436 ntohl (packet->id), 492 ntohl (packet->id),
437 ntohs (packet->off), 493 ntohs (packet->off),
438 ntohs (packet->off) + ntohs (packet->header.size) - 494 ntohs (packet->off) + ntohs (packet->header.size) -
439 sizeof (P2P_fragmentation_MESSAGE)); 495 sizeof (P2P_fragmentation_MESSAGE));
440#endif 496#endif
441 pos = entry->head; 497 pos = entry->head;
442 if ((pos != NULL) && (packet->len != pos->frag->len)) 498 if ((pos != NULL) && (packet->len != pos->frag->len))
443 return GNUNET_SYSERR; /* wrong fragment size */ 499 return GNUNET_SYSERR; /* wrong fragment size */
444 500
445 before = NULL; 501 before = NULL;
446 /* find the before-frame */ 502 /* find the before-frame */
447 while ((pos != NULL) && (ntohs (pos->frag->off) < ntohs (packet->off))) 503 while ((pos != NULL) && (ntohs (pos->frag->off) < ntohs (packet->off)))
448 { 504 {
449 before = pos; 505 before = pos;
450 pos = pos->link; 506 pos = pos->link;
451 } 507 }
452 508
453 /* find the after-frame */ 509 /* find the after-frame */
454 end = 510 end =
455 ntohs (packet->off) + ntohs (packet->header.size) - 511 ntohs (packet->off) + ntohs (packet->header.size) -
456 sizeof (P2P_fragmentation_MESSAGE); 512 sizeof (P2P_fragmentation_MESSAGE);
457 if (end <= ntohs (packet->off)) 513 if (end <= ntohs (packet->off))
458 { 514 {
459 GNUNET_GE_LOG (NULL, 515 GNUNET_GE_LOG (NULL,
460 GNUNET_GE_DEVELOPER | GNUNET_GE_DEBUG | GNUNET_GE_BULK, 516 GNUNET_GE_DEVELOPER | GNUNET_GE_DEBUG | GNUNET_GE_BULK,
461 "Received invalid fragment at %s:%d\n", __FILE__, 517 "Received invalid fragment at %s:%d\n", __FILE__,
462 __LINE__); 518 __LINE__);
463 return GNUNET_SYSERR; /* yuck! integer overflow! */ 519 return GNUNET_SYSERR; /* yuck! integer overflow! */
464 } 520 }
465 521
466 if (before != NULL) 522 if (before != NULL)
467 after = before; 523 after = before;
468 else 524 else
469 after = entry->head; 525 after = entry->head;
470 while ((after != NULL) && (ntohs (after->frag->off) < end)) 526 while ((after != NULL) && (ntohs (after->frag->off) < end))
471 after = after->link; 527 after = after->link;
472 528
473 if ((before != NULL) && (before == after)) 529 if ((before != NULL) && (before == after))
474 { 530 {
475 /* this implies after or before != NULL and thereby the new 531 /* this implies after or before != NULL and thereby the new
476 fragment is redundant as it is fully enclosed in an earlier 532 fragment is redundant as it is fully enclosed in an earlier
477 fragment */ 533 fragment */
478 if (stats != NULL) 534 if (stats != NULL)
479 stats->change (stat_defragmented, 1); 535 stats->change (stat_defragmented, 1);
480 return GNUNET_OK; /* drop, there is a packet that spans our range! */ 536 return GNUNET_OK; /* drop, there is a packet that spans our range! */
481 } 537 }
482 538
483 if ((before != NULL) && 539 if ((before != NULL) &&
484 (after != NULL) && 540 (after != NULL) &&
485 ((htons (before->frag->off) + 541 ((htons (before->frag->off) +
486 FRAGSIZE (before)) >= htons (after->frag->off))) 542 FRAGSIZE (before)) >= htons (after->frag->off)))
487 { 543 {
488 /* this implies that the fragment that starts before us and the 544 /* this implies that the fragment that starts before us and the
489 fragment that comes after this one leave no space in the middle 545 fragment that comes after this one leave no space in the middle
490 or even overlap; thus we can drop this redundant piece */ 546 or even overlap; thus we can drop this redundant piece */
491 if (stats != NULL) 547 if (stats != NULL)
492 stats->change (stat_defragmented, 1); 548 stats->change (stat_defragmented, 1);
493 return GNUNET_OK; 549 return GNUNET_OK;
494 } 550 }
495 551
496 /* allocate pep */ 552 /* allocate pep */
497 pep = GNUNET_malloc (sizeof (FC)); 553 pep = GNUNET_malloc (sizeof (FC));
498 pep->frag = GNUNET_malloc (ntohs (packet->header.size)); 554 pep->frag = GNUNET_malloc (ntohs (packet->header.size));
499 memcpy (pep->frag, packet, ntohs (packet->header.size)); 555 memcpy (pep->frag, packet, ntohs (packet->header.size));
500 pep->link = NULL; 556 pep->link = NULL;
501 557
502 if (before == NULL) 558 if (before == NULL)
503 { 559 {
504 pep->link = after; 560 pep->link = after;
505 pos = entry->head; 561 pos = entry->head;
506 while (pos != after) 562 while (pos != after)
507 { 563 {
508 tmp = pos->link; 564 tmp = pos->link;
509 GNUNET_free (pos->frag); 565 GNUNET_free (pos->frag);
510 GNUNET_free (pos); 566 GNUNET_free (pos);
511 pos = tmp; 567 pos = tmp;
512 } 568 }
513 entry->head = pep; 569 entry->head = pep;
514 goto FINISH; 570 goto FINISH;
515 /* end of insert first */ 571 /* end of insert first */
516 } 572 }
517 573
518 if (after == NULL) 574 if (after == NULL)
519 { 575 {
520 /* insert last: find the end, free everything after it */ 576 /* insert last: find the end, free everything after it */
521 freeFL (before->link, 1); 577 freeFL (before->link, 1);
522 before->link = pep; 578 before->link = pep;
523 goto FINISH; 579 goto FINISH;
524 } 580 }
525 581
526 /* ok, we are filling the middle between two fragments; insert. If 582 /* ok, we are filling the middle between two fragments; insert. If
527 there is anything else in the middle, it can be dropped as we're 583 there is anything else in the middle, it can be dropped as we're
528 bigger & cover that area as well */ 584 bigger & cover that area as well */
529 /* free everything between before and after */ 585 /* free everything between before and after */
530 pos = before->link; 586 pos = before->link;
531 while (pos != after) 587 while (pos != after)
532 { 588 {
533 tmp = pos->link; 589 tmp = pos->link;
534 GNUNET_free (pos->frag); 590 GNUNET_free (pos->frag);
535 GNUNET_free (pos); 591 GNUNET_free (pos);
536 pos = tmp; 592 pos = tmp;
537 } 593 }
538 before->link = pep; 594 before->link = pep;
539 pep->link = after; 595 pep->link = after;
540 596
541FINISH: 597 FINISH:
542 entry->ttl = GNUNET_get_time () + DEFRAGMENTATION_TIMEOUT; 598 entry->ttl = GNUNET_get_time () + DEFRAGMENTATION_TIMEOUT;
543 checkComplete (entry); 599 checkComplete (entry);
544 return GNUNET_OK; 600 return GNUNET_OK;
545} 601}
546 602
547/** 603/**
@@ -553,59 +609,59 @@ FINISH:
553 */ 609 */
554static int 610static int
555processFragment (const GNUNET_PeerIdentity * sender, 611processFragment (const GNUNET_PeerIdentity * sender,
556 const GNUNET_MessageHeader * frag) 612 const GNUNET_MessageHeader * frag)
557{ 613{
558 unsigned int hash; 614 unsigned int hash;
559 FC *smf; 615 FC *smf;
560 616
561 if (ntohs (frag->size) < sizeof (P2P_fragmentation_MESSAGE)) 617 if (ntohs (frag->size) < sizeof (P2P_fragmentation_MESSAGE))
562 return GNUNET_SYSERR; 618 return GNUNET_SYSERR;
563 619
564 GNUNET_mutex_lock (defragCacheLock); 620 GNUNET_mutex_lock (defragCacheLock);
565 hash = sender->hashPubKey.bits[0] % DEFRAG_BUCKET_COUNT; 621 hash = sender->hashPubKey.bits[0] % DEFRAG_BUCKET_COUNT;
566 smf = defragmentationCache[hash]; 622 smf = defragmentationCache[hash];
567 while (smf != NULL) 623 while (smf != NULL)
568 { 624 {
569 if (GNUNET_OK == 625 if (GNUNET_OK ==
570 tryJoin (smf, sender, (P2P_fragmentation_MESSAGE *) frag)) 626 tryJoin (smf, sender, (P2P_fragmentation_MESSAGE *) frag))
571 { 627 {
572 GNUNET_mutex_unlock (defragCacheLock); 628 GNUNET_mutex_unlock (defragCacheLock);
573 return GNUNET_OK; 629 return GNUNET_OK;
574 } 630 }
575 if (0 == memcmp (sender, &smf->sender, sizeof (GNUNET_PeerIdentity))) 631 if (0 == memcmp (sender, &smf->sender, sizeof (GNUNET_PeerIdentity)))
576 { 632 {
577 freeFL (smf->head, 1); 633 freeFL (smf->head, 1);
578 break; 634 break;
579 } 635 }
580 smf = smf->next; 636 smf = smf->next;
581 } 637 }
582 if (smf == NULL) 638 if (smf == NULL)
583 { 639 {
584 smf = GNUNET_malloc (sizeof (FC)); 640 smf = GNUNET_malloc (sizeof (FC));
585 smf->next = defragmentationCache[hash]; 641 smf->next = defragmentationCache[hash];
586 defragmentationCache[hash] = smf; 642 defragmentationCache[hash] = smf;
587 smf->ttl = GNUNET_get_time () + DEFRAGMENTATION_TIMEOUT; 643 smf->ttl = GNUNET_get_time () + DEFRAGMENTATION_TIMEOUT;
588 smf->sender = *sender; 644 smf->sender = *sender;
589 } 645 }
590 smf->id = ntohl (((P2P_fragmentation_MESSAGE *) frag)->id); 646 smf->id = ntohl (((P2P_fragmentation_MESSAGE *) frag)->id);
591 smf->head = GNUNET_malloc (sizeof (FL)); 647 smf->head = GNUNET_malloc (sizeof (FL));
592 smf->head->link = NULL; 648 smf->head->link = NULL;
593 smf->head->frag = GNUNET_malloc (ntohs (frag->size)); 649 smf->head->frag = GNUNET_malloc (ntohs (frag->size));
594 memcpy (smf->head->frag, frag, ntohs (frag->size)); 650 memcpy (smf->head->frag, frag, ntohs (frag->size));
595 651
596 GNUNET_mutex_unlock (defragCacheLock); 652 GNUNET_mutex_unlock (defragCacheLock);
597 return GNUNET_OK; 653 return GNUNET_OK;
598} 654}
599 655
600typedef struct 656typedef struct
601{ 657{
602 GNUNET_PeerIdentity sender; 658 GNUNET_PeerIdentity sender;
603 /* maximums size of each fragment */ 659 /* maximums size of each fragment */
604 unsigned short mtu; 660 unsigned short mtu;
605 /** how long is this message part expected to be? */ 661 /** how long is this message part expected to be? */
606 unsigned short len; 662 unsigned short len;
607 /** when did we intend to transmit? */ 663 /** when did we intend to transmit? */
608 GNUNET_CronTime transmissionTime; 664 GNUNET_CronTime transmissionTime;
609} FragmentBMC; 665} FragmentBMC;
610 666
611/** 667/**
@@ -624,57 +680,57 @@ typedef struct
624static int 680static int
625fragmentBMC (void *buf, void *cls, unsigned short len) 681fragmentBMC (void *buf, void *cls, unsigned short len)
626{ 682{
627 FragmentBMC *ctx = cls; 683 FragmentBMC *ctx = cls;
628 static int idGen = 0; 684 static int idGen = 0;
629 P2P_fragmentation_MESSAGE *frag; 685 P2P_fragmentation_MESSAGE *frag;
630 unsigned int pos; 686 unsigned int pos;
631 int id; 687 int id;
632 unsigned short mlen; 688 unsigned short mlen;
633 689
634 if ((len < ctx->mtu) || (buf == NULL)) 690 if ((len < ctx->mtu) || (buf == NULL))
635 { 691 {
636 GNUNET_free (ctx); 692 GNUNET_free (ctx);
637 return GNUNET_SYSERR; 693 return GNUNET_SYSERR;
638 } 694 }
639 if (stats != NULL) 695 if (stats != NULL)
640 stats->change (stat_fragmented, 1); 696 stats->change (stat_fragmented, 1);
641 id = (idGen++) + GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 512); 697 id = (idGen++) + GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 512);
642 /* write first fragment to buf */ 698 /* write first fragment to buf */
643 frag = (P2P_fragmentation_MESSAGE *) buf; 699 frag = (P2P_fragmentation_MESSAGE *) buf;
644 frag->header.size = htons (len); 700 frag->header.size = htons (len);
645 frag->header.type = htons (GNUNET_P2P_PROTO_MESSAGE_FRAGMENT); 701 frag->header.type = htons (GNUNET_P2P_PROTO_MESSAGE_FRAGMENT);
646 frag->id = id; 702 frag->id = id;
647 frag->off = htons (0); 703 frag->off = htons (0);
648 frag->len = htons (ctx->len); 704 frag->len = htons (ctx->len);
649 memcpy (&frag[1], &ctx[1], len - sizeof (P2P_fragmentation_MESSAGE)); 705 memcpy (&frag[1], &ctx[1], len - sizeof (P2P_fragmentation_MESSAGE));
650 706
651 /* create remaining fragments, add to queue! */ 707 /* create remaining fragments, add to queue! */
652 pos = len - sizeof (P2P_fragmentation_MESSAGE); 708 pos = len - sizeof (P2P_fragmentation_MESSAGE);
653 frag = GNUNET_malloc (ctx->mtu); 709 frag = GNUNET_malloc (ctx->mtu);
654 while (pos < ctx->len) 710 while (pos < ctx->len)
655 { 711 {
656 mlen = sizeof (P2P_fragmentation_MESSAGE) + ctx->len - pos; 712 mlen = sizeof (P2P_fragmentation_MESSAGE) + ctx->len - pos;
657 if (mlen > ctx->mtu) 713 if (mlen > ctx->mtu)
658 mlen = ctx->mtu; 714 mlen = ctx->mtu;
659 GNUNET_GE_ASSERT (NULL, mlen > sizeof (P2P_fragmentation_MESSAGE)); 715 GNUNET_GE_ASSERT (NULL, mlen > sizeof (P2P_fragmentation_MESSAGE));
660 frag->header.size = htons (mlen); 716 frag->header.size = htons (mlen);
661 frag->header.type = htons (GNUNET_P2P_PROTO_MESSAGE_FRAGMENT); 717 frag->header.type = htons (GNUNET_P2P_PROTO_MESSAGE_FRAGMENT);
662 frag->id = id; 718 frag->id = id;
663 frag->off = htons (pos); 719 frag->off = htons (pos);
664 frag->len = htons (ctx->len); 720 frag->len = htons (ctx->len);
665 memcpy (&frag[1], 721 memcpy (&frag[1],
666 &((char *) (&ctx[1]))[pos], 722 &((char *) (&ctx[1]))[pos],
667 mlen - sizeof (P2P_fragmentation_MESSAGE)); 723 mlen - sizeof (P2P_fragmentation_MESSAGE));
668 coreAPI->ciphertext_send (&ctx->sender, 724 coreAPI->ciphertext_send (&ctx->sender,
669 &frag->header, 725 &frag->header,
670 GNUNET_EXTREME_PRIORITY, 726 GNUNET_EXTREME_PRIORITY,
671 ctx->transmissionTime - GNUNET_get_time ()); 727 ctx->transmissionTime - GNUNET_get_time ());
672 pos += mlen - sizeof (P2P_fragmentation_MESSAGE); 728 pos += mlen - sizeof (P2P_fragmentation_MESSAGE);
673 } 729 }
674 GNUNET_GE_ASSERT (NULL, pos == ctx->len); 730 GNUNET_GE_ASSERT (NULL, pos == ctx->len);
675 GNUNET_free (frag); 731 GNUNET_free (frag);
676 GNUNET_free (ctx); 732 GNUNET_free (ctx);
677 return GNUNET_OK; 733 return GNUNET_OK;
678} 734}
679 735
680/** 736/**
@@ -685,37 +741,37 @@ fragmentBMC (void *buf, void *cls, unsigned short len)
685 */ 741 */
686void 742void
687fragment (const GNUNET_PeerIdentity * peer, 743fragment (const GNUNET_PeerIdentity * peer,
688 unsigned int mtu, 744 unsigned int mtu,
689 unsigned int prio, 745 unsigned int prio,
690 unsigned int targetTime, 746 unsigned int targetTime,
691 unsigned int len, GNUNET_BuildMessageCallback bmc, void *bmcClosure) 747 unsigned int len, GNUNET_BuildMessageCallback bmc, void *bmcClosure)
692{ 748{
693 FragmentBMC *fbmc; 749 FragmentBMC *fbmc;
694 int xlen; 750 int xlen;
695 751
696 GNUNET_GE_ASSERT (NULL, len > mtu); 752 GNUNET_GE_ASSERT (NULL, len > mtu);
697 GNUNET_GE_ASSERT (NULL, mtu > sizeof (P2P_fragmentation_MESSAGE)); 753 GNUNET_GE_ASSERT (NULL, mtu > sizeof (P2P_fragmentation_MESSAGE));
698 fbmc = GNUNET_malloc (sizeof (FragmentBMC) + len); 754 fbmc = GNUNET_malloc (sizeof (FragmentBMC) + len);
699 fbmc->mtu = mtu; 755 fbmc->mtu = mtu;
700 fbmc->sender = *peer; 756 fbmc->sender = *peer;
701 fbmc->transmissionTime = targetTime; 757 fbmc->transmissionTime = targetTime;
702 fbmc->len = len; 758 fbmc->len = len;
703 if (bmc == NULL) 759 if (bmc == NULL)
704 { 760 {
705 memcpy (&fbmc[1], bmcClosure, len); 761 memcpy (&fbmc[1], bmcClosure, len);
706 GNUNET_free (bmcClosure); 762 GNUNET_free (bmcClosure);
707 } 763 }
708 else 764 else
709 { 765 {
710 if (GNUNET_SYSERR == bmc (&fbmc[1], bmcClosure, len)) 766 if (GNUNET_SYSERR == bmc (&fbmc[1], bmcClosure, len))
711 { 767 {
712 GNUNET_free (fbmc); 768 GNUNET_free (fbmc);
713 return; 769 return;
714 } 770 }
715 } 771 }
716 xlen = mtu - sizeof (P2P_fragmentation_MESSAGE); 772 xlen = mtu - sizeof (P2P_fragmentation_MESSAGE);
717 coreAPI->ciphertext_send_with_callback (peer, &fragmentBMC, fbmc, mtu, prio * xlen / len, /* compute new priority */ 773 coreAPI->ciphertext_send_with_callback (peer, &fragmentBMC, fbmc, mtu, prio * xlen / len, /* compute new priority */
718 targetTime); 774 targetTime);
719} 775}
720 776
721/** 777/**
@@ -724,35 +780,35 @@ fragment (const GNUNET_PeerIdentity * peer,
724GNUNET_Fragmentation_ServiceAPI * 780GNUNET_Fragmentation_ServiceAPI *
725provide_module_fragmentation (GNUNET_CoreAPIForPlugins * capi) 781provide_module_fragmentation (GNUNET_CoreAPIForPlugins * capi)
726{ 782{
727 static GNUNET_Fragmentation_ServiceAPI ret; 783 static GNUNET_Fragmentation_ServiceAPI ret;
728 int i; 784 int i;
729 785
730 coreAPI = capi; 786 coreAPI = capi;
731 stats = coreAPI->service_request ("stats"); 787 stats = coreAPI->service_request ("stats");
732 if (stats != NULL) 788 if (stats != NULL)
733 { 789 {
734 stat_defragmented = 790 stat_defragmented =
735 stats->create (gettext_noop ("# messages defragmented")); 791 stats->create (gettext_noop ("# messages defragmented"));
736 stat_fragmented = 792 stat_fragmented =
737 stats->create (gettext_noop ("# messages fragmented")); 793 stats->create (gettext_noop ("# messages fragmented"));
738 stat_discarded = stats->create (gettext_noop ("# fragments discarded")); 794 stat_discarded = stats->create (gettext_noop ("# fragments discarded"));
739 } 795 }
740 for (i = 0; i < DEFRAG_BUCKET_COUNT; i++) 796 for (i = 0; i < DEFRAG_BUCKET_COUNT; i++)
741 defragmentationCache[i] = NULL; 797 defragmentationCache[i] = NULL;
742 defragCacheLock = GNUNET_mutex_create (GNUNET_NO); 798 defragCacheLock = GNUNET_mutex_create (GNUNET_NO);
743 GNUNET_cron_add_job (coreAPI->cron, 799 GNUNET_cron_add_job (coreAPI->cron,
744 &defragmentationPurgeCron, 800 &defragmentationPurgeCron,
745 60 * GNUNET_CRON_SECONDS, 60 * GNUNET_CRON_SECONDS, 801 60 * GNUNET_CRON_SECONDS, 60 * GNUNET_CRON_SECONDS,
746 NULL); 802 NULL);
747 GNUNET_GE_LOG (capi->ectx, 803 GNUNET_GE_LOG (capi->ectx,
748 GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_REQUEST, 804 GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_REQUEST,
749 _("`%s' registering handler %d\n"), "fragmentation", 805 _("`%s' registering handler %d\n"), "fragmentation",
750 GNUNET_P2P_PROTO_MESSAGE_FRAGMENT); 806 GNUNET_P2P_PROTO_MESSAGE_FRAGMENT);
751 capi->p2p_ciphertext_handler_register (GNUNET_P2P_PROTO_MESSAGE_FRAGMENT, 807 capi->p2p_ciphertext_handler_register (GNUNET_P2P_PROTO_MESSAGE_FRAGMENT,
752 &processFragment); 808 &processFragment);
753 809
754 ret.fragment = &fragment; 810 ret.fragment = &fragment;
755 return &ret; 811 return &ret;
756} 812}
757 813
758/** 814/**
@@ -761,31 +817,31 @@ provide_module_fragmentation (GNUNET_CoreAPIForPlugins * capi)
761void 817void
762release_module_fragmentation () 818release_module_fragmentation ()
763{ 819{
764 int i; 820 int i;
765 821
766 coreAPI->p2p_ciphertext_handler_unregister 822 coreAPI->p2p_ciphertext_handler_unregister
767 (GNUNET_P2P_PROTO_MESSAGE_FRAGMENT, &processFragment); 823 (GNUNET_P2P_PROTO_MESSAGE_FRAGMENT, &processFragment);
768 GNUNET_cron_del_job (coreAPI->cron, &defragmentationPurgeCron, 824 GNUNET_cron_del_job (coreAPI->cron, &defragmentationPurgeCron,
769 60 * GNUNET_CRON_SECONDS, NULL); 825 60 * GNUNET_CRON_SECONDS, NULL);
770 for (i = 0; i < DEFRAG_BUCKET_COUNT; i++) 826 for (i = 0; i < DEFRAG_BUCKET_COUNT; i++)
771 { 827 {
772 FC *pos = defragmentationCache[i]; 828 FC *pos = defragmentationCache[i];
773 while (pos != NULL) 829 while (pos != NULL)
774 { 830 {
775 FC *next = pos->next; 831 FC *next = pos->next;
776 freeFL (pos->head, 1); 832 freeFL (pos->head, 1);
777 GNUNET_free (pos); 833 GNUNET_free (pos);
778 pos = next; 834 pos = next;
779 } 835 }
780 } 836 }
781 if (stats != NULL) 837 if (stats != NULL)
782 { 838 {
783 coreAPI->service_release (stats); 839 coreAPI->service_release (stats);
784 stats = NULL; 840 stats = NULL;
785 } 841 }
786 GNUNET_mutex_destroy (defragCacheLock); 842 GNUNET_mutex_destroy (defragCacheLock);
787 defragCacheLock = NULL; 843 defragCacheLock = NULL;
788 coreAPI = NULL; 844 coreAPI = NULL;
789} 845}
790 846
791#endif 847#endif
diff --git a/src/fragmentation/test_frag_ji.c b/src/fragmentation/test_frag_ji.c
index 8cba654ad..059994f2b 100644
--- a/src/fragmentation/test_frag_ji.c
+++ b/src/fragmentation/test_frag_ji.c
@@ -1,38 +1,55 @@
1#include "platform.h" 1#include "platform.h"
2#include "gnunet_protocols.h"
2#include "gnunet_fragmentation_lib.h" 3#include "gnunet_fragmentation_lib.h"
3 4
5struct combine{
6 struct GNUNET_FRAGMENT_Context* ctx;
7 struct GNUNET_PeerIdentity* sender;
8};
9
4void message_proc1(void *cls, const struct GNUNET_MessageHeader * msg){ 10void message_proc1(void *cls, const struct GNUNET_MessageHeader * msg){
11 fprintf(stderr, "enter into message_proc1\n");
5 12
6 struct GNUNET_MessageHeader * originalMsg = (struct GNUNET_MessageHeader *)cls; 13 struct GNUNET_MessageHeader * originalMsg = (struct GNUNET_MessageHeader *)cls;
7 if(originalMsg->size != msg->size){ 14
8 fprintf(stderr, "the received message has the different size with the sent one!"); 15 if(ntohs(originalMsg->size) != ntohs(msg->size)){
16 fprintf(stderr, "the received message has the different size with the sent one!\n");
9 } 17 }
10 if(originalMsg->type != msg->type){ 18 if(ntohs(originalMsg->type) != ntohs(msg->type)){
11 fprintf(stderr, "the received message has the different type with the sent one!"); 19 fprintf(stderr, "the received message has the different type with the sent one!\n");
12 } 20 }
13 if(memcmp(&originalMsg[1], &msg[1], originalMsg->size - sizeof(struct GNUNET_MessageHeader))){ 21 if(memcmp(msg+960, originalMsg+960, 68)){
14 fprintf(stderr, "the received message is not the sent one!"); 22 fprintf(stderr, "the received message is not the sent one!\n");
15 } 23 }
16 24
17} 25}
18 26
19void message_proc2(void *cls, const struct GNUNET_MessageHeader * msg){ 27void message_proc2(void *cls, const struct GNUNET_MessageHeader * msg){
20 struct GNUNET_FRAGMENT_Context * ctx = (struct GNUNET_FRAGMENT_Context * )cls; 28 printf("enter into message_proc2\n");
21 struct Fragment *frag; 29 struct combine * com2 = (struct combine* )cls;
22 struct GNUNET_PeerIdentity sender; 30 GNUNET_FRAGMENT_process(com2->ctx, com2->sender, msg);
23 GNUNET_FRAGMENT_process(ctx, &sender, msg);
24} 31}
25 32
26int 33int
27main(int argc, char * argv[]){ 34main(int argc, char * argv[]){
28 35
36 uint16_t mtu = 512;
29 struct GNUNET_FRAGMENT_Context * ctx; 37 struct GNUNET_FRAGMENT_Context * ctx;
30 struct GNUNET_MessageHeader *msg; 38 struct GNUNET_MessageHeader *msg = GNUNET_malloc(sizeof(struct GNUNET_MessageHeader)+2*mtu);
31 ctx = GNUNET_FRAGMENT_context_create(stats, message_proc1, msg); 39 ctx = GNUNET_FRAGMENT_context_create(NULL, message_proc1, msg);
32 msg->size = sizeof(struct GNUNET_MessageHeader)+2*mtu; 40 msg->size = htons(sizeof(struct GNUNET_MessageHeader)+2*mtu);
33 msg->type = GNUNET_MESSAGE_TYPE_HELLO; 41 msg->type = htons(GNUNET_MESSAGE_TYPE_HELLO);
34 memcpy(&msg[1], 5, 2*mtu); 42 struct GNUNET_PeerIdentity *sender;
35 GNUNET_FRAGMENT_fragment(msg, mtu, message_proc2, ctx); 43 sender = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity));
44
45 memset(sender, 9, sizeof(struct GNUNET_PeerIdentity));
36 46
47 memset(&msg[1], 5, 2*mtu);
48 struct combine *com;
49 com = GNUNET_malloc(sizeof(struct combine));
50 com->ctx = ctx;
51 com->sender = sender;
52 GNUNET_FRAGMENT_fragment(msg, mtu, message_proc2, com);
53 GNUNET_free(msg);
37 return 0; 54 return 0;
38} 55}