diff options
Diffstat (limited to 'src/gns/gnunet-service-gns_resolver.c')
-rw-r--r-- | src/gns/gnunet-service-gns_resolver.c | 187 |
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; | |||
55 | static struct GNUNET_DHT_Handle *dht_handle; | 55 | static struct GNUNET_DHT_Handle *dht_handle; |
56 | 56 | ||
57 | /** | 57 | /** |
58 | * Heap for parallel DHT lookups | ||
59 | */ | ||
60 | static 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 | */ | ||
457 | static void | ||
458 | background_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 | |||
450 | dht_lookup_timeout(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 474 | dht_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 | ||
830 | static void | ||
831 | handle_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 | { |