2 This file is part of GNUnet.
3 (C) 2009, 2010, 2011 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.
23 * @file gns/gnunet-service-gns.c
24 * @brief GNUnet GNS service
25 * @author Martin Schanzenbach
28 #include "gnunet_util_lib.h"
29 #include "gnunet_transport_service.h"
30 #include "gnunet_dns_service.h"
31 #include "gnunet_dnsparser_lib.h"
32 #include "gnunet_dht_service.h"
33 #include "gnunet_namestore_service.h"
35 #include "gnunet_gns_service.h"
36 #include "block_gns.h"
38 #include "gnunet-service-gns_resolver.h"
39 #include "gnunet-service-gns_interceptor.h"
41 /* FIXME move to proper header in include */
42 #define GNUNET_MESSAGE_TYPE_GNS_LOOKUP 23
43 #define GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT 24
44 #define GNUNET_MESSAGE_TYPE_GNS_SHORTEN 25
45 #define GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT 26
46 #define GNUNET_MESSAGE_TYPE_GNS_GET_AUTH 27
47 #define GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT 28
51 * Handle to a shorten operation from api
53 struct ClientShortenHandle
55 /* the requesting client that */
56 struct GNUNET_SERVER_Client *client;
62 enum GNUNET_GNS_RecordType type;
71 * Handle to a get auhtority operation from api
73 struct ClientGetAuthHandle
75 /* the requesting client that */
76 struct GNUNET_SERVER_Client *client;
81 /* name to lookup authority */
88 * Handle to a lookup operation from api
90 struct ClientLookupHandle
92 /* the requesting client that */
93 struct GNUNET_SERVER_Client *client;
99 enum GNUNET_GNS_RecordType type;
101 /* the name to look up */
102 char* name; //Needed?
106 * Our handle to the DHT
108 static struct GNUNET_DHT_Handle *dht_handle;
111 * Our zone's private key
113 struct GNUNET_CRYPTO_RsaPrivateKey *zone_key;
116 * Our handle to the namestore service
117 * FIXME maybe need a second handle for iteration
119 struct GNUNET_NAMESTORE_Handle *namestore_handle;
122 * Handle to iterate over our authoritative zone in namestore
124 struct GNUNET_NAMESTORE_ZoneIterator *namestore_iter;
127 * The configuration the GNS service is running with
129 const struct GNUNET_CONFIGURATION_Handle *GNS_cfg;
132 * Our notification context.
134 static struct GNUNET_SERVER_NotificationContext *nc;
139 struct GNUNET_CRYPTO_ShortHashCode zone_hash;
142 * Useful for zone update for DHT put
144 static int num_public_records = 3600;
146 /* dht update interval FIXME define? */
147 static struct GNUNET_TIME_Relative dht_update_interval;
149 /* zone update task */
150 GNUNET_SCHEDULER_TaskIdentifier zone_update_taskid = GNUNET_SCHEDULER_NO_TASK;
152 /* automatic pkey import for name shortening */
153 static int auto_import_pkey;
156 static struct GNUNET_TIME_Relative default_lookup_timeout;
159 * Normalizes the name in old
161 * @param old the old name to normalize
162 * @param new the buffer to write the new name to
165 normalize_name(const char* old, char** new)
170 tmp_name = u8_tolower ((uint8_t*)old, strlen ((char *) old),
171 NULL, UNINORM_NFD, NULL, &n_len);
173 memcpy(*new, tmp_name, n_len);
174 (*new)[n_len] = '\0';
181 on_resolver_cleanup(void)
183 GNUNET_NAMESTORE_disconnect(namestore_handle, 1);
184 GNUNET_DHT_disconnect(dht_handle);
188 * Task run during shutdown.
194 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
197 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
199 /* Kill zone task for it may make the scheduler hang */
200 if (zone_update_taskid)
201 GNUNET_SCHEDULER_cancel(zone_update_taskid);
203 GNUNET_SERVER_notification_context_destroy (nc);
205 gns_interceptor_stop();
206 gns_resolver_cleanup(&on_resolver_cleanup);
212 * Method called periodicattluy that triggers
213 * iteration over root zone
216 * @param tc task context
219 update_zone_dht_next(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
221 GNUNET_NAMESTORE_zone_iterator_next(namestore_iter);
225 * Continuation for DHT put
228 * @param tc task context
231 record_dht_put(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
233 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "put request transmitted\n");
238 update_zone_dht_start(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
241 * Function used to put all records successively into the DHT.
243 * @param cls the closure (NULL)
244 * @param key the public key of the authority (ours)
245 * @param expiration lifetime of the namestore entry
246 * @param name the name of the records
247 * @param rd_count the number of records in data
248 * @param rd the record data
249 * @param signature the signature for the record data
252 put_gns_record(void *cls,
253 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key,
254 struct GNUNET_TIME_Absolute expiration,
256 unsigned int rd_count,
257 const struct GNUNET_NAMESTORE_RecordData *rd,
258 const struct GNUNET_CRYPTO_RsaSignature *signature)
261 struct GNSNameRecordBlock *nrb;
262 struct GNUNET_CRYPTO_ShortHashCode name_hash;
263 GNUNET_HashCode xor_hash;
264 GNUNET_HashCode name_hash_double;
265 GNUNET_HashCode zone_hash_double;
266 struct GNUNET_CRYPTO_HashAsciiEncoded xor_hash_string;
267 uint32_t rd_payload_length;
268 char* nrb_data = NULL;
274 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
275 "Zone iteration finished. Rescheduling put in %ds\n",
276 GNUNET_GNS_DHT_MAX_UPDATE_INTERVAL);
277 zone_update_taskid = GNUNET_SCHEDULER_add_delayed (
278 GNUNET_TIME_relative_multiply(
279 GNUNET_TIME_UNIT_SECONDS,
280 GNUNET_GNS_DHT_MAX_UPDATE_INTERVAL
282 &update_zone_dht_start,
287 namelen = strlen(name) + 1;
289 if (signature == NULL)
291 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
292 "No signature for %s record data provided! Skipping...\n",
294 zone_update_taskid = GNUNET_SCHEDULER_add_now (&update_zone_dht_next,
300 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
301 "Putting records for %s into the DHT\n", name);
303 rd_payload_length = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
305 nrb = GNUNET_malloc(rd_payload_length + namelen
306 + sizeof(struct GNSNameRecordBlock));
308 nrb->signature = *signature;
310 nrb->public_key = *key;
312 nrb->rd_count = htonl(rd_count);
314 memcpy(&nrb[1], name, namelen);
316 nrb_data = (char*)&nrb[1];
319 rd_payload_length += sizeof(struct GNSNameRecordBlock) + namelen;
321 if (-1 == GNUNET_NAMESTORE_records_serialize (rd_count,
326 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
327 "Record serialization failed! Skipping...\n");
329 zone_update_taskid = GNUNET_SCHEDULER_add_now (&update_zone_dht_next,
336 * calculate DHT key: H(name) xor H(pubkey)
338 GNUNET_CRYPTO_short_hash(name, strlen(name), &name_hash);
339 GNUNET_CRYPTO_short_hash_double (&name_hash, &name_hash_double);
340 GNUNET_CRYPTO_short_hash_double (&zone_hash, &zone_hash_double);
341 GNUNET_CRYPTO_hash_xor(&zone_hash_double, &name_hash_double, &xor_hash);
342 GNUNET_CRYPTO_hash_to_enc (&xor_hash, &xor_hash_string);
344 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
345 "putting records for %s under key: %s with size %d\n",
346 name, (char*)&xor_hash_string, rd_payload_length);
348 GNUNET_DHT_put (dht_handle, &xor_hash,
349 DHT_GNS_REPLICATION_LEVEL,
351 GNUNET_BLOCK_TYPE_GNS_NAMERECORD,
355 DHT_OPERATION_TIMEOUT,
357 NULL); //cls for cont
359 num_public_records++;
362 * Reschedule periodic put
364 zone_update_taskid = GNUNET_SCHEDULER_add_delayed (dht_update_interval,
365 &update_zone_dht_next,
373 * Periodically iterate over our zone and store everything in dht
376 * @param tc task context
379 update_zone_dht_start(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
381 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Scheduling DHT zone update!\n");
382 if (0 == num_public_records)
384 dht_update_interval = GNUNET_TIME_relative_multiply(
385 GNUNET_TIME_UNIT_SECONDS,
386 GNUNET_GNS_DHT_MAX_UPDATE_INTERVAL);
387 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
388 "No records in db. Adjusted DHT update interval to %ds\n",
389 GNUNET_GNS_DHT_MAX_UPDATE_INTERVAL);
394 dht_update_interval = GNUNET_TIME_relative_multiply(
395 GNUNET_TIME_UNIT_SECONDS,
396 (3600/num_public_records));
397 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
398 "Adjusted DHT update interval to %ds!\n",
399 (3600/num_public_records));
402 /* start counting again */
403 num_public_records = 0;
404 namestore_iter = GNUNET_NAMESTORE_zone_iteration_start (namestore_handle,
406 GNUNET_NAMESTORE_RF_AUTHORITY,
407 GNUNET_NAMESTORE_RF_PRIVATE,
413 /* END DHT ZONE PROPAGATION */
416 * Send shorten response back to client
418 * @param cls the closure containing a client shorten handle
419 * @param name the shortened name result or NULL if cannot be shortened
422 send_shorten_response(void* cls, const char* name)
424 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message with %s\n",
425 "SHORTEN_RESULT", name);
426 struct GNUNET_GNS_ClientShortenResultMessage *rmsg;
427 struct ClientShortenHandle *csh = (struct ClientShortenHandle *)cls;
434 rmsg = GNUNET_malloc(sizeof(struct GNUNET_GNS_ClientShortenResultMessage)
437 rmsg->id = csh->unique_id;
438 rmsg->header.type = htons(GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT);
440 htons(sizeof(struct GNUNET_GNS_ClientShortenResultMessage) +
443 strcpy((char*)&rmsg[1], name);
445 GNUNET_SERVER_notification_context_unicast (nc, csh->client,
446 (const struct GNUNET_MessageHeader *) rmsg,
448 GNUNET_SERVER_receive_done (csh->client, GNUNET_OK);
451 GNUNET_free_non_null(csh->name);
457 * Handle a shorten message from the api
459 * @param cls the closure
460 * @param client the client
461 * @param message the message
463 static void handle_shorten(void *cls,
464 struct GNUNET_SERVER_Client * client,
465 const struct GNUNET_MessageHeader * message)
467 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "SHORTEN");
470 struct ClientShortenHandle *csh;
471 char name[MAX_DNS_NAME_LENGTH];
473 if (ntohs (message->size) < sizeof (struct GNUNET_GNS_ClientShortenMessage))
476 GNUNET_SERVER_receive_done (client, GNUNET_OK);
480 GNUNET_SERVER_notification_context_add (nc, client);
482 struct GNUNET_GNS_ClientShortenMessage *sh_msg =
483 (struct GNUNET_GNS_ClientShortenMessage *) message;
485 msg_size = ntohs(message->size);
487 if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
490 GNUNET_SERVER_receive_done (client, GNUNET_OK);
494 csh = GNUNET_malloc(sizeof(struct ClientShortenHandle));
495 csh->client = client;
496 csh->unique_id = sh_msg->id;
498 normalize_name((char*)&sh_msg[1], (char**)&name);
500 if (strlen (name) < strlen(GNUNET_GNS_TLD)) {
502 send_shorten_response(csh, name);
506 if (!is_gnunet_tld(name) && !is_zkey_tld(name))
508 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
509 "%s is not our domain. Returning\n", name);
511 send_shorten_response(csh, name);
515 /* Start shortening */
516 if (GNUNET_YES == auto_import_pkey)
517 gns_resolver_shorten_name(zone_hash, name, zone_key,
518 &send_shorten_response, csh);
520 gns_resolver_shorten_name(zone_hash, name, NULL,
521 &send_shorten_response, csh);
526 * Send get authority response back to client
528 * @param cls the closure containing a client get auth handle
529 * @param name the shortened name result or NULL if cannot be shortened
532 send_get_auth_response(void *cls, const char* name)
534 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message with %s\n",
535 "GET_AUTH_RESULT", name);
536 struct GNUNET_GNS_ClientGetAuthResultMessage *rmsg;
537 struct ClientGetAuthHandle *cah = (struct ClientGetAuthHandle *)cls;
544 rmsg = GNUNET_malloc(sizeof(struct GNUNET_GNS_ClientGetAuthResultMessage)
547 rmsg->id = cah->unique_id;
548 rmsg->header.type = htons(GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT);
550 htons(sizeof(struct GNUNET_GNS_ClientGetAuthResultMessage) +
553 strcpy((char*)&rmsg[1], name);
555 GNUNET_SERVER_notification_context_unicast (nc, cah->client,
556 (const struct GNUNET_MessageHeader *) rmsg,
558 GNUNET_SERVER_receive_done (cah->client, GNUNET_OK);
560 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up handles...\n");
563 GNUNET_free_non_null(cah->name);
566 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "done.\n");
572 * Handle a get authority message from the api
574 * @param cls the closure
575 * @param client the client
576 * @param message the message
578 static void handle_get_authority(void *cls,
579 struct GNUNET_SERVER_Client * client,
580 const struct GNUNET_MessageHeader * message)
582 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "GET_AUTH");
585 struct ClientGetAuthHandle *cah;
586 char name[MAX_DNS_NAME_LENGTH];
588 if (ntohs (message->size) < sizeof (struct GNUNET_GNS_ClientGetAuthMessage))
591 GNUNET_SERVER_receive_done (client, GNUNET_OK);
595 GNUNET_SERVER_notification_context_add (nc, client);
597 struct GNUNET_GNS_ClientGetAuthMessage *sh_msg =
598 (struct GNUNET_GNS_ClientGetAuthMessage *) message;
600 msg_size = ntohs(message->size);
602 if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
605 GNUNET_SERVER_receive_done (client, GNUNET_OK);
609 normalize_name((char*)&sh_msg[1], (char**)&name);
612 cah = GNUNET_malloc(sizeof(struct ClientGetAuthHandle));
613 cah->client = client;
614 cah->unique_id = sh_msg->id;
616 if (strlen(name) < strlen(GNUNET_GNS_TLD))
618 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
619 "%s is too short. Returning\n", name);
621 send_get_auth_response(cah, name);
625 if (strcmp(name+strlen(name)-strlen(GNUNET_GNS_TLD),
626 GNUNET_GNS_TLD) != 0)
628 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
629 "%s is not our domain. Returning\n", name);
631 send_get_auth_response(cah, name);
635 if (strcmp(name, GNUNET_GNS_TLD) == 0)
637 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
638 "%s is us. Returning\n", name);
640 send_get_auth_response(cah, name);
644 cah->name = GNUNET_malloc(strlen(name)
645 - strlen(GNUNET_GNS_TLD) + 1);
647 strlen(name)-strlen(GNUNET_GNS_TLD) + 1);
648 memcpy(cah->name, name,
649 strlen(name)-strlen(GNUNET_GNS_TLD));
651 /* Start delegation resolution in our namestore */
652 gns_resolver_get_authority(zone_hash, name, &send_get_auth_response, cah);
657 * Reply to client with the result from our lookup.
659 * @param cls the closure (our client lookup handle)
660 * @param rd_count the number of records
661 * @param rd the record data
664 send_lookup_response(void* cls,
666 const struct GNUNET_NAMESTORE_RecordData *rd)
668 struct ClientLookupHandle* clh = (struct ClientLookupHandle*)cls;
669 struct GNUNET_GNS_ClientLookupResultMessage *rmsg;
672 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message with %d results\n",
673 "LOOKUP_RESULT", rd_count);
675 len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
676 rmsg = GNUNET_malloc(len+sizeof(struct GNUNET_GNS_ClientLookupResultMessage));
678 rmsg->id = clh->unique_id;
679 rmsg->rd_count = htonl(rd_count);
680 rmsg->header.type = htons(GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT);
682 htons(len+sizeof(struct GNUNET_GNS_ClientLookupResultMessage));
684 GNUNET_NAMESTORE_records_serialize (rd_count, rd, len, (char*)&rmsg[1]);
686 GNUNET_SERVER_notification_context_unicast (nc, clh->client,
687 (const struct GNUNET_MessageHeader *) rmsg,
689 GNUNET_SERVER_receive_done (clh->client, GNUNET_OK);
692 GNUNET_free(clh->name);
699 * Handle lookup requests from client
701 * @param cls the closure
702 * @param client the client
703 * @param message the message
706 handle_lookup(void *cls,
707 struct GNUNET_SERVER_Client * client,
708 const struct GNUNET_MessageHeader * message)
710 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "LOOKUP");
714 char name[MAX_DNS_NAME_LENGTH];
715 struct ClientLookupHandle *clh;
717 if (ntohs (message->size) < sizeof (struct GNUNET_GNS_ClientLookupMessage))
720 GNUNET_SERVER_receive_done (client, GNUNET_OK);
724 GNUNET_SERVER_notification_context_add (nc, client);
726 struct GNUNET_GNS_ClientLookupMessage *sh_msg =
727 (struct GNUNET_GNS_ClientLookupMessage *) message;
729 msg_size = ntohs(message->size);
731 if (msg_size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
734 GNUNET_SERVER_receive_done (client, GNUNET_OK);
738 normalize_name((char*)&sh_msg[1], (char**)&name);
739 namelen = strlen(name)+1;
740 clh = GNUNET_malloc(sizeof(struct ClientLookupHandle));
741 clh->client = client;
742 clh->name = GNUNET_malloc(namelen);
743 strcpy(clh->name, name);
744 clh->unique_id = sh_msg->id;
745 clh->type = ntohl(sh_msg->type);
747 if (GNUNET_YES == auto_import_pkey)
749 gns_resolver_lookup_record(zone_hash, clh->type, name,
751 default_lookup_timeout,
752 &send_lookup_response, clh);
756 gns_resolver_lookup_record(zone_hash, clh->type, name,
758 default_lookup_timeout,
759 &send_lookup_response, clh);
766 * Process GNS requests.
768 * @param cls closure)
769 * @param server the initialized server
770 * @param c configuration to use
773 run (void *cls, struct GNUNET_SERVER_Handle *server,
774 const struct GNUNET_CONFIGURATION_Handle *c)
777 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Initializing GNS\n");
780 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
781 unsigned long long max_parallel_bg_queries = 0;
782 unsigned long long default_lookup_timeout_secs = 0;
784 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
785 {&handle_shorten, NULL, GNUNET_MESSAGE_TYPE_GNS_SHORTEN, 0},
786 {&handle_lookup, NULL, GNUNET_MESSAGE_TYPE_GNS_LOOKUP, 0},
787 {&handle_get_authority, NULL, GNUNET_MESSAGE_TYPE_GNS_GET_AUTH, 0}
790 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (c, "gns",
791 "ZONEKEY", &keyfile))
793 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
794 "No private key for root zone specified!\n");
795 GNUNET_SCHEDULER_shutdown(0);
799 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
800 "Using keyfile %s for root zone.\n", keyfile);
802 zone_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
803 GNUNET_CRYPTO_rsa_key_get_public (zone_key, &pkey);
805 GNUNET_CRYPTO_short_hash(&pkey,
806 sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
808 GNUNET_free(keyfile);
811 * handle to our local namestore
813 namestore_handle = GNUNET_NAMESTORE_connect(c);
815 if (NULL == namestore_handle)
817 //FIXME do error handling;
818 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
819 "Failed to connect to the namestore!\n");
820 GNUNET_SCHEDULER_shutdown(0);
827 dht_handle = GNUNET_DHT_connect(c, 1); //FIXME get ht_len from cfg
829 if (NULL == dht_handle)
831 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Could not connect to DHT!\n");
835 GNUNET_CONFIGURATION_get_value_yesno (c, "gns",
838 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
839 "Automatic PKEY import is enabled.\n");
840 auto_import_pkey = GNUNET_YES;
845 GNUNET_CONFIGURATION_get_value_number(c, "gns",
846 "MAX_PARALLEL_BACKGROUND_QUERIES",
847 &max_parallel_bg_queries))
849 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
850 "Number of allowed parallel background queries: %d\n",
851 max_parallel_bg_queries);
855 GNUNET_CONFIGURATION_get_value_number(c, "gns",
856 "DEFAULT_LOOKUP_TIMEOUT",
857 &default_lookup_timeout_secs))
859 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
860 "Default lookup timeout: %ds\n", default_lookup_timeout_secs);
861 default_lookup_timeout = GNUNET_TIME_relative_multiply(
862 GNUNET_TIME_UNIT_SECONDS,
863 default_lookup_timeout_secs);
866 if (gns_resolver_init(namestore_handle, dht_handle, zone_hash,
867 max_parallel_bg_queries)
870 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
871 "Unable to initialize resolver!\n");
872 GNUNET_SCHEDULER_add_now (&shutdown_task, NULL);
877 GNUNET_CONFIGURATION_get_value_yesno (c, "gns", "HIJACK_DNS"))
879 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
880 "DNS hijacking enabled... connecting to service.\n");
882 if (gns_interceptor_init(zone_hash, zone_key, c) == GNUNET_SYSERR)
884 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
885 "Failed to enable the dns interceptor!\n");
889 //put_some_records(); //FIXME for testing
892 * Schedule periodic put
894 * We have roughly an hour for all records;
896 dht_update_interval = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS,
898 zone_update_taskid = GNUNET_SCHEDULER_add_now (&update_zone_dht_start, NULL);
900 GNUNET_SERVER_add_handlers (server, handlers);
903 //GNUNET_SERVER_disconnect_notify (server,
904 // &client_disconnect_notification,
907 nc = GNUNET_SERVER_notification_context_create (server, 1);
909 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
915 * The main function for the GNS service.
917 * @param argc number of arguments from the command line
918 * @param argv command line arguments
919 * @return 0 ok, 1 on error
922 main (int argc, char *const *argv)
928 GNUNET_SERVICE_run (argc, argv, "gns", GNUNET_SERVICE_OPTION_NONE, &run,
933 /* end of gnunet-service-gns.c */