aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gnunet-service-gns_resolver.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gns/gnunet-service-gns_resolver.c')
-rw-r--r--src/gns/gnunet-service-gns_resolver.c187
1 files changed, 172 insertions, 15 deletions
diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c
index df4ba670f..ed2f8797c 100644
--- a/src/gns/gnunet-service-gns_resolver.c
+++ b/src/gns/gnunet-service-gns_resolver.c
@@ -55,6 +55,11 @@ static struct GNUNET_NAMESTORE_Handle *namestore_handle;
55static struct GNUNET_DHT_Handle *dht_handle; 55static struct GNUNET_DHT_Handle *dht_handle;
56 56
57/** 57/**
58 * Heap for parallel DHT lookups
59 */
60static struct GNUNET_CONTAINER_Heap *dht_lookup_heap;
61
62/**
58 * Namestore calls this function if we have record for this name. 63 * Namestore calls this function if we have record for this name.
59 * (or with rd_count=0 to indicate no matches) 64 * (or with rd_count=0 to indicate no matches)
60 * 65 *
@@ -216,7 +221,7 @@ process_auth_discovery_dht_result(void* cls,
216 221
217 /* stop lookup and timeout task */ 222 /* stop lookup and timeout task */
218 GNUNET_DHT_get_stop (gph->get_handle); 223 GNUNET_DHT_get_stop (gph->get_handle);
219 GNUNET_SCHEDULER_cancel(gph->dht_timeout); 224 GNUNET_SCHEDULER_cancel(gph->timeout);
220 225
221 gph->get_handle = NULL; 226 gph->get_handle = NULL;
222 227
@@ -310,8 +315,8 @@ process_zone_to_name_discover(void *cls,
310 "starting dht lookup for %s with key: %s\n", 315 "starting dht lookup for %s with key: %s\n",
311 "+", (char*)&lookup_key_string); 316 "+", (char*)&lookup_key_string);
312 317
313 gph->dht_timeout = GNUNET_SCHEDULER_add_delayed(DHT_LOOKUP_TIMEOUT, 318 //gph->timeout = GNUNET_SCHEDULER_add_delayed(DHT_LOOKUP_TIMEOUT,
314 &handle_auth_discovery_timeout, gph); 319 // &handle_auth_discovery_timeout, gph);
315 320
316 xquery = htonl(GNUNET_GNS_RECORD_PSEU); 321 xquery = htonl(GNUNET_GNS_RECORD_PSEU);
317 322
@@ -377,6 +382,8 @@ gns_resolver_init(struct GNUNET_NAMESTORE_Handle *nh,
377{ 382{
378 namestore_handle = nh; 383 namestore_handle = nh;
379 dht_handle = dh; 384 dht_handle = dh;
385 dht_lookup_heap =
386 GNUNET_CONTAINER_heap_create(GNUNET_CONTAINER_HEAP_ORDER_MIN);
380 if ((namestore_handle != NULL) && (dht_handle != NULL)) 387 if ((namestore_handle != NULL) && (dht_handle != NULL))
381 { 388 {
382 return GNUNET_OK; 389 return GNUNET_OK;
@@ -441,6 +448,23 @@ on_namestore_record_put_result(void *cls,
441 448
442 449
443/** 450/**
451 * Processor for background lookups in the DHT
452 *
453 * @param cls closure (NULL)
454 * @param rd_count number of records found (not 0)
455 * @param rd record data
456 */
457static void
458background_lookup_result_processor(void *cls,
459 uint32_t rd_count,
460 const struct GNUNET_NAMESTORE_RecordData *rd)
461{
462 //We could do sth verbose/more useful here but it doesn't make any difference
463 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
464 "background dht lookup finished.\n");
465}
466
467/**
444 * Handle timeout for DHT requests 468 * Handle timeout for DHT requests
445 * 469 *
446 * @param cls the request handle as closure 470 * @param cls the request handle as closure
@@ -450,11 +474,26 @@ static void
450dht_lookup_timeout(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 474dht_lookup_timeout(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
451{ 475{
452 struct ResolverHandle *rh = cls; 476 struct ResolverHandle *rh = cls;
477 struct RecordLookupHandle *rlh = (struct RecordLookupHandle *)rh->proc_cls;
478 char new_name[MAX_DNS_NAME_LENGTH];
453 479
454 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 480 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
455 "dht lookup for query %s timed out.\n", 481 "dht lookup for query %s timed out.\n",
456 rh->name); 482 rh->name);
457 483 /**
484 * Start resolution in bg
485 */
486 strcpy(new_name, rh->name);
487 memcpy(new_name+strlen(new_name), GNUNET_GNS_TLD, strlen(GNUNET_GNS_TLD));
488
489 gns_resolver_lookup_record(rh->authority,
490 rlh->record_type,
491 new_name,
492 rh->priv_key,
493 GNUNET_TIME_UNIT_FOREVER_REL,
494 &background_lookup_result_processor,
495 NULL);
496
458 GNUNET_DHT_get_stop (rh->get_handle); 497 GNUNET_DHT_get_stop (rh->get_handle);
459 rh->proc(rh->proc_cls, rh, 0, NULL); 498 rh->proc(rh->proc_cls, rh, 0, NULL);
460} 499}
@@ -508,8 +547,16 @@ process_record_result_dht(void* cls,
508 547
509 /* stop lookup and timeout task */ 548 /* stop lookup and timeout task */
510 GNUNET_DHT_get_stop (rh->get_handle); 549 GNUNET_DHT_get_stop (rh->get_handle);
511 GNUNET_SCHEDULER_cancel(rh->dht_timeout_task);
512 550
551 if (rh->dht_heap_node != NULL)
552 {
553 GNUNET_CONTAINER_heap_remove_node(rh->dht_heap_node);
554 rh->dht_heap_node = NULL;
555 }
556
557 if (rh->timeout_task != GNUNET_SCHEDULER_NO_TASK)
558 GNUNET_SCHEDULER_cancel(rh->timeout_task);
559
513 rh->get_handle = NULL; 560 rh->get_handle = NULL;
514 name = (char*)&nrb[1]; 561 name = (char*)&nrb[1];
515 num_records = ntohl(nrb->rd_count); 562 num_records = ntohl(nrb->rd_count);
@@ -563,6 +610,7 @@ process_record_result_dht(void* cls,
563 &nrb->signature, 610 &nrb->signature,
564 &on_namestore_record_put_result, //cont 611 &on_namestore_record_put_result, //cont
565 NULL); //cls 612 NULL); //cls
613
566 614
567 if (rh->answered) 615 if (rh->answered)
568 rh->proc(rh->proc_cls, rh, num_records, rd); 616 rh->proc(rh->proc_cls, rh, num_records, rd);
@@ -589,6 +637,7 @@ resolve_record_dht(struct ResolverHandle *rh)
589 GNUNET_HashCode zone_hash_double; 637 GNUNET_HashCode zone_hash_double;
590 struct GNUNET_CRYPTO_HashAsciiEncoded lookup_key_string; 638 struct GNUNET_CRYPTO_HashAsciiEncoded lookup_key_string;
591 struct RecordLookupHandle *rlh = (struct RecordLookupHandle *)rh->proc_cls; 639 struct RecordLookupHandle *rlh = (struct RecordLookupHandle *)rh->proc_cls;
640 struct ResolverHandle *rh_heap_root;
592 641
593 GNUNET_CRYPTO_short_hash(rh->name, strlen(rh->name), &name_hash); 642 GNUNET_CRYPTO_short_hash(rh->name, strlen(rh->name), &name_hash);
594 GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double); 643 GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double);
@@ -600,9 +649,35 @@ resolve_record_dht(struct ResolverHandle *rh)
600 "starting dht lookup for %s with key: %s\n", 649 "starting dht lookup for %s with key: %s\n",
601 rh->name, (char*)&lookup_key_string); 650 rh->name, (char*)&lookup_key_string);
602 651
603 rh->dht_timeout_task = GNUNET_SCHEDULER_add_delayed(DHT_LOOKUP_TIMEOUT, 652 rh->timeout_task = GNUNET_SCHEDULER_NO_TASK;
604 &dht_lookup_timeout, rh); 653 rh->dht_heap_node = NULL;
605 654
655 if (rh->timeout.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value)
656 {
657 //rh->timeout_task = GNUNET_SCHEDULER_add_delayed (DHT_LOOKUP_TIMEOUT,
658 // &dht_lookup_timeout,
659 // rh);
660 rh->timeout_cont = &dht_lookup_timeout;
661 rh->timeout_cont_cls = rh;
662 }
663 else
664 {
665 if (GNUNET_GNS_MAX_PARALLEL_LOOKUPS >
666 GNUNET_CONTAINER_heap_get_size (dht_lookup_heap))
667 {
668 rh_heap_root = GNUNET_CONTAINER_heap_remove_root (dht_lookup_heap);
669 GNUNET_DHT_get_stop(rh_heap_root->get_handle);
670 rh_heap_root->dht_heap_node = NULL;
671 rh_heap_root->proc(rh_heap_root->proc_cls,
672 rh_heap_root,
673 0,
674 NULL);
675 }
676 rh->dht_heap_node = GNUNET_CONTAINER_heap_insert (dht_lookup_heap,
677 rh,
678 GNUNET_TIME_absolute_get().abs_value);
679 }
680
606 xquery = htonl(rlh->record_type); 681 xquery = htonl(rlh->record_type);
607 rh->get_handle = GNUNET_DHT_get_start(dht_handle, 682 rh->get_handle = GNUNET_DHT_get_start(dht_handle,
608 DHT_OPERATION_TIMEOUT, 683 DHT_OPERATION_TIMEOUT,
@@ -649,6 +724,9 @@ process_record_result_ns(void* cls,
649 sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), 724 sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
650 &zone); 725 &zone);
651 remaining_time = GNUNET_TIME_absolute_get_remaining (expiration); 726 remaining_time = GNUNET_TIME_absolute_get_remaining (expiration);
727
728 if (rh->timeout_task != GNUNET_SCHEDULER_NO_TASK)
729 GNUNET_SCHEDULER_cancel(rh->timeout_task);
652 730
653 rh->status = 0; 731 rh->status = 0;
654 732
@@ -749,6 +827,14 @@ resolve_record_ns(struct ResolverHandle *rh)
749 rh); 827 rh);
750} 828}
751 829
830static void
831handle_lookup_timeout(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
832{
833 struct ResolverHandle *rh = cls;
834
835 if (rh->timeout_cont)
836 rh->timeout_cont(rh->timeout_cont_cls, tc);
837}
752 838
753/** 839/**
754 * Handle timeout for DHT requests 840 * Handle timeout for DHT requests
@@ -761,19 +847,43 @@ dht_authority_lookup_timeout(void *cls,
761 const struct GNUNET_SCHEDULER_TaskContext *tc) 847 const struct GNUNET_SCHEDULER_TaskContext *tc)
762{ 848{
763 struct ResolverHandle *rh = cls; 849 struct ResolverHandle *rh = cls;
850 struct RecordLookupHandle *rlh = rh->proc_cls;
851 char new_name[MAX_DNS_NAME_LENGTH];
764 852
765 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 853 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
766 "dht lookup for query %s timed out.\n", 854 "dht lookup for query %s timed out.\n",
767 rh->name); 855 rh->name);
768 856
769 GNUNET_DHT_get_stop (rh->get_handle); 857
770 if (strcmp(rh->name, "") == 0) 858 if (strcmp(rh->name, "") == 0)
771 { 859 {
772 /* 860 /*
773 * promote authority back to name and try to resolve record 861 * promote authority back to name and try to resolve record
774 */ 862 */
775 strcpy(rh->name, rh->authority_name); 863 strcpy(rh->name, rh->authority_name);
864 rh->proc(rh->proc_cls, rh, 0, NULL);
865 return;
776 } 866 }
867
868 /**
869 * Start resolution in bg
870 */
871 strcpy(new_name, rh->name);
872 strcpy(new_name+strlen(new_name), ".");
873 memcpy(new_name+strlen(new_name), rh->authority_name,
874 strlen(rh->authority_name));
875 memcpy(new_name+strlen(new_name), GNUNET_GNS_TLD, strlen(GNUNET_GNS_TLD));
876
877 gns_resolver_lookup_record(rh->authority,
878 rlh->record_type,
879 new_name,
880 rh->priv_key,
881 GNUNET_TIME_UNIT_FOREVER_REL,
882 &background_lookup_result_processor,
883 NULL);
884
885 GNUNET_DHT_get_stop (rh->get_handle);
886
777 rh->proc(rh->proc_cls, rh, 0, NULL); 887 rh->proc(rh->proc_cls, rh, 0, NULL);
778} 888}
779 889
@@ -829,9 +939,15 @@ process_delegation_result_dht(void* cls,
829 939
830 /* stop dht lookup and timeout task */ 940 /* stop dht lookup and timeout task */
831 GNUNET_DHT_get_stop (rh->get_handle); 941 GNUNET_DHT_get_stop (rh->get_handle);
832 GNUNET_SCHEDULER_cancel(rh->dht_timeout_task);
833 942
834 rh->get_handle = NULL; 943 rh->get_handle = NULL;
944
945 if (rh->dht_heap_node != NULL)
946 {
947 GNUNET_CONTAINER_heap_remove_node(rh->dht_heap_node);
948 rh->dht_heap_node = NULL;
949 }
950
835 num_records = ntohl(nrb->rd_count); 951 num_records = ntohl(nrb->rd_count);
836 name = (char*)&nrb[1]; 952 name = (char*)&nrb[1];
837 { 953 {
@@ -1132,6 +1248,7 @@ handle_record_ns(void* cls, struct ResolverHandle *rh,
1132 "Record resolved from namestore!"); 1248 "Record resolved from namestore!");
1133 1249
1134 finish_lookup(rh, rlh, rd_count, rd); 1250 finish_lookup(rh, rlh, rd_count, rd);
1251
1135 free_resolver_handle(rh); 1252 free_resolver_handle(rh);
1136 1253
1137} 1254}
@@ -1289,6 +1406,7 @@ resolve_delegation_dht(struct ResolverHandle *rh)
1289 GNUNET_HashCode name_hash_double; 1406 GNUNET_HashCode name_hash_double;
1290 GNUNET_HashCode zone_hash_double; 1407 GNUNET_HashCode zone_hash_double;
1291 GNUNET_HashCode lookup_key; 1408 GNUNET_HashCode lookup_key;
1409 struct ResolverHandle *rh_heap_root;
1292 1410
1293 GNUNET_CRYPTO_short_hash(rh->authority_name, 1411 GNUNET_CRYPTO_short_hash(rh->authority_name,
1294 strlen(rh->authority_name), 1412 strlen(rh->authority_name),
@@ -1296,13 +1414,38 @@ resolve_delegation_dht(struct ResolverHandle *rh)
1296 GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double); 1414 GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double);
1297 GNUNET_CRYPTO_short_hash_double(&rh->authority, &zone_hash_double); 1415 GNUNET_CRYPTO_short_hash_double(&rh->authority, &zone_hash_double);
1298 GNUNET_CRYPTO_hash_xor(&name_hash_double, &zone_hash_double, &lookup_key); 1416 GNUNET_CRYPTO_hash_xor(&name_hash_double, &zone_hash_double, &lookup_key);
1417
1418 rh->dht_heap_node = NULL;
1299 1419
1300 rh->dht_timeout_task = GNUNET_SCHEDULER_add_delayed (DHT_LOOKUP_TIMEOUT, 1420 if (rh->timeout.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value)
1301 &dht_authority_lookup_timeout, 1421 {
1302 rh); 1422 //rh->timeout_task = GNUNET_SCHEDULER_add_delayed (DHT_LOOKUP_TIMEOUT,
1303 1423 // &dht_authority_lookup_timeout,
1304 xquery = htonl(GNUNET_GNS_RECORD_PKEY); 1424 // rh);
1425 rh->timeout_cont = &dht_authority_lookup_timeout;
1426 rh->timeout_cont_cls = rh;
1427 }
1428 else
1429 {
1430 if (GNUNET_GNS_MAX_PARALLEL_LOOKUPS >
1431 GNUNET_CONTAINER_heap_get_size (dht_lookup_heap))
1432 {
1433 /* terminate oldest lookup */
1434 rh_heap_root = GNUNET_CONTAINER_heap_remove_root (dht_lookup_heap);
1435 GNUNET_DHT_get_stop(rh_heap_root->get_handle);
1436 rh_heap_root->dht_heap_node = NULL;
1437 rh_heap_root->proc(rh_heap_root->proc_cls,
1438 rh_heap_root,
1439 0,
1440 NULL);
1441 }
1442 rh->dht_heap_node = GNUNET_CONTAINER_heap_insert (dht_lookup_heap,
1443 rh,
1444 GNUNET_TIME_absolute_get().abs_value);
1445 }
1305 1446
1447 xquery = htonl(GNUNET_GNS_RECORD_PKEY);
1448
1306 rh->get_handle = GNUNET_DHT_get_start(dht_handle, 1449 rh->get_handle = GNUNET_DHT_get_start(dht_handle,
1307 DHT_OPERATION_TIMEOUT, 1450 DHT_OPERATION_TIMEOUT,
1308 GNUNET_BLOCK_TYPE_GNS_NAMERECORD, 1451 GNUNET_BLOCK_TYPE_GNS_NAMERECORD,
@@ -1574,12 +1717,13 @@ gns_resolver_lookup_record(struct GNUNET_CRYPTO_ShortHashCode zone,
1574 uint32_t record_type, 1717 uint32_t record_type,
1575 const char* name, 1718 const char* name,
1576 struct GNUNET_CRYPTO_RsaPrivateKey *key, 1719 struct GNUNET_CRYPTO_RsaPrivateKey *key,
1720 struct GNUNET_TIME_Relative timeout,
1577 RecordLookupProcessor proc, 1721 RecordLookupProcessor proc,
1578 void* cls) 1722 void* cls)
1579{ 1723{
1580 struct ResolverHandle *rh; 1724 struct ResolverHandle *rh;
1581 struct RecordLookupHandle* rlh; 1725 struct RecordLookupHandle* rlh;
1582 char string_hash[MAX_DNS_NAME_LENGTH]; //FIXME name len as soon as shorthash 1726 char string_hash[MAX_DNS_LABEL_LENGTH];
1583 1727
1584 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1728 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1585 "Starting resolution for %s (type=%d)!\n", 1729 "Starting resolution for %s (type=%d)!\n",
@@ -1600,6 +1744,19 @@ gns_resolver_lookup_record(struct GNUNET_CRYPTO_ShortHashCode zone,
1600 rh->authority = zone; 1744 rh->authority = zone;
1601 rh->proc_cls = rlh; 1745 rh->proc_cls = rlh;
1602 rh->priv_key = key; 1746 rh->priv_key = key;
1747 rh->timeout = timeout;
1748 if (timeout.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value)
1749 {
1750 rh->timeout_task = GNUNET_SCHEDULER_add_delayed(timeout,
1751 &handle_lookup_timeout,
1752 rh);
1753 rh->timeout_cont = &handle_auth_discovery_timeout;
1754 rh->timeout_cont_cls = rh;
1755 }
1756 else
1757 {
1758 rh->timeout_task = GNUNET_SCHEDULER_NO_TASK;
1759 }
1603 1760
1604 if (strcmp(GNUNET_GNS_TLD, name) == 0) 1761 if (strcmp(GNUNET_GNS_TLD, name) == 0)
1605 { 1762 {