-test case cleanup
[oweals/gnunet.git] / src / gns / test_gns_cname_lookup.c
1 /*
2      This file is part of GNUnet.
3      (C) 2012 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 gns/test_gns_cname_lookup.c
22  * @brief base testcase for testing a local GNS record lookup
23  * @author Martin Schanzenbach
24  */
25 #include "platform.h"
26 #include "gnunet_testing_lib-new.h"
27 #include "gnunet_core_service.h"
28 #include "block_dns.h"
29 #include "gnunet_signatures.h"
30 #include "gnunet_namestore_service.h"
31 #include "gnunet_dnsparser_lib.h"
32 #include "gnunet_gns_service.h"
33
34
35 /**
36  * Timeout for entire testcase 
37  */
38 #define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 20)
39
40 /* test records to resolve */
41 #define TEST_DOMAIN_PLUS "www.gads"
42 #define TEST_DOMAIN_ZKEY "www2.gads"
43 #define TEST_DOMAIN_DNS  "www3.gads"
44 #define TEST_IP_PLUS "127.0.0.1"
45 #define TEST_IP_ZKEY "127.0.0.2"
46 #define TEST_IP_DNS  "131.159.74.67"
47 #define TEST_RECORD_CNAME_SERVER "server.gads"
48 #define TEST_RECORD_CNAME_PLUS "server.+"
49 #define TEST_RECORD_CNAME_ZKEY "www.188JSUMKEF25GVU8TTV0PBNNN8JVCPUEDFV1UHJJU884JD25V0T0.zkey"
50 #define TEST_RECORD_CNAME_DNS "gnunet.org"
51 #define TEST_RECORD_NAME_SERVER "server"
52 #define TEST_RECORD_NAME_PLUS "www"
53 #define TEST_RECORD_NAME_ZKEY "www2"
54 #define TEST_RECORD_NAME_DNS "www3"
55
56 #define KEYFILE_BOB "zonefiles/188JSUMKEF25GVU8TTV0PBNNN8JVCPUEDFV1UHJJU884JD25V0T0.zkey"
57
58
59 /* Task handle to use to schedule test failure */
60 static GNUNET_SCHEDULER_TaskIdentifier die_task;
61
62 /* Global return value (0 for success, anything else for failure) */
63 static int ok;
64
65 static struct GNUNET_NAMESTORE_Handle *namestore_handle;
66
67 static struct GNUNET_GNS_Handle *gns_handle;
68
69 static const struct GNUNET_CONFIGURATION_Handle *cfg;
70
71
72 /**
73  * Check if the get_handle is being used, if so stop the request.  Either
74  * way, schedule the end_badly_cont function which actually shuts down the
75  * test.
76  */
77 static void
78 end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
79 {
80   die_task = GNUNET_SCHEDULER_NO_TASK;
81   if (NULL != gns_handle)
82   {
83     GNUNET_GNS_disconnect (gns_handle);
84     gns_handle = NULL;
85   }
86   if (NULL != namestore_handle)
87   {
88     GNUNET_NAMESTORE_disconnect (namestore_handle);
89     namestore_handle = NULL;
90   }
91   GNUNET_break (0);
92   GNUNET_SCHEDULER_shutdown ();
93   ok = 1;
94 }
95
96
97 static void
98 end_badly_now ()
99 {
100   GNUNET_SCHEDULER_cancel (die_task);
101   die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
102 }
103
104
105 static void 
106 shutdown_task (void *cls,
107                const struct GNUNET_SCHEDULER_TaskContext *tc)
108 {
109   GNUNET_GNS_disconnect (gns_handle);
110   gns_handle = NULL;
111   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down peer!\n");
112   GNUNET_SCHEDULER_shutdown ();
113 }
114
115
116 static void
117 on_lookup_result_cname (void *cls, 
118                         uint32_t rd_count,
119                         const struct GNUNET_NAMESTORE_RecordData *rd)
120 {
121   uint32_t i;
122   
123   if (GNUNET_SCHEDULER_NO_TASK != die_task)
124   {
125       GNUNET_SCHEDULER_cancel (die_task);
126       die_task = GNUNET_SCHEDULER_NO_TASK;
127   }
128   GNUNET_NAMESTORE_disconnect (namestore_handle);
129   namestore_handle = NULL;
130   if (rd_count == 0)
131   {
132     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
133                 "Lookup failed, rp_filtering?\n");
134     ok = 2;
135   }
136   else
137   {
138     ok = 1;
139     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "name: %s\n", (char*)cls);
140     for (i=0; i<rd_count; i++)
141     {
142       GNUNET_log (GNUNET_ERROR_TYPE_INFO, "type: %d\n", rd[i].record_type);
143       if (rd[i].record_type == GNUNET_GNS_RECORD_CNAME)
144       {
145         GNUNET_log (GNUNET_ERROR_TYPE_INFO, "CNAME: %s\n", rd[i].data);
146         if (0 == strcmp(rd[i].data, TEST_RECORD_CNAME_SERVER))
147         {
148           GNUNET_log (GNUNET_ERROR_TYPE_INFO,
149                     "%s correctly resolved to %s!\n", TEST_DOMAIN_PLUS, rd[i].data);
150           ok = 0;
151         }
152       }
153       else
154       {
155         GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No resolution!\n");
156       }
157     }
158   }
159   GNUNET_SCHEDULER_add_now (&shutdown_task, NULL);
160 }
161
162
163 static void
164 on_lookup_result_dns (void *cls,
165                       uint32_t rd_count,
166                       const struct GNUNET_NAMESTORE_RecordData *rd)
167 {
168   struct in_addr a;
169   uint32_t i;
170   char* addr;
171   
172   if (rd_count == 0)
173   {
174     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
175                 "Lookup failed, rp_filtering?\n");
176     ok = 2;
177   }
178   else
179   {
180     ok = 1;
181     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "name: %s\n", (char*)cls);
182     for (i=0; i<rd_count; i++)
183     {
184       GNUNET_log (GNUNET_ERROR_TYPE_INFO, "type: %d\n", rd[i].record_type);
185       if (rd[i].record_type == GNUNET_GNS_RECORD_A)
186       {
187         memcpy(&a, rd[i].data, sizeof(a));
188         addr = inet_ntoa(a);
189         GNUNET_log (GNUNET_ERROR_TYPE_INFO, "address: %s\n", addr);
190         if (0 == strcmp(addr, TEST_IP_DNS))
191         {
192           GNUNET_log (GNUNET_ERROR_TYPE_INFO,
193                     "%s correctly resolved to %s!\n", TEST_DOMAIN_DNS, addr);
194           ok = 0;
195         }
196       }
197       else
198       {
199         GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No resolution!\n");
200       }
201     }
202   }
203   GNUNET_GNS_lookup (gns_handle, TEST_DOMAIN_PLUS, GNUNET_GNS_RECORD_CNAME,
204                      GNUNET_YES,
205                      NULL,
206                      &on_lookup_result_cname, TEST_DOMAIN_PLUS);
207 }
208
209
210 static void
211 on_lookup_result_zkey (void *cls, uint32_t rd_count,
212                        const struct GNUNET_NAMESTORE_RecordData *rd)
213 {
214   struct in_addr a;
215   uint32_t i;
216   char* addr;
217   
218   if (rd_count == 0)
219   {
220     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
221                 "Lookup failed, rp_filtering?\n");
222     ok = 2;
223   }
224   else
225   {
226     ok = 1;
227     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
228                 "name: %s\n", (char*)cls);
229     for (i=0; i<rd_count; i++)
230     {
231       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
232                   "type: %d\n", rd[i].record_type);
233       if (rd[i].record_type == GNUNET_GNS_RECORD_A)
234       {
235         memcpy (&a, rd[i].data, sizeof(a));
236         addr = inet_ntoa(a);
237         GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
238                     "address: %s\n", addr);
239         if (0 == strcmp (addr, TEST_IP_ZKEY))
240         {
241           GNUNET_log (GNUNET_ERROR_TYPE_INFO,
242                       "%s correctly resolved to %s!\n", 
243                       TEST_DOMAIN_ZKEY, addr);
244           ok = 0;
245         }
246       }
247       else
248       {
249         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
250                     "No resolution!\n");
251       }
252     }
253   
254   GNUNET_GNS_lookup (gns_handle, TEST_DOMAIN_DNS, GNUNET_GNS_RECORD_A,
255                      GNUNET_YES,
256                      NULL,
257                      &on_lookup_result_dns, TEST_DOMAIN_DNS);
258 }
259
260
261 static void
262 on_lookup_result_plus (void *cls, uint32_t rd_count,
263                        const struct GNUNET_NAMESTORE_RecordData *rd)
264 {
265   struct in_addr a;
266   uint32_t i;
267   char* addr;
268   
269   if (rd_count == 0)
270   {
271     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
272                 "Lookup failed, rp_filtering?\n");
273     ok = 2;
274   }
275   else
276   {
277     ok = 1;
278     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "name: %s\n", (char*)cls);
279     for (i=0; i<rd_count; i++)
280     {
281       GNUNET_log (GNUNET_ERROR_TYPE_INFO, "type: %d\n", rd[i].record_type);
282       if (rd[i].record_type == GNUNET_GNS_RECORD_A)
283       {
284         memcpy(&a, rd[i].data, sizeof(a));
285         addr = inet_ntoa(a);
286         GNUNET_log (GNUNET_ERROR_TYPE_INFO, "address: %s\n", addr);
287         if (0 == strcmp(addr, TEST_IP_PLUS))
288         {
289           GNUNET_log (GNUNET_ERROR_TYPE_INFO,
290                     "%s correctly resolved to %s!\n", TEST_DOMAIN_PLUS, addr);
291           ok = 0;
292         }
293       }
294       else
295       {
296         GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No resolution!\n");
297       }
298     }
299   }
300   GNUNET_GNS_lookup (gns_handle, TEST_DOMAIN_ZKEY, GNUNET_GNS_RECORD_A,
301                      GNUNET_YES,
302                      NULL,
303                      &on_lookup_result_zkey, TEST_DOMAIN_ZKEY);
304 }
305
306
307 /**
308  * Function scheduled to be run on the successful start of services
309  * tries to look up the dns record for TEST_DOMAIN
310  *
311  * @param cls closure
312  * @param success GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate)
313  *                GNUNET_NO if content was already there or not found
314  *                GNUNET_YES (or other positive value) on success
315  * @param emsg NULL on success, otherwise an error message
316  */
317 static void
318 commence_testing (void *cls, int32_t success, const char *emsg)
319 {
320   if (NULL != emsg)
321   {
322     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
323                 "Failed to store record in namestore: %s\n",
324                 emsg);
325     end_badly_now ();
326     return;
327   }
328   gns_handle = GNUNET_GNS_connect(cfg);
329   if (NULL == gns_handle)
330   {
331     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
332                 "Failed to connect to GNS!\n");
333     end_badly_now ();
334     return;
335   }
336   GNUNET_GNS_lookup (gns_handle, TEST_DOMAIN_PLUS, GNUNET_GNS_RECORD_A,
337                      GNUNET_YES,
338                      NULL,
339                      &on_lookup_result_plus, TEST_DOMAIN_PLUS);
340 }
341
342
343 static void
344 do_check (void *cls,
345           const struct GNUNET_CONFIGURATION_Handle *ccfg,
346           struct GNUNET_TESTING_Peer *peer)
347 {
348   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded alice_pkey;
349   struct GNUNET_CRYPTO_RsaPrivateKey *alice_key;
350   struct GNUNET_CRYPTO_RsaPrivateKey *bob_key;
351   char* alice_keyfile;
352   struct GNUNET_NAMESTORE_RecordData rd;
353   const char* ip = TEST_IP_PLUS;
354   struct in_addr web;
355   
356   cfg = ccfg;
357   die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
358
359   /* put records into namestore */
360   namestore_handle = GNUNET_NAMESTORE_connect(cfg);
361   if (NULL == namestore_handle)
362   {
363     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
364                 "Failed to connect to namestore\n");
365     end_badly_now ();
366     return;
367   }
368
369   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
370                                                           "ZONEKEY",
371                                                           &alice_keyfile))
372   {
373     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
374                 "Failed to get key from cfg\n");
375     end_badly_now ();
376     return;
377   }
378
379   alice_key = GNUNET_CRYPTO_rsa_key_create_from_file (alice_keyfile);
380   GNUNET_CRYPTO_rsa_key_get_public (alice_key, &alice_pkey);
381   GNUNET_free(alice_keyfile);
382
383   bob_key = GNUNET_CRYPTO_rsa_key_create_from_file (KEYFILE_BOB);
384
385   rd.expiration_time = UINT64_MAX;
386   GNUNET_assert(1 == inet_pton (AF_INET, ip, &web));
387   rd.data_size = sizeof(struct in_addr);
388   rd.data = &web;
389   rd.record_type = GNUNET_DNSPARSER_TYPE_A;
390   rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
391
392   GNUNET_NAMESTORE_record_create (namestore_handle,
393                                   alice_key,
394                                   TEST_RECORD_NAME_SERVER,
395                                   &rd,
396                                   NULL,
397                                   NULL);
398
399   rd.data_size = strlen (TEST_RECORD_CNAME_PLUS);
400   rd.data = TEST_RECORD_CNAME_PLUS;
401   rd.record_type = GNUNET_GNS_RECORD_CNAME;
402
403   GNUNET_NAMESTORE_record_create (namestore_handle,
404                                   alice_key,
405                                   TEST_RECORD_NAME_PLUS,
406                                   &rd,
407                                   NULL,
408                                   NULL);
409
410   rd.data_size = strlen (TEST_RECORD_CNAME_ZKEY);
411   rd.data = TEST_RECORD_CNAME_ZKEY;
412   rd.record_type = GNUNET_GNS_RECORD_CNAME;
413
414   GNUNET_NAMESTORE_record_create (namestore_handle,
415                                   alice_key,
416                                   TEST_RECORD_NAME_ZKEY,
417                                   &rd,
418                                   NULL,
419                                   NULL);
420
421   rd.data_size = strlen (TEST_RECORD_CNAME_DNS);
422   rd.data = TEST_RECORD_CNAME_DNS;
423   rd.record_type = GNUNET_GNS_RECORD_CNAME;
424
425   GNUNET_NAMESTORE_record_create (namestore_handle,
426                                   alice_key,
427                                   TEST_RECORD_NAME_DNS,
428                                   &rd,
429                                   NULL,
430                                   NULL);
431
432   GNUNET_assert(1 == inet_pton (AF_INET, TEST_IP_ZKEY, &web));
433   rd.data_size = sizeof(struct in_addr);
434   rd.data = &web;
435   rd.record_type = GNUNET_DNSPARSER_TYPE_A;
436   
437   GNUNET_NAMESTORE_record_create (namestore_handle,
438                                   bob_key,
439                                   TEST_RECORD_NAME_PLUS,
440                                   &rd,
441                                   &commence_testing,
442                                   NULL);
443   GNUNET_CRYPTO_rsa_key_free(alice_key);
444   GNUNET_CRYPTO_rsa_key_free(bob_key);
445 }
446
447
448 int
449 main (int argc, char *argv[])
450 {
451   ok = 1;
452
453   GNUNET_log_setup ("test-gns-simple-cname-lookup",
454                     "WARNING",
455                     NULL);
456   GNUNET_TESTING_peer_run ("test-gns-simple-cname-lookup", "test_gns_simple_lookup.conf", &do_check, NULL);
457   return ok;
458 }
459
460 /* end of test_gns_cname_lookup.c */