lnk
[oweals/gnunet.git] / src / fragmentation / test_fragmentation.c
1 /*
2      This file is part of GNUnet
3      (C) 2004, 2009 Christian Grothoff (and other contributing authors)
4
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 2, or (at your
8      option) any later version.
9
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.
14
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.
19 */
20 /**
21  * @file fragmentation/test_fragmentation.c
22  * @brief test for fragmentation.c
23  * @author Christian Grothoff
24  */
25
26 /**
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)
33  * - holes in sequence
34  * - other overlaps
35  * - timeouts
36  * - multiple entries in GNUNET_hash-list
37  * - id collisions in GNUNET_hash-list
38  */
39
40 #include "platform.h"
41 #include "gnunet_fragmentation_lib.h"
42
43 #if 0
44
45 /* -- to speed up the testcases -- */
46 #define DEFRAGMENTATION_TIMEOUT (1 * GNUNET_CRON_SECONDS)
47
48
49 static GNUNET_PeerIdentity mySender;
50 static char *myMsg;
51 static unsigned short myMsgLen;
52
53 /* static buffers to avoid lots of malloc/free */
54 static char masterBuffer[65536];
55 static char resultBuffer[65536];
56
57 static void
58 handleHelper (const GNUNET_PeerIdentity * sender,
59               const char *msg,
60               const unsigned int len, int wasEncrypted, GNUNET_TSession * ts)
61 {
62   GNUNET_GE_ASSERT (NULL,
63                     0 == memcmp (sender, &mySender,
64                                  sizeof (GNUNET_PeerIdentity)));
65   myMsg = resultBuffer;
66   memcpy (resultBuffer, msg, len);
67   myMsgLen = len;
68 }
69
70 /**
71  * Wait long enough to force all fragments to timeout.
72  */
73 static void
74 makeTimeout ()
75 {
76   GNUNET_thread_sleep (DEFRAGMENTATION_TIMEOUT * 2);
77   defragmentationPurgeCron (NULL);
78 }
79
80 /**
81  * Create a fragment. The data-portion will be filled
82  * with a sequence of numbers from start+id to start+len-1+id.
83  *
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
89  */
90 static GNUNET_MessageHeader *
91 makeFragment (unsigned short start,
92               unsigned short size, unsigned short tot, int id)
93 {
94   P2P_fragmentation_MESSAGE *frag;
95   int i;
96
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);
102
103   for (i = 0; i < size; i++)
104     ((char *) &frag[1])[i] = (char) i + id + start;
105   return &frag->header;
106 }
107
108 /**
109  * Check that the packet received is what we expected to
110  * get.
111  * @param id the expected id
112  * @param len the expected length
113  */
114 static void
115 checkPacket (int id, unsigned int len)
116 {
117   int i;
118
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));
123   myMsgLen = 0;
124   myMsg = NULL;
125 }
126
127
128 /* **************** actual testcases ***************** */
129
130 static void
131 testSimpleFragment ()
132 {
133   GNUNET_MessageHeader *pep;
134
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);
141 }
142
143 static void
144 testSimpleFragmentTimeout ()
145 {
146   GNUNET_MessageHeader *pep;
147
148   pep = makeFragment (0, 16, 32, 42);
149   processFragment (&mySender, pep);
150   GNUNET_GE_ASSERT (NULL, myMsg == NULL);
151   makeTimeout ();
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);
158 }
159
160 static void
161 testSimpleFragmentReverse ()
162 {
163   GNUNET_MessageHeader *pep;
164
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);
171 }
172
173 static void
174 testManyFragments ()
175 {
176   GNUNET_MessageHeader *pep;
177   int i;
178
179   for (i = 0; i < 50; i++)
180     {
181       pep = makeFragment (i * 16, 16, 51 * 16, 42);
182       processFragment (&mySender, pep);
183       GNUNET_GE_ASSERT (NULL, myMsg == NULL);
184     }
185   pep = makeFragment (50 * 16, 16, 51 * 16, 42);
186   processFragment (&mySender, pep);
187   checkPacket (42, 51 * 16);
188 }
189
190 static void
191 testManyFragmentsMegaLarge ()
192 {
193   GNUNET_MessageHeader *pep;
194   int i;
195
196   for (i = 0; i < 4000; i++)
197     {
198       pep = makeFragment (i * 16, 16, 4001 * 16, 42);
199       processFragment (&mySender, pep);
200       GNUNET_GE_ASSERT (NULL, myMsg == NULL);
201     }
202   pep = makeFragment (4000 * 16, 16, 4001 * 16, 42);
203   processFragment (&mySender, pep);
204   checkPacket (42, 4001 * 16);
205 }
206
207 static void
208 testLastFragmentEarly ()
209 {
210   GNUNET_MessageHeader *pep;
211   int i;
212
213   for (i = 0; i < 5; i++)
214     {
215       pep = makeFragment (i * 16, 8, 6 * 16 + 8, 42);
216       processFragment (&mySender, pep);
217       GNUNET_GE_ASSERT (NULL, myMsg == NULL);
218     }
219   pep = makeFragment (5 * 16, 24, 6 * 16 + 8, 42);
220   processFragment (&mySender, pep);
221   for (i = 0; i < 5; i++)
222     {
223       pep = makeFragment (i * 16 + 8, 8, 6 * 16 + 8, 42);
224       processFragment (&mySender, pep);
225     }
226   checkPacket (42, 6 * 16 + 8);
227 }
228
229 static void
230 testManyInterleavedFragments ()
231 {
232   GNUNET_MessageHeader *pep;
233   int i;
234
235   for (i = 0; i < 50; i++)
236     {
237       pep = makeFragment (i * 16, 8, 51 * 16 + 8, 42);
238       processFragment (&mySender, pep);
239       GNUNET_GE_ASSERT (NULL, myMsg == NULL);
240     }
241   for (i = 0; i < 50; i++)
242     {
243       pep = makeFragment (i * 16 + 8, 8, 51 * 16 + 8, 42);
244       processFragment (&mySender, pep);
245       GNUNET_GE_ASSERT (NULL, myMsg == NULL);
246     }
247   pep = makeFragment (50 * 16, 24, 51 * 16 + 8, 42);
248   processFragment (&mySender, pep);
249   checkPacket (42, 51 * 16 + 8);
250 }
251
252 static void
253 testManyInterleavedOverlappingFragments ()
254 {
255   GNUNET_MessageHeader *pep;
256   int i;
257
258   for (i = 0; i < 50; i++)
259     {
260       pep = makeFragment (i * 32, 16, 51 * 32, 42);
261       processFragment (&mySender, pep);
262       GNUNET_GE_ASSERT (NULL, myMsg == NULL);
263     }
264   for (i = 0; i < 50; i++)
265     {
266       pep = makeFragment (i * 32 + 8, 24, 51 * 32, 42);
267       processFragment (&mySender, pep);
268       GNUNET_GE_ASSERT (NULL, myMsg == NULL);
269     }
270   pep = makeFragment (50 * 32, 32, 51 * 32, 42);
271   processFragment (&mySender, pep);
272   checkPacket (42, 51 * 32);
273 }
274
275 static void
276 testManyOverlappingFragments ()
277 {
278   GNUNET_MessageHeader *pep;
279   int i;
280
281   for (i = 0; i < 50; i++)
282     {
283       pep = makeFragment (0, i * 16 + 16, 51 * 16, 42);
284       processFragment (&mySender, pep);
285       GNUNET_GE_ASSERT (NULL, myMsg == NULL);
286     }
287   pep = makeFragment (50 * 16, 16, 51 * 16, 42);
288   processFragment (&mySender, pep);
289   checkPacket (42, 51 * 16);
290 }
291
292 static void
293 testManyOverlappingFragmentsTimeout ()
294 {
295   GNUNET_MessageHeader *pep;
296   int i;
297
298   for (i = 0; i < 50; i++)
299     {
300       pep = makeFragment (0, i * 16 + 16, 51 * 16 + 8, 42);
301       processFragment (&mySender, pep);
302       GNUNET_GE_ASSERT (NULL, myMsg == NULL);
303     }
304   makeTimeout ();
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++)
309     {
310       pep = makeFragment (0, i * 16 + 16, 51 * 16 + 8, 42);
311       processFragment (&mySender, pep);
312     }
313   checkPacket (42, 51 * 16 + 8);
314 }
315
316 static void
317 testManyFragmentsMultiId ()
318 {
319   GNUNET_MessageHeader *pep;
320   int i;
321   int id;
322
323   for (i = 0; i < 50; i++)
324     {
325       for (id = 0; id < DEFRAG_BUCKET_COUNT; id++)
326         {
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);
331         }
332     }
333   for (id = 0; id < DEFRAG_BUCKET_COUNT; id++)
334     {
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);
339     }
340 }
341
342 static void
343 testManyFragmentsMultiIdCollisions ()
344 {
345   GNUNET_MessageHeader *pep;
346   int i;
347   int id;
348
349   for (i = 0; i < 5; i++)
350     {
351       for (id = 0; id < DEFRAG_BUCKET_COUNT * 4; id++)
352         {
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);
357         }
358     }
359   for (id = 0; id < DEFRAG_BUCKET_COUNT * 4; id++)
360     {
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);
365     }
366 }
367
368 /* ************* driver ****************** */
369
370 static int
371 p2p_register_handler (const unsigned short type,
372                       GNUNET_P2PRequestHandler callback)
373 {
374   return GNUNET_OK;
375 }
376
377 static int
378 p2p_unregister_handler (const unsigned short type,
379                         GNUNET_P2PRequestHandler callback)
380 {
381   return GNUNET_OK;
382 }
383
384
385 static void *
386 request_service (const char *name)
387 {
388   return NULL;
389 }
390
391 #endif
392
393 int
394 main (int argc, char *argv[])
395 {
396   fprintf (stderr, "WARNING: testcase not yet ported to new API.\n");
397 #if 0
398   GNUNET_CoreAPIForPlugins capi;
399
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);
407
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, ".");
421
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);
437 #endif
438   return 0;                     /* testcase passed */
439 }