-dead code elimination
[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.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.J7POEUT41A8PBFS7KVVDRF88GBOU4HK8PSU5QKVLVE3R9T91E99G.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/J7POEUT41A8PBFS7KVVDRF88GBOU4HK8PSU5QKVLVE3R9T91E99G.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 shutdown_task (void *cls,
99                const struct GNUNET_SCHEDULER_TaskContext *tc)
100 {
101   GNUNET_GNS_disconnect (gns_handle);
102   gns_handle = NULL;
103   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down peer!\n");
104   GNUNET_SCHEDULER_shutdown ();
105 }
106
107
108 static void
109 on_lookup_result_cname (void *cls, 
110                         uint32_t rd_count,
111                         const struct GNUNET_NAMESTORE_RecordData *rd)
112 {
113   uint32_t i;
114   
115   if (GNUNET_SCHEDULER_NO_TASK != die_task)
116   {
117       GNUNET_SCHEDULER_cancel (die_task);
118       die_task = GNUNET_SCHEDULER_NO_TASK;
119   }
120   GNUNET_NAMESTORE_disconnect (namestore_handle);
121   namestore_handle = NULL;
122   if (rd_count == 0)
123   {
124     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
125                 "Lookup failed, rp_filtering?\n");
126     ok = 2;
127   }
128   else
129   {
130     ok = 1;
131     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "name: %s\n", (char*)cls);
132     for (i=0; i<rd_count; i++)
133     {
134       GNUNET_log (GNUNET_ERROR_TYPE_INFO, "type: %d\n", rd[i].record_type);
135       if (rd[i].record_type == GNUNET_DNSPARSER_TYPE_CNAME)
136       {
137         GNUNET_log (GNUNET_ERROR_TYPE_INFO, "CNAME: %s\n", rd[i].data);
138         if (0 == strcmp(rd[i].data, TEST_RECORD_CNAME_SERVER))
139         {
140           GNUNET_log (GNUNET_ERROR_TYPE_INFO,
141                     "%s correctly resolved to %s!\n", TEST_DOMAIN_PLUS, rd[i].data);
142           ok = 0;
143         }
144       }
145       else
146       {
147         GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No resolution!\n");
148       }
149     }
150   }
151   GNUNET_SCHEDULER_add_now (&shutdown_task, NULL);
152 }
153
154
155 static void
156 on_lookup_result_dns (void *cls,
157                       uint32_t rd_count,
158                       const struct GNUNET_NAMESTORE_RecordData *rd)
159 {
160   struct in_addr a;
161   uint32_t i;
162   char* addr;
163   
164   if (rd_count == 0)
165   {
166     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
167                 "CNAME to DNS delegation failed. System offline?\n");
168   }
169   else
170   {
171     ok = 1;
172     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "name: %s\n", (char*)cls);
173     for (i=0; i<rd_count; i++)
174     {
175       GNUNET_log (GNUNET_ERROR_TYPE_INFO, "type: %d\n", rd[i].record_type);
176       if (rd[i].record_type == GNUNET_DNSPARSER_TYPE_A)
177       {
178         memcpy(&a, rd[i].data, sizeof(a));
179         addr = inet_ntoa(a);
180         GNUNET_log (GNUNET_ERROR_TYPE_INFO, "address: %s\n", addr);
181         if (0 == strcmp(addr, TEST_IP_DNS))
182         {
183           GNUNET_log (GNUNET_ERROR_TYPE_INFO,
184                       "%s correctly resolved to %s!\n", TEST_DOMAIN_DNS, addr);
185           ok = 0;
186         }
187       }
188       else
189       {
190         GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No resolution!\n");
191       }
192     }
193   }
194   GNUNET_GNS_lookup (gns_handle, TEST_DOMAIN_PLUS, GNUNET_DNSPARSER_TYPE_CNAME,
195                      GNUNET_YES,
196                      NULL,
197                      &on_lookup_result_cname, TEST_DOMAIN_PLUS);
198 }
199
200
201 static void
202 on_lookup_result_zkey (void *cls, uint32_t rd_count,
203                        const struct GNUNET_NAMESTORE_RecordData *rd)
204 {
205   struct in_addr a;
206   uint32_t i;
207   char* addr;
208   
209   if (rd_count == 0)
210   {
211     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
212                 "Lookup failed, rp_filtering?\n");
213     ok = 2;
214     GNUNET_SCHEDULER_shutdown ();
215     return;
216   }
217   ok = 1;
218   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
219               "name: %s\n", (char*)cls);
220   for (i=0; i<rd_count; i++)
221   {
222     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
223                 "type: %d\n", rd[i].record_type);
224     if (rd[i].record_type == GNUNET_DNSPARSER_TYPE_A)
225     {
226       memcpy (&a, rd[i].data, sizeof(a));
227       addr = inet_ntoa(a);
228       GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
229                   "address: %s\n", addr);
230       if (0 == strcmp (addr, TEST_IP_ZKEY))
231       {
232         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
233                     "%s correctly resolved to %s!\n", 
234                     TEST_DOMAIN_ZKEY, addr);
235         ok = 0;
236       }
237     }
238     else
239     {
240       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
241                   "No resolution!\n");
242     }
243   }  
244   GNUNET_GNS_lookup (gns_handle, TEST_DOMAIN_DNS, GNUNET_DNSPARSER_TYPE_A,
245                      GNUNET_YES,
246                      NULL,
247                      &on_lookup_result_dns, TEST_DOMAIN_DNS);
248 }
249
250
251 static void
252 on_lookup_result_plus (void *cls, uint32_t rd_count,
253                        const struct GNUNET_NAMESTORE_RecordData *rd)
254 {
255   struct in_addr a;
256   uint32_t i;
257   char* addr;
258   
259   if (rd_count == 0)
260   {
261     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
262                 "Lookup failed, rp_filtering?\n");
263     ok = 2;
264     GNUNET_SCHEDULER_shutdown ();
265     return;
266   }
267   ok = 1;
268   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "name: %s\n", (char*)cls);
269   for (i=0; i<rd_count; i++)
270   {
271     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "type: %d\n", rd[i].record_type);
272     if (rd[i].record_type == GNUNET_DNSPARSER_TYPE_A)
273     {
274       memcpy(&a, rd[i].data, sizeof(a));
275       addr = inet_ntoa(a);
276       GNUNET_log (GNUNET_ERROR_TYPE_INFO, "address: %s\n", addr);
277       if (0 == strcmp(addr, TEST_IP_PLUS))
278       {
279         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
280                     "%s correctly resolved to %s!\n", TEST_DOMAIN_PLUS, addr);
281         ok = 0;
282       }
283     }
284     else
285     {
286       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No resolution!\n");
287     }
288   }
289   GNUNET_GNS_lookup (gns_handle, TEST_DOMAIN_ZKEY, GNUNET_DNSPARSER_TYPE_A,
290                      GNUNET_YES,
291                      NULL,
292                      &on_lookup_result_zkey, TEST_DOMAIN_ZKEY);
293 }
294
295
296 /**
297  * Function scheduled to be run on the successful start of services
298  * tries to look up the dns record for TEST_DOMAIN
299  *
300  * @param cls closure
301  * @param success GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate)
302  *                GNUNET_NO if content was already there or not found
303  *                GNUNET_YES (or other positive value) on success
304  * @param emsg NULL on success, otherwise an error message
305  */
306 static void
307 commence_testing (void *cls, int32_t success, const char *emsg)
308 {
309   if (NULL != emsg)
310   {
311     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
312                 "Failed to store record in namestore: %s\n",
313                 emsg);
314     GNUNET_SCHEDULER_shutdown ();
315     return;
316   }
317   gns_handle = GNUNET_GNS_connect(cfg);
318   if (NULL == gns_handle)
319   {
320     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
321                 "Failed to connect to GNS!\n");
322     GNUNET_SCHEDULER_shutdown ();
323     return;
324   }
325   GNUNET_GNS_lookup (gns_handle, TEST_DOMAIN_PLUS, GNUNET_DNSPARSER_TYPE_A,
326                      GNUNET_YES,
327                      NULL,
328                      &on_lookup_result_plus, TEST_DOMAIN_PLUS);
329 }
330
331
332 static void
333 do_check (void *cls,
334           const struct GNUNET_CONFIGURATION_Handle *ccfg,
335           struct GNUNET_TESTING_Peer *peer)
336 {
337   struct GNUNET_CRYPTO_EccPublicKey alice_pkey;
338   struct GNUNET_CRYPTO_EccPrivateKey *alice_key;
339   struct GNUNET_CRYPTO_EccPrivateKey *bob_key;
340   char* alice_keyfile;
341   struct GNUNET_NAMESTORE_RecordData rd;
342   const char* ip = TEST_IP_PLUS;
343   struct in_addr web;
344   
345   cfg = ccfg;
346   die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
347
348   /* put records into namestore */
349   namestore_handle = GNUNET_NAMESTORE_connect(cfg);
350   if (NULL == namestore_handle)
351   {
352     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
353                 "Failed to connect to namestore\n");
354     GNUNET_SCHEDULER_shutdown ();
355     return;
356   }
357
358   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
359                                                           "ZONEKEY",
360                                                           &alice_keyfile))
361   {
362     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
363                 "Failed to get key from cfg\n");
364     GNUNET_SCHEDULER_shutdown ();
365     return;
366   }
367
368   alice_key = GNUNET_CRYPTO_ecc_key_create_from_file (alice_keyfile);
369   GNUNET_CRYPTO_ecc_key_get_public (alice_key, &alice_pkey);
370   GNUNET_free(alice_keyfile);
371
372   bob_key = GNUNET_CRYPTO_ecc_key_create_from_file (KEYFILE_BOB);
373
374   rd.expiration_time = UINT64_MAX;
375   GNUNET_assert(1 == inet_pton (AF_INET, ip, &web));
376   rd.data_size = sizeof(struct in_addr);
377   rd.data = &web;
378   rd.record_type = GNUNET_DNSPARSER_TYPE_A;
379   rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
380
381   GNUNET_NAMESTORE_record_put_by_authority (namestore_handle,
382                                             alice_key,
383                                             TEST_RECORD_NAME_SERVER,
384                                             1, &rd,
385                                             NULL,
386                                             NULL);
387
388   rd.data_size = strlen (TEST_RECORD_CNAME_PLUS);
389   rd.data = TEST_RECORD_CNAME_PLUS;
390   rd.record_type = GNUNET_DNSPARSER_TYPE_CNAME;
391
392   GNUNET_NAMESTORE_record_put_by_authority (namestore_handle,
393                                             alice_key,
394                                             TEST_RECORD_NAME_PLUS,
395                                             1, &rd,
396                                             NULL,
397                                             NULL);
398
399   rd.data_size = strlen (TEST_RECORD_CNAME_ZKEY);
400   rd.data = TEST_RECORD_CNAME_ZKEY;
401   rd.record_type = GNUNET_DNSPARSER_TYPE_CNAME;
402
403   GNUNET_NAMESTORE_record_put_by_authority (namestore_handle,
404                                             alice_key,
405                                             TEST_RECORD_NAME_ZKEY,
406                                             1, &rd,
407                                             NULL,
408                                             NULL);
409
410   rd.data_size = strlen (TEST_RECORD_CNAME_DNS);
411   rd.data = TEST_RECORD_CNAME_DNS;
412   rd.record_type = GNUNET_DNSPARSER_TYPE_CNAME;
413
414   GNUNET_NAMESTORE_record_put_by_authority (namestore_handle,
415                                             alice_key,
416                                             TEST_RECORD_NAME_DNS,
417                                             1, &rd,
418                                             NULL,
419                                             NULL);
420
421   GNUNET_assert(1 == inet_pton (AF_INET, TEST_IP_ZKEY, &web));
422   rd.data_size = sizeof(struct in_addr);
423   rd.data = &web;
424   rd.record_type = GNUNET_DNSPARSER_TYPE_A;
425   
426   GNUNET_NAMESTORE_record_put_by_authority (namestore_handle,
427                                             bob_key,
428                                             TEST_RECORD_NAME_PLUS,
429                                             1, &rd,
430                                             &commence_testing,
431                                             NULL);
432   GNUNET_CRYPTO_ecc_key_free(alice_key);
433   GNUNET_CRYPTO_ecc_key_free(bob_key);
434 }
435
436
437 int
438 main (int argc, char *argv[])
439 {
440   ok = 1;
441
442   GNUNET_log_setup ("test-gns-simple-cname-lookup",
443                     "WARNING",
444                     NULL);
445   GNUNET_TESTING_peer_run ("test-gns-simple-cname-lookup", "test_gns_simple_lookup.conf", &do_check, NULL);
446   return ok;
447 }
448
449 /* end of test_gns_cname_lookup.c */