2 This file is part of GNUnet
3 (C) 2004, 2009 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
21 * @file fragmentation/test_fragmentation.c
22 * @brief test for fragmentation.c
23 * @author Christian Grothoff
27 * Testcase for defragmentation code.
28 * We have testcases for:
29 * - 2 fragments, aligned, [0,16),[16,32)
30 * - n (50) fragments, [i*16,(i+1)*16)
31 * - n (50) fragments, [0,i*16) + [50*16,51*16)
32 * - n (100) fragments, inserted in interleaved order (holes in sequence)
36 * - multiple entries in GNUNET_hash-list
37 * - id collisions in GNUNET_hash-list
41 #include "gnunet_fragmentation_lib.h"
45 /* -- to speed up the testcases -- */
46 #define DEFRAGMENTATION_TIMEOUT (1 * GNUNET_CRON_SECONDS)
49 static GNUNET_PeerIdentity mySender;
51 static unsigned short myMsgLen;
53 /* static buffers to avoid lots of malloc/free */
54 static char masterBuffer[65536];
55 static char resultBuffer[65536];
58 handleHelper (const GNUNET_PeerIdentity * sender,
60 const unsigned int len, int wasEncrypted, GNUNET_TSession * ts)
62 GNUNET_GE_ASSERT (NULL,
63 0 == memcmp (sender, &mySender,
64 sizeof (GNUNET_PeerIdentity)));
66 memcpy (resultBuffer, msg, len);
71 * Wait long enough to force all fragments to timeout.
76 GNUNET_thread_sleep (DEFRAGMENTATION_TIMEOUT * 2);
77 defragmentationPurgeCron (NULL);
81 * Create a fragment. The data-portion will be filled
82 * with a sequence of numbers from start+id to start+len-1+id.
84 * @param pep pointer to the ethernet frame/buffer
85 * @param ip pointer to the ip-header
86 * @param start starting-offset
87 * @param length of the data portion
88 * @param id the identity of the fragment
90 static GNUNET_MessageHeader *
91 makeFragment (unsigned short start,
92 unsigned short size, unsigned short tot, int id)
94 P2P_fragmentation_MESSAGE *frag;
97 frag = (P2P_fragmentation_MESSAGE *) masterBuffer;
98 frag->id = htonl (id);
99 frag->off = htons (start);
100 frag->len = htons (tot);
101 frag->header.size = htons (sizeof (P2P_fragmentation_MESSAGE) + size);
103 for (i = 0; i < size; i++)
104 ((char *) &frag[1])[i] = (char) i + id + start;
105 return &frag->header;
109 * Check that the packet received is what we expected to
111 * @param id the expected id
112 * @param len the expected length
115 checkPacket (int id, unsigned int len)
119 GNUNET_GE_ASSERT (NULL, myMsg != NULL);
120 GNUNET_GE_ASSERT (NULL, myMsgLen == len);
121 for (i = 0; i < len; i++)
122 GNUNET_GE_ASSERT (NULL, myMsg[i] == (char) (i + id));
128 /* **************** actual testcases ***************** */
131 testSimpleFragment ()
133 GNUNET_MessageHeader *pep;
135 pep = makeFragment (0, 16, 32, 42);
136 processFragment (&mySender, pep);
137 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
138 pep = makeFragment (16, 16, 32, 42);
139 processFragment (&mySender, pep);
140 checkPacket (42, 32);
144 testSimpleFragmentTimeout ()
146 GNUNET_MessageHeader *pep;
148 pep = makeFragment (0, 16, 32, 42);
149 processFragment (&mySender, pep);
150 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
152 pep = makeFragment (16, 16, 32, 42);
153 processFragment (&mySender, pep);
154 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
155 pep = makeFragment (0, 16, 32, 42);
156 processFragment (&mySender, pep);
157 checkPacket (42, 32);
161 testSimpleFragmentReverse ()
163 GNUNET_MessageHeader *pep;
165 pep = makeFragment (16, 16, 32, 42);
166 processFragment (&mySender, pep);
167 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
168 pep = makeFragment (0, 16, 32, 42);
169 processFragment (&mySender, pep);
170 checkPacket (42, 32);
176 GNUNET_MessageHeader *pep;
179 for (i = 0; i < 50; i++)
181 pep = makeFragment (i * 16, 16, 51 * 16, 42);
182 processFragment (&mySender, pep);
183 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
185 pep = makeFragment (50 * 16, 16, 51 * 16, 42);
186 processFragment (&mySender, pep);
187 checkPacket (42, 51 * 16);
191 testManyFragmentsMegaLarge ()
193 GNUNET_MessageHeader *pep;
196 for (i = 0; i < 4000; i++)
198 pep = makeFragment (i * 16, 16, 4001 * 16, 42);
199 processFragment (&mySender, pep);
200 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
202 pep = makeFragment (4000 * 16, 16, 4001 * 16, 42);
203 processFragment (&mySender, pep);
204 checkPacket (42, 4001 * 16);
208 testLastFragmentEarly ()
210 GNUNET_MessageHeader *pep;
213 for (i = 0; i < 5; i++)
215 pep = makeFragment (i * 16, 8, 6 * 16 + 8, 42);
216 processFragment (&mySender, pep);
217 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
219 pep = makeFragment (5 * 16, 24, 6 * 16 + 8, 42);
220 processFragment (&mySender, pep);
221 for (i = 0; i < 5; i++)
223 pep = makeFragment (i * 16 + 8, 8, 6 * 16 + 8, 42);
224 processFragment (&mySender, pep);
226 checkPacket (42, 6 * 16 + 8);
230 testManyInterleavedFragments ()
232 GNUNET_MessageHeader *pep;
235 for (i = 0; i < 50; i++)
237 pep = makeFragment (i * 16, 8, 51 * 16 + 8, 42);
238 processFragment (&mySender, pep);
239 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
241 for (i = 0; i < 50; i++)
243 pep = makeFragment (i * 16 + 8, 8, 51 * 16 + 8, 42);
244 processFragment (&mySender, pep);
245 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
247 pep = makeFragment (50 * 16, 24, 51 * 16 + 8, 42);
248 processFragment (&mySender, pep);
249 checkPacket (42, 51 * 16 + 8);
253 testManyInterleavedOverlappingFragments ()
255 GNUNET_MessageHeader *pep;
258 for (i = 0; i < 50; i++)
260 pep = makeFragment (i * 32, 16, 51 * 32, 42);
261 processFragment (&mySender, pep);
262 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
264 for (i = 0; i < 50; i++)
266 pep = makeFragment (i * 32 + 8, 24, 51 * 32, 42);
267 processFragment (&mySender, pep);
268 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
270 pep = makeFragment (50 * 32, 32, 51 * 32, 42);
271 processFragment (&mySender, pep);
272 checkPacket (42, 51 * 32);
276 testManyOverlappingFragments ()
278 GNUNET_MessageHeader *pep;
281 for (i = 0; i < 50; i++)
283 pep = makeFragment (0, i * 16 + 16, 51 * 16, 42);
284 processFragment (&mySender, pep);
285 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
287 pep = makeFragment (50 * 16, 16, 51 * 16, 42);
288 processFragment (&mySender, pep);
289 checkPacket (42, 51 * 16);
293 testManyOverlappingFragmentsTimeout ()
295 GNUNET_MessageHeader *pep;
298 for (i = 0; i < 50; i++)
300 pep = makeFragment (0, i * 16 + 16, 51 * 16 + 8, 42);
301 processFragment (&mySender, pep);
302 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
305 pep = makeFragment (50 * 16, 24, 51 * 16 + 8, 42);
306 processFragment (&mySender, pep);
307 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
308 for (i = 0; i < 50; i++)
310 pep = makeFragment (0, i * 16 + 16, 51 * 16 + 8, 42);
311 processFragment (&mySender, pep);
313 checkPacket (42, 51 * 16 + 8);
317 testManyFragmentsMultiId ()
319 GNUNET_MessageHeader *pep;
323 for (i = 0; i < 50; i++)
325 for (id = 0; id < DEFRAG_BUCKET_COUNT; id++)
327 pep = makeFragment (i * 16, 16, 51 * 16, id + 5);
328 mySender.hashPubKey.bits[0] = id;
329 processFragment (&mySender, pep);
330 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
333 for (id = 0; id < DEFRAG_BUCKET_COUNT; id++)
335 pep = makeFragment (50 * 16, 16, 51 * 16, id + 5);
336 mySender.hashPubKey.bits[0] = id;
337 processFragment (&mySender, pep);
338 checkPacket (id + 5, 51 * 16);
343 testManyFragmentsMultiIdCollisions ()
345 GNUNET_MessageHeader *pep;
349 for (i = 0; i < 5; i++)
351 for (id = 0; id < DEFRAG_BUCKET_COUNT * 4; id++)
353 pep = makeFragment (i * 16, 16, 6 * 16, id + 5);
354 mySender.hashPubKey.bits[0] = id;
355 processFragment (&mySender, pep);
356 GNUNET_GE_ASSERT (NULL, myMsg == NULL);
359 for (id = 0; id < DEFRAG_BUCKET_COUNT * 4; id++)
361 pep = makeFragment (5 * 16, 16, 6 * 16, id + 5);
362 mySender.hashPubKey.bits[0] = id;
363 processFragment (&mySender, pep);
364 checkPacket (id + 5, 6 * 16);
368 /* ************* driver ****************** */
371 p2p_register_handler (const unsigned short type,
372 GNUNET_P2PRequestHandler callback)
378 p2p_unregister_handler (const unsigned short type,
379 GNUNET_P2PRequestHandler callback)
386 request_service (const char *name)
394 main (int argc, char *argv[])
396 fprintf (stderr, "WARNING: testcase not yet ported to new API.\n");
398 GNUNET_CoreAPIForPlugins capi;
400 memset (&capi, 0, sizeof (GNUNET_CoreAPIForPlugins));
401 capi.cron = GNUNET_cron_create (NULL);
402 capi.loopback_send = &handleHelper;
403 capi.service_request = &request_service;
404 capi.p2p_ciphertext_handler_register = &p2p_register_handler;
405 capi.p2p_ciphertext_handler_unregister = &p2p_unregister_handler;
406 provide_module_fragmentation (&capi);
408 fprintf (stderr, ".");
409 testSimpleFragment ();
410 fprintf (stderr, ".");
411 testSimpleFragmentTimeout ();
412 fprintf (stderr, ".");
413 testSimpleFragmentReverse ();
414 fprintf (stderr, ".");
415 testManyFragments ();
416 fprintf (stderr, ".");
417 testManyFragmentsMegaLarge ();
418 fprintf (stderr, ".");
419 testManyFragmentsMultiId ();
420 fprintf (stderr, ".");
422 testManyInterleavedFragments ();
423 fprintf (stderr, ".");
424 testManyInterleavedOverlappingFragments ();
425 fprintf (stderr, ".");
426 testManyOverlappingFragments ();
427 fprintf (stderr, ".");
428 testManyOverlappingFragmentsTimeout ();
429 fprintf (stderr, ".");
430 testLastFragmentEarly ();
431 fprintf (stderr, ".");
432 testManyFragmentsMultiIdCollisions ();
433 fprintf (stderr, ".");
434 release_module_fragmentation ();
435 fprintf (stderr, "\n");
436 GNUNET_cron_destroy (capi.cron);
438 return 0; /* testcase passed */