regex profiler cleanup
[oweals/gnunet.git] / src / namestore / test_namestore_api_zone_iteration_stop.c
1 /*
2      This file is part of GNUnet.
3      (C) 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 3, 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 namestore/test_namestore_api_zone_iteration.c
22  * @brief testcase for zone iteration functionality: iterate of a specific zone
23  */
24 #include "platform.h"
25 #include "gnunet_common.h"
26 #include "gnunet_testing_lib-new.h"
27 #include "gnunet_namestore_service.h"
28 #include "namestore.h"
29
30
31 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 150)
32
33 static struct GNUNET_NAMESTORE_Handle * nsh;
34
35 static GNUNET_SCHEDULER_TaskIdentifier endbadly_task;
36
37 static GNUNET_SCHEDULER_TaskIdentifier stopiteration_task;
38
39 static struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
40
41 static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
42
43 static struct GNUNET_HashCode zone;
44
45 static struct GNUNET_CRYPTO_RsaPrivateKey * privkey2;
46
47 static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey2;
48
49 static struct GNUNET_HashCode zone2;
50
51 static struct GNUNET_NAMESTORE_ZoneIterator *zi;
52
53 static int res;
54
55 static int returned_records;
56
57 static struct GNUNET_CRYPTO_RsaSignature *sig_1;
58
59 static char * s_name_1;
60
61 static struct GNUNET_NAMESTORE_RecordData *s_rd_1;
62
63 static struct GNUNET_CRYPTO_RsaSignature *sig_2;
64
65 static char * s_name_2;
66
67 static struct GNUNET_NAMESTORE_RecordData *s_rd_2;
68
69 static struct GNUNET_CRYPTO_RsaSignature *sig_3;
70
71 static char * s_name_3;
72
73 static struct GNUNET_NAMESTORE_RecordData *s_rd_3;
74
75
76 /**
77  * Re-establish the connection to the service.
78  *
79  * @param cls handle to use to re-connect.
80  * @param tc scheduler context
81  */
82 static void
83 endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
84 {
85   if (stopiteration_task != GNUNET_SCHEDULER_NO_TASK)
86   {
87     GNUNET_SCHEDULER_cancel (stopiteration_task);
88     stopiteration_task = GNUNET_SCHEDULER_NO_TASK;
89   }
90   if (nsh != NULL)
91     GNUNET_NAMESTORE_disconnect (nsh);
92   nsh = NULL;
93   GNUNET_free_non_null(sig_1);
94   GNUNET_free_non_null(sig_2);
95   GNUNET_free_non_null(sig_3);
96   GNUNET_free_non_null(s_name_1);
97   GNUNET_free_non_null(s_name_2);
98   GNUNET_free_non_null(s_name_3);
99   if (s_rd_1 != NULL)
100   {
101     GNUNET_free ((void *)s_rd_1->data);
102     GNUNET_free (s_rd_1);
103   }
104   if (s_rd_2 != NULL)
105   {
106     GNUNET_free ((void *)s_rd_2->data);
107     GNUNET_free (s_rd_2);
108   }
109   if (s_rd_3 != NULL)
110   {
111     GNUNET_free ((void *)s_rd_3->data);
112     GNUNET_free (s_rd_3);
113   }
114   if (privkey != NULL)
115     GNUNET_CRYPTO_rsa_key_free (privkey);
116   privkey = NULL;
117
118   if (privkey2 != NULL)
119     GNUNET_CRYPTO_rsa_key_free (privkey2);
120   privkey2 = NULL;
121   res = 1;
122 }
123
124
125 static void
126 end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
127 {
128   if (stopiteration_task != GNUNET_SCHEDULER_NO_TASK)
129   {
130     GNUNET_SCHEDULER_cancel (stopiteration_task);
131     stopiteration_task = GNUNET_SCHEDULER_NO_TASK;
132   }
133
134   if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
135   {
136     GNUNET_SCHEDULER_cancel (endbadly_task);
137     endbadly_task = GNUNET_SCHEDULER_NO_TASK;
138   }
139   if (privkey != NULL)
140     GNUNET_CRYPTO_rsa_key_free (privkey);
141   privkey = NULL;
142   if (privkey2 != NULL)
143     GNUNET_CRYPTO_rsa_key_free (privkey2);
144   privkey2 = NULL;
145
146   GNUNET_free (sig_1);
147   GNUNET_free (sig_2);
148   GNUNET_free (sig_3);
149   GNUNET_free (s_name_1);
150   GNUNET_free (s_name_2);
151   GNUNET_free (s_name_3);
152   if (s_rd_1 != NULL)
153   {
154     GNUNET_free ((void *)s_rd_1->data);
155     GNUNET_free (s_rd_1);
156   }
157   if (s_rd_2 != NULL)
158   {
159     GNUNET_free ((void *)s_rd_2->data);
160     GNUNET_free (s_rd_2);
161   }
162   if (s_rd_3 != NULL)
163   {
164     GNUNET_free ((void *)s_rd_3->data);
165     GNUNET_free (s_rd_3);
166   }
167   if (nsh != NULL)
168     GNUNET_NAMESTORE_disconnect (nsh);
169   nsh = NULL;
170   if (returned_records == 1)
171     res = 0;
172   else
173     res = 1;
174
175 }
176
177
178 static void
179 zone_proc (void *cls,
180            const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
181            struct GNUNET_TIME_Absolute expire,
182            const char *name,
183            unsigned int rd_count,
184            const struct GNUNET_NAMESTORE_RecordData *rd,
185            const struct GNUNET_CRYPTO_RsaSignature *signature)
186 {
187   int failed = GNUNET_NO;
188
189   if ((zone_key == NULL) &&  (name == NULL))
190   {
191     GNUNET_break (3 == returned_records);
192     if (3 == returned_records)
193       res = 0;
194     else
195       res = 1;
196
197     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received last result, iteration done after receing %u results\n",returned_records );
198     GNUNET_SCHEDULER_add_now (&end, NULL);
199   }
200   else
201   {
202
203     /* verify signature returned from name store */
204     if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(zone_key, expire, name, rd_count, rd, signature))
205     {
206       failed = GNUNET_YES;
207       GNUNET_break (0);
208     }
209
210
211     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing results name %s \n", name);
212     if (0 == strcmp (name, s_name_1))
213     { /* name_1 */
214       if (rd_count == 1)
215       {
216         if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_1))
217         {
218           failed = GNUNET_YES;
219           GNUNET_break (0);
220         }
221       }
222       else
223       {
224         failed = GNUNET_YES;
225         GNUNET_break (0);
226       }
227       if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire, s_name_1, 1, s_rd_1, signature))
228       {
229         failed = GNUNET_YES;
230         GNUNET_break (0);
231       }
232     }
233     else if (0 == strcmp (name, s_name_2))
234     { /* name_2 */
235       if (rd_count == 1)
236       {
237         if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_2))
238         {
239           failed = GNUNET_YES;
240           GNUNET_break (0);
241         }
242       }
243       else
244       {
245         failed = GNUNET_YES;
246         GNUNET_break (0);
247       }
248
249       if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire, s_name_2, 1, s_rd_2, signature))
250       {
251         failed = GNUNET_YES;
252         GNUNET_break (0);
253       }
254     }
255     else if (0 == strcmp (name, s_name_3))
256     { /* name_3 */
257       if (rd_count == 1)
258       {
259         if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_3))
260         {
261           failed = GNUNET_YES;
262           GNUNET_break (0);
263         }
264       }
265       else
266       {
267         failed = GNUNET_YES;
268         GNUNET_break (0);
269       }
270       if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey2, expire, s_name_3, 1, s_rd_3, signature))
271       {
272         failed = GNUNET_YES;
273         GNUNET_break (0);
274       }
275     }
276     else
277     {
278       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing result failed: got name `%s'\n", name);
279       res = 1;
280       GNUNET_break (0);
281       GNUNET_SCHEDULER_add_now (&end, NULL);
282     }
283
284     if (failed == GNUNET_NO)
285     {
286       returned_records ++;
287
288       if (1 == returned_records)
289       {
290         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping zone iteration after %u received record \n",returned_records );
291         GNUNET_NAMESTORE_zone_iteration_stop (zi);
292         if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
293         {
294           GNUNET_SCHEDULER_cancel (endbadly_task);
295           endbadly_task = GNUNET_SCHEDULER_NO_TASK;
296         }
297         GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3), &end , NULL);
298         return;
299       }
300       else
301       {
302         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Telling namestore to send the next result\n");
303         GNUNET_NAMESTORE_zone_iterator_next (zi);
304       }
305     }
306     else
307     {
308       GNUNET_break (0);
309       GNUNET_SCHEDULER_add_now (&end, NULL);
310     }
311   }
312 }
313
314
315 static void
316 put_cont (void *cls, int32_t success, const char *emsg)
317 {
318   static int c = 0;
319
320   if (success == GNUNET_OK)
321   {
322     c++;
323     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record %u \n", c);
324   }
325   else
326   {
327     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to created records\n");
328     GNUNET_break (0);
329     GNUNET_SCHEDULER_cancel (endbadly_task);
330     endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
331   }
332
333   if (c == 3)
334   {
335     res = 1;
336     returned_records = 0;
337     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All records created, starting iteration over all zones \n");
338     zi = GNUNET_NAMESTORE_zone_iteration_start(nsh,
339                                         NULL,
340                                         GNUNET_NAMESTORE_RF_NONE,
341                                         GNUNET_NAMESTORE_RF_NONE,
342                                         zone_proc,
343                                         &zone);
344     if (zi == NULL)
345     {
346       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create zone iterator\n");
347       GNUNET_break (0);
348       GNUNET_SCHEDULER_cancel (endbadly_task);
349       endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
350     }
351   }
352 }
353
354
355 static struct GNUNET_NAMESTORE_RecordData *
356 create_record (unsigned int count)
357 {
358   unsigned int c;
359   struct GNUNET_NAMESTORE_RecordData * rd;
360
361   rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData));
362   for (c = 0; c < count; c++)
363   {
364     rd[c].expiration_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_HOURS).abs_value;
365     rd[c].record_type = 1111;
366     rd[c].data_size = 50;
367     rd[c].data = GNUNET_malloc(50);
368     memset ((char *) rd[c].data, 'a', 50);
369   }
370   return rd;
371 }
372
373
374 static void
375 run (void *cls,
376      const struct GNUNET_CONFIGURATION_Handle *cfg,
377      struct GNUNET_TESTING_Peer *peer)
378 {
379   char *hostkey_file;
380   struct GNUNET_TIME_Absolute et;
381
382   endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,&endbadly, NULL);
383   GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
384       "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey");
385   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
386   privkey = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file);
387   GNUNET_free (hostkey_file);
388   GNUNET_assert (privkey != NULL);
389   GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey);
390   GNUNET_CRYPTO_hash(&pubkey, sizeof (pubkey), &zone);
391
392   GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
393       "HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey");
394   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
395   privkey2 = GNUNET_CRYPTO_rsa_key_create_from_file(hostkey_file);
396   GNUNET_free (hostkey_file);
397   GNUNET_assert (privkey2 != NULL);
398   GNUNET_CRYPTO_rsa_key_get_public(privkey2, &pubkey2);
399   GNUNET_CRYPTO_hash(&pubkey2, sizeof (pubkey), &zone2);
400
401   nsh = GNUNET_NAMESTORE_connect (cfg);
402   GNUNET_break (NULL != nsh);
403
404   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 1\n");
405
406   GNUNET_asprintf(&s_name_1, "dummy1");
407   s_rd_1 = create_record(1);
408   et.abs_value = s_rd_1[0].expiration_time;
409   sig_1 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_1, s_rd_1, 1);
410   GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_1, s_rd_1, &put_cont, NULL);
411
412
413   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n");
414   GNUNET_asprintf(&s_name_2, "dummy2");
415   s_rd_2 = create_record(1);
416
417   et.abs_value = s_rd_2[0].expiration_time;
418   sig_2 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_2, s_rd_2, 1);
419   GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_2, s_rd_2, &put_cont, NULL);
420
421   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 3\n");
422   /* name in different zone */
423   GNUNET_asprintf(&s_name_3, "dummy3");
424   s_rd_3 = create_record(1);
425   et.abs_value = s_rd_3[0].expiration_time;
426   sig_3 = GNUNET_NAMESTORE_create_signature(privkey2, et, s_name_3, s_rd_3, 1);
427   GNUNET_NAMESTORE_record_put (nsh, &pubkey2, s_name_3, GNUNET_TIME_UNIT_FOREVER_ABS, 1, s_rd_3, sig_3, &put_cont, NULL);
428 }
429
430
431 int
432 main (int argc, char *argv[])
433 {
434   res = 1;
435   if (0 != 
436       GNUNET_TESTING_service_run ("test-namestore-api-zone-iteration-stop",
437                                   "namestore",
438                                   "test_namestore_api.conf",
439                                   &run,
440                                   NULL))
441     return 1;
442   return res;
443 }
444
445
446 /* end of test_namestore_api_zone_iteration_stop.c */