X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fgns%2Fgnunet-service-gns_resolver.c;h=7258f97a145db1d532cbae4ff7b4955ebdffe7c2;hb=9062e2e68f6675e65d45a1cc0d4cf7beac1ab007;hp=b6bc5eb1d8dfbfc5d73fab746fe46827fe1a1151;hpb=0970f98adb25e2ec8076ddf61b3437b5003af0b2;p=oweals%2Fgnunet.git diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c index b6bc5eb1d..7258f97a1 100644 --- a/src/gns/gnunet-service-gns_resolver.c +++ b/src/gns/gnunet-service-gns_resolver.c @@ -19,8 +19,6 @@ */ /** - * - * * @file gns/gnunet-service-gns_resolver.c * @brief GNUnet GNS resolver logic * @author Martin Schanzenbach @@ -35,6 +33,7 @@ #include "gnunet_dns_service.h" #include "gnunet_resolver_service.h" #include "gnunet_dnsparser_lib.h" +#include "../dns/dnsparser.h" #include "gnunet_gns_service.h" #include "block_gns.h" #include "gns.h" @@ -65,11 +64,21 @@ static struct GNUNET_DHT_Handle *dht_handle; */ static struct GNUNET_CONTAINER_Heap *dht_lookup_heap; +/** + * Heap for namestore queues + */ +static struct GNUNET_CONTAINER_Heap *ns_task_heap; + /** * Maximum amount of parallel queries in background */ static unsigned long long max_allowed_background_queries; +/** + * Maximum amount of parallel namestore tasks in background + */ +static unsigned long long max_allowed_ns_tasks; + /** * Wheather or not to ignore pending records */ @@ -90,6 +99,41 @@ static struct GetPseuAuthorityHandle *gph_head; */ static struct GetPseuAuthorityHandle *gph_tail; +/** + * Resolver lookup list + */ +static struct ResolverHandle *rlh_head; + +/** + * Resolver lookup list + */ +static struct ResolverHandle *rlh_tail; + +/** + * Resolver shorten list + */ +static struct ResolverHandle *nsh_head; + +/** + * Resolver shorten list + */ +static struct ResolverHandle *nsh_tail; + +/** + * Resolver get auth list + */ +static struct ResolverHandle *nah_head; + +/** + * Resolver get auth list + */ +static struct ResolverHandle *nah_tail; + +/** + * Global configuration. + */ +static const struct GNUNET_CONFIGURATION_Handle *cfg; + /** * a resolution identifier pool variable * FIXME overflow? @@ -97,6 +141,39 @@ static struct GetPseuAuthorityHandle *gph_tail; */ static unsigned long long rid = 0; +/* + * Check if name is in srv format (_x._y.xxx) + * + * @param name + * @return GNUNET_YES if true + */ +static int +is_srv (char* name) +{ + char* ndup; + int ret = GNUNET_YES; + + if (*name != '_') + return GNUNET_NO; + if (NULL == strstr (name, "._")) + return GNUNET_NO; + + ndup = GNUNET_strdup (name); + strtok (ndup, "."); + + if (NULL == strtok (NULL, ".")) + ret = GNUNET_NO; + + if (NULL == strtok (NULL, ".")) + ret = GNUNET_NO; + + if (NULL != strtok (NULL, ".")) + ret = GNUNET_NO; + + GNUNET_free (ndup); + + return ret; +} /** * Determine if this name is canonical. @@ -105,20 +182,29 @@ static unsigned long long rid = 0; * a = canonical * * @param name the name to test - * @return 1 if canonical + * @return GNUNET_YES if canonical */ static int -is_canonical(char* name) +is_canonical (char* name) { - uint32_t len = strlen(name); - int i; + char* ndup; + char* tok; - for (i=0; inamestore_task = NULL; + do + { + iter = gph->ahead->next; + GNUNET_free (gph->ahead); + gph->ahead = iter; + } while (iter != NULL); + GNUNET_CRYPTO_rsa_key_free (gph->key); + GNUNET_CONTAINER_DLL_remove (gph_head, gph_tail, gph); + GNUNET_free (gph); +} + + /** * Namestore calls this function if we have record for this name. * (or with rd_count=0 to indicate no matches) @@ -155,6 +261,7 @@ process_pseu_lookup_ns (void* cls, struct GNUNET_NAMESTORE_RecordData new_pkey; struct AuthorityChain *iter; + gph->namestore_task = NULL; if (rd_count > 0) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, @@ -191,7 +298,7 @@ process_pseu_lookup_ns (void* cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNS_AUTO_PSEU: Trying delegated name %s\n", gph->name); memcpy (gph->test_name, gph->name, strlen (gph->name)+1); - GNUNET_NAMESTORE_lookup_record (namestore_handle, + gph->namestore_task = GNUNET_NAMESTORE_lookup_record (namestore_handle, &gph->our_zone, gph->test_name, GNUNET_NAMESTORE_TYPE_ANY, @@ -200,33 +307,23 @@ process_pseu_lookup_ns (void* cls, return; } - /** name is free */ + /* name is free */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNS_AUTO_PSEU: Name %s not taken in NS! Adding\n", gph->test_name); - new_pkey.expiration = GNUNET_TIME_UNIT_FOREVER_ABS; + new_pkey.expiration_time = UINT64_MAX; new_pkey.data_size = sizeof (struct GNUNET_CRYPTO_ShortHashCode); new_pkey.data = &gph->ahead->zone; new_pkey.record_type = GNUNET_GNS_RECORD_PKEY; new_pkey.flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_PRIVATE | GNUNET_NAMESTORE_RF_PENDING; - GNUNET_NAMESTORE_record_create (namestore_handle, + gph->namestore_task = GNUNET_NAMESTORE_record_create (namestore_handle, gph->key, gph->test_name, &new_pkey, - NULL, //cont - NULL); //cls - do - { - iter = gph->ahead->next; - GNUNET_free (gph->ahead); - gph->ahead = iter; - } while (iter != NULL); - GNUNET_CRYPTO_rsa_key_free (gph->key); - GNUNET_CONTAINER_DLL_remove (gph_head, gph_tail, gph); - GNUNET_free (gph); - + &create_pseu_cont, //cont + gph); //cls } /** @@ -254,7 +351,7 @@ process_pseu_result (struct GetPseuAuthorityHandle* gph, char* name) /** * Check for collision */ - GNUNET_NAMESTORE_lookup_record (namestore_handle, + gph->namestore_task = GNUNET_NAMESTORE_lookup_record (namestore_handle, &gph->our_zone, gph->test_name, GNUNET_NAMESTORE_TYPE_ANY, @@ -444,6 +541,7 @@ process_auth_discovery_ns_result(void* cls, struct GetPseuAuthorityHandle* gph = (struct GetPseuAuthorityHandle*)cls; struct AuthorityChain *iter; + gph->namestore_task = NULL; /* no pseu found */ if (rd_count == 0) { @@ -532,7 +630,8 @@ process_zone_to_name_discover (void *cls, { struct GetPseuAuthorityHandle* gph = (struct GetPseuAuthorityHandle*)cls; struct AuthorityChain *iter; - + + gph->namestore_task = NULL; /* we found a match in our own zone */ if (rd_len != 0) { @@ -553,7 +652,7 @@ process_zone_to_name_discover (void *cls, else { - GNUNET_NAMESTORE_lookup_record (namestore_handle, + gph->namestore_task = GNUNET_NAMESTORE_lookup_record (namestore_handle, &gph->ahead->zone, "+", GNUNET_GNS_RECORD_PSEU, @@ -577,7 +676,7 @@ shorten_authority_chain (struct GetPseuAuthorityHandle *gph) "GNS_AUTO_PSEU: New authority %s discovered\n", gph->ahead->name); - GNUNET_NAMESTORE_zone_to_name (namestore_handle, + gph->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle, &gph->our_zone, &gph->ahead->zone, &process_zone_to_name_discover, @@ -631,43 +730,44 @@ start_shorten (struct AuthorityChain *atail, * @param nh the namestore handle * @param dh the dht handle * @param lz the local zone's hash + * @param c configuration handle * @param max_bg_queries maximum number of parallel background queries in dht * @param ignore_pending ignore records that still require user confirmation * on lookup * @return GNUNET_OK on success */ int -gns_resolver_init(struct GNUNET_NAMESTORE_Handle *nh, - struct GNUNET_DHT_Handle *dh, - struct GNUNET_CRYPTO_ShortHashCode lz, - const struct GNUNET_CONFIGURATION_Handle *cfg, - unsigned long long max_bg_queries, - int ignore_pending) +gns_resolver_init (struct GNUNET_NAMESTORE_Handle *nh, + struct GNUNET_DHT_Handle *dh, + struct GNUNET_CRYPTO_ShortHashCode lz, + const struct GNUNET_CONFIGURATION_Handle *c, + unsigned long long max_bg_queries, + int ignore_pending) { + cfg = c; namestore_handle = nh; dht_handle = dh; local_zone = lz; dht_lookup_heap = GNUNET_CONTAINER_heap_create(GNUNET_CONTAINER_HEAP_ORDER_MIN); + ns_task_heap = + GNUNET_CONTAINER_heap_create(GNUNET_CONTAINER_HEAP_ORDER_MIN); max_allowed_background_queries = max_bg_queries; + max_allowed_ns_tasks = GNUNET_GNS_MAX_NS_TASKS; + ignore_pending_records = ignore_pending; gph_head = NULL; gph_tail = NULL; - + rlh_head = NULL; + rlh_tail = NULL; + nsh_head = NULL; + nsh_tail = NULL; + nah_head = NULL; + nah_tail = NULL; + GNUNET_RESOLVER_connect (cfg); - if (NULL == vpn_handle) - { - vpn_handle = GNUNET_VPN_connect (cfg); - if (NULL == vpn_handle) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_INIT: Error connecting to VPN!\n"); - - return GNUNET_SYSERR; - } - } if ((namestore_handle != NULL) && (dht_handle != NULL)) { @@ -677,8 +777,55 @@ gns_resolver_init(struct GNUNET_NAMESTORE_Handle *nh, return GNUNET_SYSERR; } + /** - * Cleanup background lookups + * Cleanup ns tasks + * + * @param cls closure to iterator + * @param node heap nodes + * @param element the namestorebgtask + * @param cost heap cost + * @return always GNUNET_YES + */ +static int +cleanup_pending_ns_tasks(void* cls, + struct GNUNET_CONTAINER_HeapNode *node, + void *element, + GNUNET_CONTAINER_HeapCostType cost) +{ + struct NamestoreBGTask *nbg = (struct NamestoreBGTask *)element; + ResolverCleanupContinuation cont = cls; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_CLEANUP: Terminating ns task\n"); + GNUNET_NAMESTORE_cancel (nbg->qe); + + GNUNET_CONTAINER_heap_remove_node(node); + + if (GNUNET_CONTAINER_heap_get_size(ns_task_heap) == 0) + cont(); + + return GNUNET_YES; +} + + +/** + * finish lookup + * + * @param rh resolver handle + * @param rlh record lookup handle + * @param rd_count number of results + * @param rd results + */ +static void +finish_lookup (struct ResolverHandle *rh, + struct RecordLookupHandle* rlh, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd); + + +/** + * Cleanup background lookups FIXME get rid of this?? * * @param cls closure to iterator * @param node heap nodes @@ -687,10 +834,10 @@ gns_resolver_init(struct GNUNET_NAMESTORE_Handle *nh, * @return always GNUNET_YES */ static int -cleanup_pending_background_queries(void* cls, - struct GNUNET_CONTAINER_HeapNode *node, - void *element, - GNUNET_CONTAINER_HeapCostType cost) +cleanup_pending_background_queries (void* cls, + struct GNUNET_CONTAINER_HeapNode *node, + void *element, + GNUNET_CONTAINER_HeapCostType cost) { struct ResolverHandle *rh = (struct ResolverHandle *)element; ResolverCleanupContinuation cont = cls; @@ -698,32 +845,108 @@ cleanup_pending_background_queries(void* cls, GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GNS_CLEANUP-%llu: Terminating background lookup for %s\n", rh->id, rh->name); - GNUNET_DHT_get_stop(rh->get_handle); - rh->get_handle = NULL; - rh->proc(rh->proc_cls, rh, 0, NULL); + + //finish_lookup (rh, rh->proc_cls, 0, NULL); + //rh->get_handle = NULL; + //rh->proc(rh->proc_cls, rh, 0, NULL); GNUNET_CONTAINER_heap_remove_node(node); if (GNUNET_CONTAINER_heap_get_size(dht_lookup_heap) == 0) - cont(); + { + if (GNUNET_CONTAINER_heap_get_size(ns_task_heap) == 0) + cont(); + else + { + GNUNET_CONTAINER_heap_iterate (ns_task_heap, + &cleanup_pending_ns_tasks, + cont); + } + } return GNUNET_YES; } +/** + * Helper function to free resolver handle + * + * @param rh the handle to free + */ +static void +free_resolver_handle (struct ResolverHandle* rh) +{ + struct AuthorityChain *ac; + struct AuthorityChain *ac_next; + + if (NULL == rh) + return; + + ac = rh->authority_chain_head; + + while (NULL != ac) + { + ac_next = ac->next; + GNUNET_free(ac); + ac = ac_next; + } + + if (NULL != rh->get_handle) + GNUNET_DHT_get_stop (rh->get_handle); + + if (NULL != rh->dns_raw_packet) + GNUNET_free (rh->dns_raw_packet); + + if (NULL != rh->namestore_task) + GNUNET_NAMESTORE_cancel (rh->namestore_task); + rh->namestore_task = NULL; + + if (GNUNET_SCHEDULER_NO_TASK != rh->dns_read_task) + GNUNET_SCHEDULER_cancel (rh->dns_read_task); + + if (GNUNET_SCHEDULER_NO_TASK != rh->timeout_task) + GNUNET_SCHEDULER_cancel (rh->timeout_task); + + if (NULL != rh->dns_sock) + GNUNET_NETWORK_socket_close (rh->dns_sock); + if (NULL != rh->dns_resolver_handle) + GNUNET_RESOLVER_request_cancel (rh->dns_resolver_handle); + + if (NULL != rh->rd.data) + GNUNET_free ((void*)(rh->rd.data)); + GNUNET_free(rh); +} + + +/** + * finish shorten + * + * @param rh resolver handle + * @param nsh name shorten handle + */ +static void +finish_shorten (struct ResolverHandle *rh, + struct NameShortenHandle *nsh); +/** + * finish get auth + * + * @param rh resolver handle + * @param nah get name authority handle + */ +static void +finish_get_auth (struct ResolverHandle *rh, + struct GetNameAuthorityHandle* rlh); /** * Shutdown resolver */ void -gns_resolver_cleanup(ResolverCleanupContinuation cont) +gns_resolver_cleanup (ResolverCleanupContinuation cont) { - unsigned int s = GNUNET_CONTAINER_heap_get_size(dht_lookup_heap); + unsigned int s; struct GetPseuAuthorityHandle *tmp; struct AuthorityChain *iter; - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_CLEANUP: %d pending background queries to terminate\n", s); tmp = gph_head; for (tmp = gph_head; tmp != NULL; tmp = gph_head) @@ -734,6 +957,10 @@ gns_resolver_cleanup(ResolverCleanupContinuation cont) if (tmp->timeout != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (tmp->timeout); tmp->timeout = GNUNET_SCHEDULER_NO_TASK; + + if (NULL != tmp->namestore_task) + GNUNET_NAMESTORE_cancel (tmp->namestore_task); + tmp->namestore_task = NULL; iter = tmp->ahead; do @@ -747,45 +974,40 @@ gns_resolver_cleanup(ResolverCleanupContinuation cont) GNUNET_CONTAINER_DLL_remove (gph_head, gph_tail, tmp); GNUNET_free (tmp); } + + while (NULL != rlh_head) + { + finish_lookup (rlh_head, rlh_head->proc_cls, 0, NULL); + } - + while (NULL != nsh_head) + { + finish_shorten (nsh_head, nsh_head->proc_cls); + } + + while (NULL != nah_head) + { + finish_get_auth (nah_head, nah_head->proc_cls); + } + + s = GNUNET_CONTAINER_heap_get_size(dht_lookup_heap); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_CLEANUP: %d pending background queries to terminate\n", s); if (0 != s) GNUNET_CONTAINER_heap_iterate (dht_lookup_heap, &cleanup_pending_background_queries, cont); + else if (0 != GNUNET_CONTAINER_heap_get_size(ns_task_heap)) + { + GNUNET_CONTAINER_heap_iterate (ns_task_heap, + &cleanup_pending_ns_tasks, + cont); + } else cont(); } -/** - * Helper function to free resolver handle - * - * @param rh the handle to free - */ -static void -free_resolver_handle(struct ResolverHandle* rh) -{ - struct AuthorityChain *ac; - struct AuthorityChain *ac_next; - - if (NULL == rh) - return; - - ac = rh->authority_chain_head; - - while (NULL != ac) - { - ac_next = ac->next; - GNUNET_free(ac); - ac = ac_next; - } - - if (NULL != rh->dns_raw_packet) - GNUNET_free (rh->dns_raw_packet); - - GNUNET_free(rh); -} /** @@ -800,6 +1022,11 @@ on_namestore_record_put_result(void *cls, int32_t success, const char *emsg) { + struct NamestoreBGTask *nbg = cls; + + GNUNET_CONTAINER_heap_remove_node (nbg->node); + GNUNET_free (nbg); + if (GNUNET_NO == success) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, @@ -858,7 +1085,7 @@ dht_lookup_timeout(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) char new_name[MAX_DNS_NAME_LENGTH]; GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: dht lookup for query %s (%ds)timed out.\n", + "GNS_PHASE_REC-%llu: dht lookup for query %s (%llus)timed out.\n", rh->id, rh->name, rh->timeout.rel_value); /** * Start resolution in bg @@ -869,14 +1096,14 @@ dht_lookup_timeout(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) rh->name, GNUNET_GNS_TLD); GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Starting background lookup for %s type %d\n", + "GNS_PHASE_REC-%llu: Starting background lookup for %s type %d\n", rh->id, new_name, rlh->record_type); gns_resolver_lookup_record(rh->authority, rh->private_local_zone, rlh->record_type, new_name, - rh->priv_key, + NULL, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &background_lookup_result_processor, @@ -926,7 +1153,7 @@ process_record_result_dht(void* cls, rh = (struct ResolverHandle *)cls; GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: got dht result (size=%d)\n", rh->id, size); + "GNS_PHASE_REC-%llu: got dht result (size=%d)\n", rh->id, size); //FIXME maybe check expiration here, check block type @@ -955,6 +1182,8 @@ process_record_result_dht(void* cls, num_records = ntohl(nrb->rd_count); { struct GNUNET_NAMESTORE_RecordData rd[num_records]; + struct NamestoreBGTask *ns_heap_root; + struct NamestoreBGTask *namestore_bg_task; rd_data += strlen(name) + 1 + sizeof(struct GNSNameRecordBlock); rd_size = size - strlen(name) - 1 - sizeof(struct GNSNameRecordBlock); @@ -965,23 +1194,23 @@ process_record_result_dht(void* cls, rd)) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, - "GNS_PHASE_REC-%d: Error deserializing data!\n", rh->id); + "GNS_PHASE_REC-%llu: Error deserializing data!\n", rh->id); return; } for (i=0; iid, name, rh->name); GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Got type: %d (wanted %d)\n", + "GNS_PHASE_REC-%llu: Got type: %d (wanted %d)\n", rh->id, rd[i].record_type, rlh->record_type); GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Got data length: %d\n", + "GNS_PHASE_REC-%llu: Got data length: %d\n", rh->id, rd[i].data_size); GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Got flag %d\n", + "GNS_PHASE_REC-%llu: Got flag %d\n", rh->id, rd[i].flags); if ((strcmp(name, rh->name) == 0) && @@ -996,9 +1225,20 @@ process_record_result_dht(void* cls, * FIXME check pubkey against existing key in namestore? * https://gnunet.org/bugs/view.php?id=2179 */ + if (max_allowed_ns_tasks <= + GNUNET_CONTAINER_heap_get_size (ns_task_heap)) + { + ns_heap_root = GNUNET_CONTAINER_heap_remove_root (ns_task_heap); + GNUNET_NAMESTORE_cancel (ns_heap_root->qe); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%llu: Replacing oldest background ns task\n", + rh->id); + } + /* Save to namestore */ - GNUNET_NAMESTORE_record_put (namestore_handle, + namestore_bg_task = GNUNET_malloc (sizeof (struct NamestoreBGTask)); + namestore_bg_task->qe = GNUNET_NAMESTORE_record_put (namestore_handle, &nrb->public_key, name, exp, @@ -1006,13 +1246,17 @@ process_record_result_dht(void* cls, rd, &nrb->signature, &on_namestore_record_put_result, //cont - NULL); //cls + namestore_bg_task); + namestore_bg_task->node = GNUNET_CONTAINER_heap_insert (ns_task_heap, + namestore_bg_task, + GNUNET_TIME_absolute_get().abs_value); + if (rh->answered) - rh->proc(rh->proc_cls, rh, num_records, rd); - else - rh->proc(rh->proc_cls, rh, 0, NULL); + rh->proc(rh->proc_cls, rh, num_records, rd); + else + rh->proc(rh->proc_cls, rh, 0, NULL); } } @@ -1043,7 +1287,7 @@ resolve_record_dht (struct ResolverHandle *rh) GNUNET_CRYPTO_hash_to_enc (&lookup_key, &lookup_key_string); GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: starting dht lookup for %s with key: %s\n", + "GNS_PHASE_REC-%llu: starting dht lookup for %s with key: %s\n", rh->id, rh->name, (char*)&lookup_key_string); //rh->timeout_task = GNUNET_SCHEDULER_NO_TASK; @@ -1058,7 +1302,7 @@ resolve_record_dht (struct ResolverHandle *rh) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Adjusting timeout\n", rh->id); + "GNS_PHASE_REC-%llu: Adjusting timeout\n", rh->id); /* * Set timeout for authority lookup phase to 1/2 */ @@ -1084,7 +1328,7 @@ resolve_record_dht (struct ResolverHandle *rh) rh_heap_root->dht_heap_node = NULL; GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Replacing oldest background query for %s\n", + "GNS_PHASE_REC-%llu: Replacing oldest background query for %s\n", rh->id, rh_heap_root->name); rh_heap_root->proc(rh_heap_root->proc_cls, rh_heap_root, @@ -1125,20 +1369,24 @@ resolve_record_dht (struct ResolverHandle *rh) * @param signature the signature of the authority for the record data */ static void -process_record_result_ns(void* cls, - const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key, - struct GNUNET_TIME_Absolute expiration, - const char *name, unsigned int rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd, - const struct GNUNET_CRYPTO_RsaSignature *signature) +process_record_result_ns (void* cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key, + struct GNUNET_TIME_Absolute expiration, + const char *name, unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) { struct ResolverHandle *rh; struct RecordLookupHandle *rlh; struct GNUNET_TIME_Relative remaining_time; struct GNUNET_CRYPTO_ShortHashCode zone; + struct GNUNET_TIME_Absolute et; + unsigned int i; rh = (struct ResolverHandle *) cls; rlh = (struct RecordLookupHandle *)rh->proc_cls; + + rh->namestore_task = NULL; GNUNET_CRYPTO_short_hash(key, sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone); @@ -1164,11 +1412,11 @@ process_record_result_ns(void* cls, * Lookup terminated and no results */ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Namestore lookup for %s terminated without results\n", + "GNS_PHASE_REC-%llu: Namestore lookup for %s terminated without results\n", rh->id, name); GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Record %s unknown in namestore\n", + "GNS_PHASE_REC-%llu: Record %s unknown in namestore\n", rh->id, rh->name); /** * Our zone and no result? Cannot resolve TT @@ -1179,14 +1427,11 @@ process_record_result_ns(void* cls, } else { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Processing additional result %s from namestore\n", + "GNS_PHASE_REC-%llu: Processing additional result %s from namestore\n", rh->id, name); - int i; for (i=0; irecord_type) continue; @@ -1194,22 +1439,22 @@ process_record_result_ns(void* cls, (rd[i].flags & GNUNET_NAMESTORE_RF_PENDING)) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Record %s is awaiting user confirmation. Skipping\n", + "GNS_PHASE_REC-%llu: Record %s is awaiting user confirmation. Skipping\n", rh->id, name); continue; } - if ((GNUNET_TIME_absolute_get_remaining (rd[i].expiration)).rel_value + GNUNET_break (0 == (rd[i].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION)); + et.abs_value = rd[i].expiration_time; + if ((GNUNET_TIME_absolute_get_remaining (et)).rel_value == 0) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: This record is expired. Skipping\n", + "GNS_PHASE_REC-%llu: This record is expired. Skipping\n", rh->id); continue; } - rh->answered++; - } /** @@ -1218,13 +1463,13 @@ process_record_result_ns(void* cls, if (rh->answered == 0) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: No answers found. This is odd!\n", rh->id); + "GNS_PHASE_REC-%llu: No answers found. This is odd!\n", rh->id); rh->proc(rh->proc_cls, rh, 0, NULL); return; } GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Found %d answer(s) to query in %d records!\n", + "GNS_PHASE_REC-%llu: Found %d answer(s) to query in %d records!\n", rh->id, rh->answered, rd_count); rh->proc(rh->proc_cls, rh, rd_count, rd); @@ -1249,23 +1494,23 @@ process_record_result_vpn (void* cls, int af, const void *address) rlh = (struct RecordLookupHandle *)rh->proc_cls; GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC_VPN-%d: Got answer from VPN to query!\n", + "GNS_PHASE_REC_VPN-%llu: Got answer from VPN to query!\n", rh->id); if (af == AF_INET) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Answer is IPv4!\n", + "GNS_PHASE_REC-%llu: Answer is IPv4!\n", rh->id); - if (rlh->record_type != GNUNET_GNS_RECORD_TYPE_A) + if (rlh->record_type != GNUNET_GNS_RECORD_A) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Requested record is not IPv4!\n", + "GNS_PHASE_REC-%llu: Requested record is not IPv4!\n", rh->id); rh->proc (rh->proc_cls, rh, 0, NULL); return; } - rd.record_type = GNUNET_GNS_RECORD_TYPE_A; - rd.expiration = GNUNET_TIME_UNIT_FOREVER_ABS; + rd.record_type = GNUNET_GNS_RECORD_A; + rd.expiration_time = UINT64_MAX; /* FIXME: should probably pick something shorter... */ rd.data = address; rd.data_size = sizeof (struct in_addr); rd.flags = 0; @@ -1275,18 +1520,18 @@ process_record_result_vpn (void* cls, int af, const void *address) else if (af == AF_INET6) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Answer is IPv6!\n", + "GNS_PHASE_REC-%llu: Answer is IPv6!\n", rh->id); if (rlh->record_type != GNUNET_GNS_RECORD_AAAA) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Requested record is not IPv6!\n", + "GNS_PHASE_REC-%llu: Requested record is not IPv6!\n", rh->id); rh->proc (rh->proc_cls, rh, 0, NULL); return; } rd.record_type = GNUNET_GNS_RECORD_AAAA; - rd.expiration = GNUNET_TIME_UNIT_FOREVER_ABS; + rd.expiration_time = UINT64_MAX; /* FIXME: should probably pick something shorter... */ rd.data = address; rd.data_size = sizeof (struct in6_addr); rd.flags = 0; @@ -1295,25 +1540,13 @@ process_record_result_vpn (void* cls, int af, const void *address) } GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Got garbage from VPN!\n", + "GNS_PHASE_REC-%llu: Got garbage from VPN!\n", rh->id); rh->proc (rh->proc_cls, rh, 0, NULL); } -/** - * finish lookup - * - * @param rh resolver handle - * @param rlh record lookup handle - * @param rd_count number of results - * @param rd results - */ -static void -finish_lookup(struct ResolverHandle *rh, - struct RecordLookupHandle* rlh, - unsigned int rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd); + /** * Process VPN lookup result for record @@ -1333,22 +1566,19 @@ handle_record_vpn (void* cls, struct ResolverHandle *rh, if (rd_count == 0) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC_VPN-%d: VPN returned no records. (status: %d)!\n", + "GNS_PHASE_REC_VPN-%llu: VPN returned no records. (status: %d)!\n", rh->id, rh->status); /* give up, cannot resolve */ finish_lookup(rh, rlh, 0, NULL); - free_resolver_handle(rh); return; } /* results found yay */ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC_VPN-%d: Record resolved from VPN!", rh->id); + "GNS_PHASE_REC_VPN-%llu: Record resolved from VPN!", rh->id); finish_lookup(rh, rlh, rd_count, rd); - - free_resolver_handle(rh); } @@ -1360,6 +1590,7 @@ handle_record_vpn (void* cls, struct ResolverHandle *rh, static void send_dns_packet (struct ResolverHandle *rh); + static void handle_dns_resolver (void *cls, const struct sockaddr *addr, @@ -1376,14 +1607,13 @@ handle_dns_resolver (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No address found in DNS!\n"); finish_lookup (rh, rlh, 0, NULL); - free_resolver_handle (rh); return; } if (addrlen == sizeof (struct sockaddr_in)) { sai = (struct sockaddr_in*) addr; - rd.record_type = GNUNET_GNS_RECORD_TYPE_A; + rd.record_type = GNUNET_GNS_RECORD_A; rd.data_size = sizeof (struct in_addr); rd.data = &sai->sin_addr; } @@ -1395,11 +1625,11 @@ handle_dns_resolver (void *cls, rd.data = &sai6->sin6_addr; } - rd.expiration = GNUNET_TIME_UNIT_FOREVER_ABS; + rd.expiration_time = UINT64_MAX; /* FIXME: should probably pick something shorter */ + rd.flags = 0; finish_lookup (rh, rlh, 1, &rd); - free_resolver_handle (rh); - GNUNET_RESOLVER_request_cancel (rh->dns_resolver_handle); + } /** @@ -1413,17 +1643,16 @@ resolve_dns_name (struct ResolverHandle *rh) struct RecordLookupHandle *rlh = rh->proc_cls; int af; - if ((rlh->record_type != GNUNET_GNS_RECORD_TYPE_A) && + if ((rlh->record_type != GNUNET_GNS_RECORD_A) && (rlh->record_type != GNUNET_GNS_RECORD_AAAA)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Can only resolve A/AAAA via stub... abort\n"); finish_lookup (rh, rlh, 0, NULL); - free_resolver_handle (rh); return; } - if (rlh->record_type == GNUNET_GNS_RECORD_TYPE_A) + if (rlh->record_type == GNUNET_GNS_RECORD_A) af = AF_INET; else af = AF_INET6; @@ -1467,10 +1696,8 @@ read_dns_response (void *cls, { /* timeout or shutdown */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Terminating DNS query\n"); + "Terminating DNS query %d\n", tc->reason); finish_lookup (rh, rlh, 0, NULL); - GNUNET_NETWORK_socket_close (rh->dns_sock); - free_resolver_handle (rh); return; } @@ -1484,8 +1711,6 @@ read_dns_response (void *cls, { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "recvfrom"); finish_lookup (rh, rlh, 0, NULL); - GNUNET_NETWORK_socket_close (rh->dns_sock); - free_resolver_handle (rh); return; } @@ -1496,8 +1721,6 @@ read_dns_response (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to parse DNS reply!\n"); finish_lookup (rh, rlh, 0, NULL); - GNUNET_NETWORK_socket_close (rh->dns_sock); - free_resolver_handle (rh); return; } @@ -1508,7 +1731,7 @@ read_dns_response (void *cls, packet->answers[i].type, rlh->record_type); /* http://tools.ietf.org/html/rfc1034#section-3.6.2 */ - if (packet->answers[i].type == GNUNET_GNS_RECORD_TYPE_CNAME) + if (packet->answers[i].type == GNUNET_GNS_RECORD_CNAME) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CNAME... restarting query with %s\n", @@ -1530,11 +1753,9 @@ read_dns_response (void *cls, rd.data_size = packet->answers[i].data.raw.data_len; rd.record_type = packet->answers[i].type; rd.flags = 0; - rd.expiration = packet->answers[i].expiration_time; + rd.expiration_time = packet->answers[i].expiration_time.abs_value; finish_lookup (rh, rlh, 1, &rd); - GNUNET_NETWORK_socket_close (rh->dns_sock); GNUNET_DNSPARSER_free_packet (packet); - free_resolver_handle (rh); return; } } @@ -1567,7 +1788,7 @@ read_dns_response (void *cls, for (i = 0; i < packet->num_authority_records; i++) { - if (packet->authority_records[i].type == GNUNET_GNS_RECORD_TYPE_NS) + if (packet->authority_records[i].type == GNUNET_GNS_RECORD_NS) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found NS delegation!\n"); @@ -1582,7 +1803,7 @@ read_dns_response (void *cls, if (found_delegation == GNUNET_NO) break; - if ((packet->additional_records[i].type == GNUNET_GNS_RECORD_TYPE_A) && + if ((packet->additional_records[i].type == GNUNET_GNS_RECORD_A) && (0 == strcmp (packet->additional_records[i].name, delegation_name))) { GNUNET_assert (sizeof (struct in_addr) == @@ -1599,8 +1820,6 @@ read_dns_response (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Nothing useful in DNS reply!\n"); finish_lookup (rh, rlh, 0, NULL); - GNUNET_NETWORK_socket_close (rh->dns_sock); - free_resolver_handle (rh); GNUNET_DNSPARSER_free_packet (packet); return; } @@ -1615,6 +1834,10 @@ send_dns_packet (struct ResolverHandle *rh) { struct GNUNET_NETWORK_FDSet *rset = GNUNET_NETWORK_fdset_create (); GNUNET_NETWORK_fdset_set (rset, rh->dns_sock); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending %dbyte DNS query\n", + rh->dns_raw_packet_size); GNUNET_NETWORK_socket_sendto (rh->dns_sock, rh->dns_raw_packet, @@ -1654,6 +1877,8 @@ resolve_record_dns (struct ResolverHandle *rh, struct sockaddr *sa; int i; struct RecordLookupHandle *rlh = rh->proc_cls; + + memset (&packet, 0, sizeof (struct GNUNET_DNSPARSER_Packet)); /* We cancel here as to not include the ns lookup in the timeout */ if (rh->timeout_task != GNUNET_SCHEDULER_NO_TASK) @@ -1662,7 +1887,8 @@ resolve_record_dns (struct ResolverHandle *rh, rh->timeout_task = GNUNET_SCHEDULER_NO_TASK; } /* Start shortening */ - if ((rh->priv_key != NULL) && is_canonical (rh->name)) + if ((rh->priv_key != NULL) && + (is_canonical (rh->name) == GNUNET_YES)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_REC_DNS-%llu: Trying to shorten authority chain\n", @@ -1674,7 +1900,7 @@ resolve_record_dns (struct ResolverHandle *rh, for (i = 0; i < rd_count; i++) { /* Synthesize dns name */ - if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_NS) + if (rd[i].record_type == GNUNET_GNS_RECORD_NS) { strcpy (rh->dns_zone, (char*)rd[i].data); if (0 == strcmp (rh->name, "")) @@ -1683,7 +1909,7 @@ resolve_record_dns (struct ResolverHandle *rh, sprintf (rh->dns_name, "%s.%s", rh->name, (char*)rd[i].data); } /* The glue */ - if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_A) + if (rd[i].record_type == GNUNET_GNS_RECORD_A) dnsip = *((struct in_addr*)rd[i].data); } @@ -1699,7 +1925,6 @@ resolve_record_dns (struct ResolverHandle *rh, "GNS_PHASE_REC_DNS-%llu: Error creating udp socket for dns!\n", rh->id); finish_lookup (rh, rlh, 0, NULL); - free_resolver_handle (rh); return; } @@ -1713,9 +1938,7 @@ resolve_record_dns (struct ResolverHandle *rh, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_REC_DNS-%llu: Error binding udp socket for dns!\n", rh->id); - GNUNET_NETWORK_socket_close (rh->dns_sock); finish_lookup (rh, rlh, 0, NULL); - free_resolver_handle (rh); return; } @@ -1745,7 +1968,6 @@ resolve_record_dns (struct ResolverHandle *rh, rh->id); GNUNET_NETWORK_socket_close (rh->dns_sock); finish_lookup (rh, rlh, 0, NULL); - free_resolver_handle (rh); return; } @@ -1773,14 +1995,10 @@ resolve_record_vpn (struct ResolverHandle *rh, int rd_count, const struct GNUNET_NAMESTORE_RecordData *rd) { - int af; - int proto; - struct GNUNET_HashCode peer_id; - struct GNUNET_CRYPTO_HashAsciiEncoded s_pid; + struct RecordLookupHandle *rlh = rh->proc_cls; struct GNUNET_HashCode serv_desc; - struct GNUNET_CRYPTO_HashAsciiEncoded s_sd; - char* pos; - size_t len = (sizeof (uint32_t) * 2) + (sizeof (struct GNUNET_HashCode) * 2); + struct vpn_data* vpn; + int af; /* We cancel here as to not include the ns lookup in the timeout */ if (rh->timeout_task != GNUNET_SCHEDULER_NO_TASK) @@ -1789,7 +2007,8 @@ resolve_record_vpn (struct ResolverHandle *rh, rh->timeout_task = GNUNET_SCHEDULER_NO_TASK; } /* Start shortening */ - if ((rh->priv_key != NULL) && is_canonical (rh->name)) + if ((rh->priv_key != NULL) && + (is_canonical (rh->name) == GNUNET_YES)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_REC_VPN-%llu: Trying to shorten authority chain\n", @@ -1798,38 +2017,23 @@ resolve_record_vpn (struct ResolverHandle *rh, rh->priv_key); } - /* Extracting VPN information FIXME rd parsing with NS API?*/ - if (len != rd->data_size) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC_VPN-%llu: Error parsing VPN RR!\n", - rh->id); - finish_lookup (rh, rh->proc_cls, 0, NULL); - free_resolver_handle (rh); - return; - } - - pos = (char*)rd; - memcpy (&af, pos, sizeof (uint32_t)); - pos += sizeof (uint32_t); - memcpy (&proto, pos, sizeof (uint32_t)); - pos += sizeof (uint32_t); - memcpy (&s_pid, pos, sizeof (struct GNUNET_HashCode)); - pos += sizeof (struct GNUNET_HashCode); - memcpy (&s_sd, pos, sizeof (struct GNUNET_HashCode)); + vpn = (struct vpn_data*)rd->data; - if ((GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char*)&s_pid, &peer_id)) || - (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char*)&s_sd, &serv_desc))) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC_VPN-%llu: Error parsing VPN RR hashes!\n", - rh->id); - finish_lookup (rh, rh->proc_cls, 0, NULL); - free_resolver_handle (rh); - return; - } + GNUNET_CRYPTO_hash ((char*)&vpn[1], + strlen ((char*)&vpn[1]) + 1, + &serv_desc); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC_VPN-%llu: proto %hu peer %s!\n", + rh->id, + ntohs (vpn->proto), + GNUNET_h2s (&vpn->peer)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC_VPN-%llu: service %s -> %s!\n", + rh->id, + (char*)&vpn[1], + GNUNET_h2s (&serv_desc)); rh->proc = &handle_record_vpn; if (NULL == vpn_handle) @@ -1838,19 +2042,36 @@ resolve_record_vpn (struct ResolverHandle *rh, "GNS_PHASE_REC_VPN-%llu: VPN not connected!\n", rh->id); finish_lookup (rh, rh->proc_cls, 0, NULL); - free_resolver_handle (rh); return; } + + if (rlh->record_type == GNUNET_GNS_RECORD_A) + af = AF_INET; + else + af = AF_INET6; //FIXME timeout?? + if (NULL == vpn_handle) + { + vpn_handle = GNUNET_VPN_connect (cfg); + if (NULL == vpn_handle) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_INIT: Error connecting to VPN!\n"); + finish_lookup (rh, rh->proc_cls, 0, NULL); + return; + } + } + + rh->vpn_handle = GNUNET_VPN_redirect_to_peer (vpn_handle, - af, proto, - (struct GNUNET_PeerIdentity*)&peer_id, - &serv_desc, - GNUNET_NO, //nac - GNUNET_TIME_UNIT_FOREVER_ABS, //FIXME - &process_record_result_vpn, - rh); + af, ntohs (vpn->proto), + (struct GNUNET_PeerIdentity *)&vpn->peer, + &serv_desc, + GNUNET_NO, //nac + GNUNET_TIME_UNIT_FOREVER_ABS, //FIXME + &process_record_result_vpn, + rh); } @@ -1873,7 +2094,8 @@ resolve_record_ns(struct ResolverHandle *rh) rh->timeout_task = GNUNET_SCHEDULER_NO_TASK; } /* Start shortening */ - if ((rh->priv_key != NULL) && is_canonical (rh->name)) + if ((rh->priv_key != NULL) && + (is_canonical (rh->name) == GNUNET_YES)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_REC-%llu: Trying to shorten authority chain\n", @@ -1888,7 +2110,7 @@ resolve_record_ns(struct ResolverHandle *rh) * since we tried to resolve it to an authority * and failed. **/ - GNUNET_NAMESTORE_lookup_record(namestore_handle, + rh->namestore_task = GNUNET_NAMESTORE_lookup_record(namestore_handle, &rh->authority, rh->name, rlh->record_type, @@ -1913,14 +2135,16 @@ dht_authority_lookup_timeout(void *cls, char new_name[MAX_DNS_NAME_LENGTH]; GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_DHT-%llu: dht lookup for query %s (%ds)timed out.\n", + "GNS_PHASE_DELEGATE_DHT-%llu: dht lookup for query %s (%llus)timed out.\n", rh->id, rh->authority_name, rh->timeout.rel_value); rh->status |= RSL_TIMED_OUT; rh->timeout_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_DHT_get_stop (rh->get_handle); + if (NULL != rh->get_handle) + GNUNET_DHT_get_stop (rh->get_handle); + rh->get_handle = NULL; if (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) @@ -1961,7 +2185,7 @@ dht_authority_lookup_timeout(void *cls, rh->private_local_zone, rlh->record_type, new_name, - rh->priv_key, + NULL, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &background_lookup_result_processor, @@ -2015,6 +2239,7 @@ process_pkey_revocation_result_ns (void *cls, struct GNUNET_TIME_Relative remaining_time; int i; + rh->namestore_task = NULL; remaining_time = GNUNET_TIME_absolute_get_remaining (expiration); for (i = 0; i < rd_count; i++) @@ -2040,14 +2265,14 @@ process_pkey_revocation_result_ns (void *cls, if (rh->timeout.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_REV-%d: Starting background lookup for %s type %d\n", + "GNS_PHASE_DELEGATE_REV-%llu: Starting background lookup for %s type %d\n", rh->id, "+.gnunet", GNUNET_GNS_RECORD_REV); gns_resolver_lookup_record(rh->authority, rh->private_local_zone, GNUNET_GNS_RECORD_REV, GNUNET_GNS_TLD, - rh->priv_key, + NULL, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &background_lookup_result_processor, @@ -2055,20 +2280,55 @@ process_pkey_revocation_result_ns (void *cls, } } GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_REV-%llu: Revocation checkpassed\n", + "GNS_PHASE_DELEGATE_REV-%llu: Revocation check passed\n", rh->id); /** * We are done with PKEY resolution if name is empty * else resolve again with new authority */ if (strcmp (rh->name, "") == 0) - rh->proc (rh->proc_cls, rh, 0, NULL); + rh->proc (rh->proc_cls, rh, rh->rd_count, &rh->rd); else resolve_delegation_ns (rh); + return; } +/** + * Callback when record data is put into namestore + * + * @param cls the closure + * @param success GNUNET_OK on success + * @param emsg the error message. NULL if SUCCESS==GNUNET_OK + */ +void +on_namestore_delegation_put_result(void *cls, + int32_t success, + const char *emsg) +{ + struct NamestoreBGTask *nbg = cls; + + GNUNET_CONTAINER_heap_remove_node (nbg->node); + GNUNET_free (nbg); + + if (GNUNET_NO == success) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_NS: records already in namestore\n"); + return; + } + else if (GNUNET_YES == success) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_NS: records successfully put in namestore\n"); + return; + } + + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + "GNS_NS: Error putting records into namestore: %s\n", emsg); +} + /** * Function called when we get a result from the dht * for our query. Recursively tries to resolve authorities @@ -2131,6 +2391,8 @@ process_delegation_result_dht(void* cls, name = (char*)&nrb[1]; { struct GNUNET_NAMESTORE_RecordData rd[num_records]; + struct NamestoreBGTask *ns_heap_root; + struct NamestoreBGTask *namestore_bg_task; rd_data += strlen(name) + 1 + sizeof(struct GNSNameRecordBlock); rd_size = size - strlen(name) - 1 - sizeof(struct GNSNameRecordBlock); @@ -2166,8 +2428,8 @@ process_delegation_result_dht(void* cls, rh->id, rd[i].flags); if ((rd[i].record_type == GNUNET_GNS_RECORD_VPN) || - (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_NS) || - (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_CNAME)) + (rd[i].record_type == GNUNET_GNS_RECORD_NS) || + (rd[i].record_type == GNUNET_GNS_RECORD_CNAME)) { /** * This is a VPN,NS,CNAME entry. Let namestore handle this after caching @@ -2198,6 +2460,14 @@ process_delegation_result_dht(void* cls, rh->authority_chain_tail, auth); + if (NULL != rh->rd.data) + GNUNET_free ((void*)rh->rd.data); + + memcpy (&rh->rd, &rd[i], sizeof (struct GNUNET_NAMESTORE_RecordData)); + rh->rd.data = GNUNET_malloc (rd[i].data_size); + memcpy ((void*)(rh->rd.data), rd[i].data, rd[i].data_size); + rh->rd_count = 1; + /** try to import pkey if private key available */ //if (rh->priv_key && is_canonical (rh->name)) // process_discovered_authority(name, auth->zone, @@ -2217,18 +2487,34 @@ process_delegation_result_dht(void* cls, if (0 != GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_tail->zone, &zone)) { - GNUNET_NAMESTORE_record_put (namestore_handle, + if (max_allowed_ns_tasks <= + GNUNET_CONTAINER_heap_get_size (ns_task_heap)) + { + ns_heap_root = GNUNET_CONTAINER_heap_remove_root (ns_task_heap); + GNUNET_NAMESTORE_cancel (ns_heap_root->qe); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_REC-%llu: Replacing oldest background ns task\n", + rh->id); + } + + namestore_bg_task = GNUNET_malloc (sizeof (struct NamestoreBGTask)); + + namestore_bg_task->node = GNUNET_CONTAINER_heap_insert (ns_task_heap, + namestore_bg_task, + GNUNET_TIME_absolute_get().abs_value); + namestore_bg_task->qe = GNUNET_NAMESTORE_record_put (namestore_handle, &nrb->public_key, name, exp, num_records, rd, &nrb->signature, - &on_namestore_record_put_result, //cont - NULL); //cls + &on_namestore_delegation_put_result, //cont + namestore_bg_task); //cls } } - + if (rh->answered) { rh->answered = 0; @@ -2237,13 +2523,14 @@ process_delegation_result_dht(void* cls, * FIXME in this case. should we ask namestore again? */ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_DHT-%llu: Answer from DHT for %s. Yet to resolve: %s\n", - rh->id, rh->authority_name, rh->name); + "GNS_PHASE_DELEGATE_DHT-%llu: Answer from DHT for %s. Yet to resolve: %s\n", + rh->id, rh->authority_name, rh->name); if (strcmp(rh->name, "") == 0) { /* Start shortening */ - if ((rh->priv_key != NULL) && is_canonical (rh->name)) + if ((rh->priv_key != NULL) && + (is_canonical (rh->name) == GNUNET_YES)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_DELEGATE_DHT-%llu: Trying to shorten authority chain\n", @@ -2255,33 +2542,15 @@ process_delegation_result_dht(void* cls, else rh->proc = &handle_delegation_ns; + /* Check for key revocation and delegate */ - GNUNET_NAMESTORE_lookup_record (namestore_handle, + rh->namestore_task = GNUNET_NAMESTORE_lookup_record (namestore_handle, &rh->authority, "+", GNUNET_GNS_RECORD_REV, &process_pkey_revocation_result_ns, - rh); - - /*if (strcmp(rh->name, "") == 0) - { - if ((rh->priv_key != NULL) && is_canonical (rh->name)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_DHT-%llu: Trying to shorten authority chain\n", - rh->id); - start_shorten (rh->authority_chain_tail, - rh->priv_key); - } - - rh->proc(rh->proc_cls, rh, 0, NULL); - } - else - { - rh->proc = &handle_delegation_ns; - resolve_delegation_ns (rh); - } - */ + rh); + return; } @@ -2301,7 +2570,7 @@ process_delegation_result_dht(void* cls, GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_DELEGATE_DHT-%llu: %s restored\n", rh->id, rh->name); GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_DHT-%llu: DHT authority lookup found no match!\n", + "GNS_PHASE_DELEGATE_DHT-%llu: DHT authority lookup found no match!\n", rh->id); rh->proc(rh->proc_cls, rh, 0, NULL); } @@ -2309,10 +2578,11 @@ process_delegation_result_dht(void* cls, #define MAX_SOA_LENGTH sizeof(uint32_t)+sizeof(uint32_t)+sizeof(uint32_t)+sizeof(uint32_t)\ +(MAX_DNS_NAME_LENGTH*2) #define MAX_MX_LENGTH sizeof(uint16_t)+MAX_DNS_NAME_LENGTH +#define MAX_SRV_LENGTH (sizeof(uint16_t)*3)+MAX_DNS_NAME_LENGTH static void -expand_plus(char** dest, char* src, char* repl) +expand_plus(char* dest, char* src, char* repl) { char* pos; unsigned int s_len = strlen(src)+1; @@ -2326,7 +2596,7 @@ expand_plus(char** dest, char* src, char* repl) "GNS_POSTPROCESS: %s to short\n", src); /* no postprocessing */ - memcpy(*dest, src, s_len+1); + memcpy(dest, src, s_len+1); return; } @@ -2334,17 +2604,17 @@ expand_plus(char** dest, char* src, char* repl) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GNS_POSTPROCESS: Expanding .+ in %s\n", src); - memset(*dest, 0, s_len+strlen(repl)+strlen(GNUNET_GNS_TLD)); - strcpy(*dest, src); - pos = *dest+s_len-2; + memset(dest, 0, s_len+strlen(repl)+strlen(GNUNET_GNS_TLD)); + strcpy(dest, src); + pos = dest+s_len-2; strcpy(pos, repl); pos += strlen(repl); GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_POSTPROCESS: Expanded to %s\n", *dest); + "GNS_POSTPROCESS: Expanded to %s\n", dest); } else { - memcpy(*dest, src, s_len+1); + memcpy(dest, src, s_len+1); } } @@ -2352,15 +2622,20 @@ expand_plus(char** dest, char* src, char* repl) * finish lookup */ static void -finish_lookup(struct ResolverHandle *rh, - struct RecordLookupHandle* rlh, - unsigned int rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd) +finish_lookup (struct ResolverHandle *rh, + struct RecordLookupHandle* rlh, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) { int i; char new_rr_data[MAX_DNS_NAME_LENGTH]; char new_mx_data[MAX_MX_LENGTH]; char new_soa_data[MAX_SOA_LENGTH]; + char new_srv_data[MAX_SRV_LENGTH]; + struct srv_data *old_srv; + struct srv_data *new_srv; + struct soa_data *old_soa; + struct soa_data *new_soa; struct GNUNET_NAMESTORE_RecordData p_rd[rd_count]; char* repl_string; char* pos; @@ -2372,16 +2647,20 @@ finish_lookup(struct ResolverHandle *rh, rh->timeout_task = GNUNET_SCHEDULER_NO_TASK; } + GNUNET_CONTAINER_DLL_remove (rlh_head, rlh_tail, rh); + if (rd_count > 0) memcpy(p_rd, rd, rd_count*sizeof(struct GNUNET_NAMESTORE_RecordData)); for (i = 0; i < rd_count; i++) { - if (rd[i].record_type != GNUNET_GNS_RECORD_TYPE_NS && - rd[i].record_type != GNUNET_GNS_RECORD_TYPE_CNAME && + if (rd[i].record_type != GNUNET_GNS_RECORD_NS && + rd[i].record_type != GNUNET_GNS_RECORD_PTR && + rd[i].record_type != GNUNET_GNS_RECORD_CNAME && rd[i].record_type != GNUNET_GNS_RECORD_MX && - rd[i].record_type != GNUNET_GNS_RECORD_TYPE_SOA) + rd[i].record_type != GNUNET_GNS_RECORD_SOA && + rd[i].record_type != GNUNET_GNS_RECORD_SRV) { p_rd[i].data = rd[i].data; continue; @@ -2404,34 +2683,50 @@ finish_lookup(struct ResolverHandle *rh, offset = 0; if (rd[i].record_type == GNUNET_GNS_RECORD_MX) { - memcpy(new_mx_data, (char*)rd[i].data, sizeof(uint16_t)); + memcpy (new_mx_data, (char*)rd[i].data, sizeof(uint16_t)); offset = sizeof(uint16_t); pos = new_mx_data+offset; - expand_plus(&pos, (char*)rd[i].data+sizeof(uint16_t), + expand_plus(pos, (char*)rd[i].data+sizeof(uint16_t), repl_string); offset += strlen(new_mx_data+sizeof(uint16_t))+1; p_rd[i].data = new_mx_data; p_rd[i].data_size = offset; } - else if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_SOA) + else if (rd[i].record_type == GNUNET_GNS_RECORD_SRV) + { + /* + * Prio, weight and port + */ + new_srv = (struct srv_data*)new_srv_data; + old_srv = (struct srv_data*)rd[i].data; + new_srv->prio = old_srv->prio; + new_srv->weight = old_srv->weight; + new_srv->port = old_srv->port; + expand_plus((char*)&new_srv[1], (char*)&old_srv[1], + repl_string); + p_rd[i].data = new_srv_data; + p_rd[i].data_size = sizeof (struct srv_data) + strlen ((char*)&new_srv[1]) + 1; + } + else if (rd[i].record_type == GNUNET_GNS_RECORD_SOA) { /* expand mname and rname */ - pos = new_soa_data; - expand_plus(&pos, (char*)rd[i].data, repl_string); - offset = strlen(new_soa_data)+1; - pos = new_soa_data+offset; - expand_plus(&pos, (char*)rd[i].data+offset, repl_string); - offset += strlen(new_soa_data+offset)+1; - /* cpy the 4 numbers serial refresh retry and expire */ - memcpy(new_soa_data+offset, (char*)rd[i].data+offset, sizeof(uint32_t)*5); - offset += sizeof(uint32_t)*5; - p_rd[i].data_size = offset; + old_soa = (struct soa_data*)rd[i].data; + new_soa = (struct soa_data*)new_soa_data; + memcpy (new_soa, old_soa, sizeof (struct soa_data)); + expand_plus((char*)&new_soa[1], (char*)&old_soa[1], repl_string); + offset = strlen ((char*)&new_soa[1]) + 1; + expand_plus((char*)&new_soa[1] + offset, + (char*)&old_soa[1] + strlen ((char*)&old_soa[1]) + 1, + repl_string); + p_rd[i].data_size = sizeof (struct soa_data) + + offset + + strlen ((char*)&new_soa[1] + offset); p_rd[i].data = new_soa_data; } else { pos = new_rr_data; - expand_plus(&pos, (char*)rd[i].data, repl_string); + expand_plus(pos, (char*)rd[i].data, repl_string); p_rd[i].data_size = strlen(new_rr_data)+1; p_rd[i].data = new_rr_data; } @@ -2440,7 +2735,7 @@ finish_lookup(struct ResolverHandle *rh, rlh->proc(rlh->proc_cls, rd_count, p_rd); GNUNET_free(rlh); - + free_resolver_handle (rh); } /** @@ -2462,20 +2757,18 @@ handle_record_dht(void* cls, struct ResolverHandle *rh, if (rd_count == 0) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: No records for %s found in DHT. Aborting\n", + "GNS_PHASE_REC-%llu: No records for %s found in DHT. Aborting\n", rh->id, rh->name); /* give up, cannot resolve */ finish_lookup(rh, rlh, 0, NULL); - free_resolver_handle(rh); return; } /* results found yay */ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Record resolved from DHT!", rh->id); + "GNS_PHASE_REC-%llu: Record resolved from DHT!", rh->id); finish_lookup(rh, rlh, rd_count, rd); - free_resolver_handle(rh); } @@ -2497,10 +2790,12 @@ handle_record_ns (void* cls, struct ResolverHandle *rh, { struct RecordLookupHandle* rlh; rlh = (struct RecordLookupHandle*) cls; + int check_dht = GNUNET_YES; + if (rd_count == 0) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: NS returned no records. (status: %d)!\n", + "GNS_PHASE_REC-%llu: NS returned no records. (status: %d)!\n", rh->id, rh->status); @@ -2515,11 +2810,22 @@ handle_record_ns (void* cls, struct ResolverHandle *rh, * would already have an entry in the NS for the record) * 5. We are not in cache only mode */ - if (((rh->status & RSL_RECORD_EXPIRED) || (rh->status &!RSL_RECORD_EXISTS)) - && GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone, - &rh->private_local_zone) && - (strcmp(rh->name, "+") == 0) && - (rh->only_cached == GNUNET_NO)) + if (((rh->status & RSL_RECORD_EXPIRED) != 0) && + ((rh->status & RSL_RECORD_EXISTS) == 0) ) + check_dht = GNUNET_NO; + + if (0 != GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone, + &rh->private_local_zone)) + check_dht = GNUNET_NO; + + if ((strcmp (rh->name, "+") != 0) && (is_srv (rh->name) == GNUNET_YES)) + check_dht = GNUNET_NO; + + + if (rh->only_cached == GNUNET_YES) + check_dht = GNUNET_NO; + + if (GNUNET_YES == check_dht) { rh->proc = &handle_record_dht; resolve_record_dht(rh); @@ -2527,17 +2833,15 @@ handle_record_ns (void* cls, struct ResolverHandle *rh, } /* give up, cannot resolve */ finish_lookup(rh, rlh, 0, NULL); - free_resolver_handle(rh); return; } /* results found yay */ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC-%d: Record resolved from namestore!", rh->id); + "GNS_PHASE_REC-%llu: Record resolved from namestore!\n", rh->id); finish_lookup(rh, rlh, rd_count, rd); - free_resolver_handle(rh); } @@ -2554,7 +2858,7 @@ pop_tld(char* name, char* dest) { uint32_t len; - if (is_canonical(name)) + if (is_canonical (name) == GNUNET_YES) { strcpy(dest, name); strcpy(name, ""); @@ -2628,7 +2932,6 @@ handle_delegation_dht(void* cls, struct ResolverHandle *rh, "GNS_PHASE_DELEGATE_DHT-%llu: Resolved queried PKEY via DHT.\n", rh->id); finish_lookup(rh, rlh, rd_count, rd); - free_resolver_handle(rh); return; } /* We resolved full name for delegation. resolving record */ @@ -2644,7 +2947,7 @@ handle_delegation_dht(void* cls, struct ResolverHandle *rh, /** * we still have some left **/ - if (is_canonical(rh->name)) + if (is_canonical (rh->name) == GNUNET_YES) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_DELEGATE_DHT-%llu: Resolving canonical record %s in ns\n", @@ -2659,7 +2962,6 @@ handle_delegation_dht(void* cls, struct ResolverHandle *rh, "GNS_PHASE_DELEGATE_DHT-%llu: Cannot fully resolve delegation for %s via DHT!\n", rh->id, rh->name); finish_lookup(rh, rlh, 0, NULL); - free_resolver_handle(rh); } @@ -2704,7 +3006,8 @@ resolve_delegation_dht(struct ResolverHandle *rh) { /* terminate oldest lookup */ rh_heap_root = GNUNET_CONTAINER_heap_remove_root (dht_lookup_heap); - GNUNET_DHT_get_stop(rh_heap_root->get_handle); + GNUNET_DHT_get_stop (rh_heap_root->get_handle); + rh_heap_root->get_handle = NULL; rh_heap_root->dht_heap_node = NULL; GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, @@ -2752,6 +3055,8 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh, { struct RecordLookupHandle* rlh; rlh = (struct RecordLookupHandle*) cls; + int check_dht = GNUNET_YES; + int s_len = 0; GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_DELEGATE_NS-%llu: Resolution status: %d.\n", @@ -2760,7 +3065,6 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh, if (rh->status & RSL_PKEY_REVOKED) { finish_lookup (rh, rlh, 0, NULL); - free_resolver_handle (rh); return; } @@ -2773,21 +3077,49 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh, rh->id); if (rh->status & RSL_CNAME_FOUND) { - if (rlh->record_type == GNUNET_GNS_RECORD_TYPE_CNAME) + if (rlh->record_type == GNUNET_GNS_RECORD_CNAME) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_DELEGATE_NS-%llu: Resolved queried CNAME in NS.\n", rh->id); - finish_lookup(rh, rlh, rd_count, rd); - free_resolver_handle(rh); + strcpy (rh->name, rh->authority_name); + finish_lookup (rh, rlh, rd_count, rd); return; } - /* A CNAME can only occur alone */ - GNUNET_assert (is_canonical ((char*)rd->data)); - strcpy (rh->name, rd->data); - resolve_delegation_ns (rh); - return; + /* A .+ CNAME */ + if (is_tld ((char*)rd->data, GNUNET_GNS_TLD_PLUS)) + { + s_len = strlen (rd->data) - 2; + memcpy (rh->name, rd->data, s_len); + rh->name[s_len] = '\0'; + resolve_delegation_ns (rh); + return; + } + else if (is_tld ((char*)rd->data, GNUNET_GNS_TLD_ZKEY)) + { + gns_resolver_lookup_record (rh->authority, + rh->private_local_zone, + rlh->record_type, + (char*)rd->data, + rh->priv_key, + rh->timeout, + rh->only_cached, + rlh->proc, + rlh->proc_cls); + GNUNET_free (rlh); + GNUNET_CONTAINER_DLL_remove (rlh_head, rlh_tail, rh); + free_resolver_handle (rh); + return; + } + else + { + //Try DNS resolver + strcpy (rh->dns_name, (char*)rd->data); + resolve_dns_name (rh); + return; + } + } else if (rh->status & RSL_DELEGATE_VPN) { @@ -2797,7 +3129,6 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh, "GNS_PHASE_DELEGATE_NS-%llu: Resolved queried VPNRR in NS.\n", rh->id); finish_lookup(rh, rlh, rd_count, rd); - free_resolver_handle(rh); return; } GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, @@ -2810,13 +3141,12 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh, } else if (rh->status & RSL_DELEGATE_NS) { - if (rlh->record_type == GNUNET_GNS_RECORD_TYPE_NS) + if (rlh->record_type == GNUNET_GNS_RECORD_NS) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_DELEGATE_NS-%llu: Resolved queried NSRR in NS.\n", rh->id); finish_lookup(rh, rlh, rd_count, rd); - free_resolver_handle(rh); return; } @@ -2836,17 +3166,14 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh, "GNS_PHASE_DELEGATE_NS-%llu: Resolved PKEY is revoked.\n", rh->id); finish_lookup (rh, rlh, 0, NULL); - free_resolver_handle (rh); return; } else if (rlh->record_type == GNUNET_GNS_RECORD_PKEY) { - GNUNET_assert(rd_count == 1); GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_DELEGATE_NS-%llu: Resolved queried PKEY in NS.\n", rh->id); finish_lookup(rh, rlh, rd_count, rd); - free_resolver_handle(rh); return; } } @@ -2861,13 +3188,12 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh, if (rh->status & RSL_DELEGATE_NS) { - if (rlh->record_type == GNUNET_GNS_RECORD_TYPE_NS) + if (rlh->record_type == GNUNET_GNS_RECORD_NS) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_DELEGATE_NS-%llu: Resolved queried NSRR in NS.\n", rh->id); finish_lookup(rh, rlh, rd_count, rd); - free_resolver_handle(rh); return; } @@ -2886,11 +3212,21 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh, * and exists * or we are authority **/ - if (((rh->status & RSL_RECORD_EXISTS) && (!(rh->status & RSL_RECORD_EXPIRED))) - || !GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone, - &rh->private_local_zone)) + + if ((rh->status & RSL_RECORD_EXISTS) && + !(rh->status & RSL_RECORD_EXPIRED)) + check_dht = GNUNET_NO; + + if (0 == GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone, + &rh->private_local_zone)) + check_dht = GNUNET_NO; + + if (rh->only_cached == GNUNET_YES) + check_dht = GNUNET_NO; + + if (check_dht == GNUNET_NO) { - if (is_canonical(rh->name)) + if (is_canonical (rh->name) == GNUNET_YES) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_DELEGATE_NS-%llu: Resolving canonical record %s\n", @@ -2912,15 +3248,6 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh, return; } - if (rh->only_cached == GNUNET_YES) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_NS-%llu: Only cache resolution, no result\n", - rh->id, rh->name); - finish_lookup(rh, rlh, rd_count, rd); - return; - } - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_DELEGATE_NS-%llu: Trying to resolve delegation for %s via DHT\n", rh->id, rh->name); @@ -2956,31 +3283,34 @@ process_delegation_result_ns (void* cls, struct GNUNET_TIME_Relative remaining_time; struct GNUNET_CRYPTO_ShortHashCode zone; char new_name[MAX_DNS_NAME_LENGTH]; + unsigned int i; + struct GNUNET_TIME_Absolute et; - rh = (struct ResolverHandle *)cls; - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_NS-%llu: Got %d records from authority lookup\n", - rh->id, rd_count); + rh = (struct ResolverHandle *)cls; + rh->namestore_task = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Got %d records from authority lookup\n", + rh->id, rd_count); - GNUNET_CRYPTO_short_hash(key, - sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), - &zone); + GNUNET_CRYPTO_short_hash (key, + sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &zone); remaining_time = GNUNET_TIME_absolute_get_remaining (expiration); rh->status = 0; if (name != NULL) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_NS-%llu: Records with name %s exist.\n", - rh->id, name); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Records with name %s exist.\n", + rh->id, name); rh->status |= RSL_RECORD_EXISTS; if (remaining_time.rel_value == 0) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_NS-%llu: Record set %s expired.\n", - rh->id, name); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Record set %s expired.\n", + rh->id, name); rh->status |= RSL_RECORD_EXPIRED; } } @@ -2999,31 +3329,29 @@ process_delegation_result_ns (void* cls, * Promote this authority back to a name maybe it is * our record. */ - if (strcmp(rh->name, "") == 0) + if (strcmp (rh->name, "") == 0) { /* simply promote back */ - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_NS-%llu: Promoting %s back to name\n", - rh->id, rh->authority_name); - strcpy(rh->name, rh->authority_name); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Promoting %s back to name\n", + rh->id, rh->authority_name); + strcpy (rh->name, rh->authority_name); } else { /* add back to existing name */ - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_NS-%llu: Adding %s back to %s\n", - rh->id, rh->authority_name, rh->name); - //memset(new_name, 0, strlen(rh->name) + strlen(rh->authority_name) + 2); - GNUNET_snprintf(new_name, MAX_DNS_NAME_LENGTH, "%s.%s", - rh->name, rh->authority_name); - //strcpy(new_name, rh->name); - //strcpy(new_name+strlen(new_name), "."); - //strcpy(new_name+strlen(new_name), rh->authority_name); - strcpy(rh->name, new_name); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_NS-%llu: %s restored\n", rh->id, rh->name); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Adding %s back to %s\n", + rh->id, rh->authority_name, rh->name); + GNUNET_snprintf (new_name, MAX_DNS_NAME_LENGTH, "%s.%s", + rh->name, rh->authority_name); + strcpy (rh->name, new_name); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: %s restored\n", + rh->id, rh->name); } - rh->proc(rh->proc_cls, rh, 0, NULL); + + rh->proc (rh->proc_cls, rh, 0, NULL); return; } @@ -3032,22 +3360,18 @@ process_delegation_result_ns (void* cls, * move on with query * Note only 1 pkey should have been returned.. anything else would be strange */ - int i; - for (i=0; iid); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_NS-%llu: new name to resolve: %s.\n", - rh->id, rh->name); rh->status |= RSL_CNAME_FOUND; rh->proc (rh->proc_cls, rh, rd_count, rd); @@ -3071,7 +3395,7 @@ process_delegation_result_ns (void* cls, * Redirect via NS * FIXME make optional */ - if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_NS) + if (rd[i].record_type == GNUNET_GNS_RECORD_NS) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_DELEGATE_NS-%llu: NS found.\n", @@ -3086,29 +3410,31 @@ process_delegation_result_ns (void* cls, rh->status |= RSL_DELEGATE_PKEY; - if (ignore_pending_records && + if ((ignore_pending_records != 0) && (rd[i].flags & GNUNET_NAMESTORE_RF_PENDING)) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_NS-%llu: PKEY for %s is pending user confirmation.\n", + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: PKEY for %s is pending user confirmation.\n", rh->id, name); continue; } - if ((GNUNET_TIME_absolute_get_remaining (rd[i].expiration)).rel_value + GNUNET_break (0 == (rd[i].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION)); + et.abs_value = rd[i].expiration_time; + if ((GNUNET_TIME_absolute_get_remaining (et)).rel_value == 0) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_NS-%llu: This pkey is expired.\n", - rh->id); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: This pkey is expired.\n", + rh->id); if (remaining_time.rel_value == 0) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_NS-%llu: This dht entry is expired.\n", - rh->id); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: This dht entry is expired.\n", + rh->id); rh->authority_chain_head->fresh = 0; - rh->proc(rh->proc_cls, rh, 0, NULL); + rh->proc (rh->proc_cls, rh, 0, NULL); return; } @@ -3118,28 +3444,34 @@ process_delegation_result_ns (void* cls, /** * Resolve rest of query with new authority */ - GNUNET_assert(rd[i].record_type == GNUNET_GNS_RECORD_PKEY); - memcpy(&rh->authority, rd[i].data, - sizeof(struct GNUNET_CRYPTO_ShortHashCode)); - struct AuthorityChain *auth = GNUNET_malloc(sizeof(struct AuthorityChain)); + GNUNET_assert (rd[i].record_type == GNUNET_GNS_RECORD_PKEY); + memcpy (&rh->authority, rd[i].data, + sizeof (struct GNUNET_CRYPTO_ShortHashCode)); + struct AuthorityChain *auth = GNUNET_malloc(sizeof (struct AuthorityChain)); auth->zone = rh->authority; - memset(auth->name, 0, strlen(rh->authority_name)+1); - strcpy(auth->name, rh->authority_name); + memset (auth->name, 0, strlen (rh->authority_name)+1); + strcpy (auth->name, rh->authority_name); GNUNET_CONTAINER_DLL_insert (rh->authority_chain_head, rh->authority_chain_tail, auth); + if (NULL != rh->rd.data) + GNUNET_free ((void*)(rh->rd.data)); + memcpy (&rh->rd, &rd[i], sizeof (struct GNUNET_NAMESTORE_RecordData)); + rh->rd.data = GNUNET_malloc (rd[i].data_size); + memcpy ((void*)rh->rd.data, rd[i].data, rd[i].data_size); + rh->rd_count = 1; /* Check for key revocation and delegate */ - GNUNET_NAMESTORE_lookup_record (namestore_handle, + rh->namestore_task = GNUNET_NAMESTORE_lookup_record (namestore_handle, &rh->authority, "+", GNUNET_GNS_RECORD_REV, &process_pkey_revocation_result_ns, rh); return; - + } - + /** * no answers found */ @@ -3149,10 +3481,11 @@ process_delegation_result_ns (void* cls, * If we have found some records for the LAST label * we return the results. Else null. */ - if (strcmp(rh->name, "") == 0) + if (strcmp (rh->name, "") == 0) { /* Start shortening */ - if ((rh->priv_key != NULL) && is_canonical (rh->name)) + if ((rh->priv_key != NULL) && + (is_canonical (rh->name) == GNUNET_YES)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_DELEGATE_NS-%llu: Trying to shorten authority chain\n", @@ -3161,15 +3494,18 @@ process_delegation_result_ns (void* cls, rh->priv_key); } /* simply promote back */ - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_DELEGATE_NS-%llu: Promoting %s back to name\n", - rh->id, rh->authority_name); - strcpy(rh->name, rh->authority_name); - rh->proc(rh->proc_cls, rh, rd_count, rd); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Promoting %s back to name\n", + rh->id, rh->authority_name); + strcpy (rh->name, rh->authority_name); + rh->proc (rh->proc_cls, rh, rd_count, rd); } else { - rh->proc(rh->proc_cls, rh, 0, NULL); + GNUNET_snprintf (new_name, MAX_DNS_NAME_LENGTH, + "%s.%s", rh->name, rh->authority_name); + strcpy (rh->name, new_name); + rh->proc (rh->proc_cls, rh, 0, NULL); } } @@ -3186,7 +3522,7 @@ resolve_delegation_ns (struct ResolverHandle *rh) "GNS_PHASE_DELEGATE_NS-%llu: Resolving delegation for %s\n", rh->id, rh->name); pop_tld(rh->name, rh->authority_name); - GNUNET_NAMESTORE_lookup_record(namestore_handle, + rh->namestore_task = GNUNET_NAMESTORE_lookup_record(namestore_handle, &rh->authority, rh->authority_name, GNUNET_GNS_RECORD_ANY, @@ -3211,15 +3547,15 @@ resolve_delegation_ns (struct ResolverHandle *rh) * @param cls the closure to pass to proc */ void -gns_resolver_lookup_record(struct GNUNET_CRYPTO_ShortHashCode zone, - struct GNUNET_CRYPTO_ShortHashCode pzone, - uint32_t record_type, - const char* name, - struct GNUNET_CRYPTO_RsaPrivateKey *key, - struct GNUNET_TIME_Relative timeout, - int only_cached, - RecordLookupProcessor proc, - void* cls) +gns_resolver_lookup_record (struct GNUNET_CRYPTO_ShortHashCode zone, + struct GNUNET_CRYPTO_ShortHashCode pzone, + uint32_t record_type, + const char* name, + struct GNUNET_CRYPTO_RsaPrivateKey *key, + struct GNUNET_TIME_Relative timeout, + int only_cached, + RecordLookupProcessor proc, + void* cls) { struct ResolverHandle *rh; struct RecordLookupHandle* rlh; @@ -3232,7 +3568,8 @@ gns_resolver_lookup_record(struct GNUNET_CRYPTO_ShortHashCode zone, name, record_type); - if (is_canonical((char*)name) && (strcmp(GNUNET_GNS_TLD, name) != 0)) + if ((is_canonical ((char*)name) == GNUNET_YES) && + (strcmp(GNUNET_GNS_TLD, name) != 0)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s is canonical and not gnunet -> cannot resolve!\n", name); @@ -3240,9 +3577,10 @@ gns_resolver_lookup_record(struct GNUNET_CRYPTO_ShortHashCode zone, return; } - rlh = GNUNET_malloc(sizeof(struct RecordLookupHandle)); - rh = GNUNET_malloc(sizeof (struct ResolverHandle)); - + rlh = GNUNET_malloc (sizeof(struct RecordLookupHandle)); + rh = GNUNET_malloc (sizeof (struct ResolverHandle)); + + memset (rh, 0, sizeof (struct ResolverHandle)); rh->authority = zone; rh->id = rid++; rh->proc_cls = rlh; @@ -3251,6 +3589,10 @@ gns_resolver_lookup_record(struct GNUNET_CRYPTO_ShortHashCode zone, rh->get_handle = NULL; rh->private_local_zone = pzone; rh->only_cached = only_cached; + rh->namestore_task = NULL; + rh->rd.data = NULL; + + GNUNET_CONTAINER_DLL_insert (rlh_head, rlh_tail, rh); if (NULL == key) { @@ -3313,24 +3655,39 @@ gns_resolver_lookup_record(struct GNUNET_CRYPTO_ShortHashCode zone, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot convert ZKEY %s to hash!\n", string_hash); - GNUNET_free(rh); - GNUNET_free(rlh); - proc(cls, 0, NULL); + + GNUNET_CONTAINER_DLL_remove (rlh_head, rlh_tail, rh); + GNUNET_free (rh); + GNUNET_free (rlh); + proc (cls, 0, NULL); return; } } - else + else if (is_gnunet_tld (name) == GNUNET_YES) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TLD is gnunet\n"); /** * Presumably GNUNET tld */ - memset(rh->name, 0, - strlen(name)-strlen(GNUNET_GNS_TLD)); - memcpy(rh->name, name, - strlen(name)-strlen(GNUNET_GNS_TLD) - 1); + memset (rh->name, 0, + strlen(name)-strlen(GNUNET_GNS_TLD)); + memcpy (rh->name, name, + strlen(name)-strlen(GNUNET_GNS_TLD) - 1); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Cannot handle this TLD %s\n", string_hash); + + if (GNUNET_SCHEDULER_NO_TASK != rh->timeout_task) + GNUNET_SCHEDULER_cancel (rh->timeout_task); + GNUNET_CONTAINER_DLL_remove (rlh_head, rlh_tail, rh); + GNUNET_free (rh); + GNUNET_free (rlh); + proc (cls, 0, NULL); + return; } } @@ -3342,6 +3699,7 @@ gns_resolver_lookup_record(struct GNUNET_CRYPTO_ShortHashCode zone, rh->authority_chain_head->next = NULL; rh->authority_chain_tail = rh->authority_chain_head; rh->authority_chain_head->zone = rh->authority; + strcpy (rh->authority_chain_head->name, ""); /** * Copy original query into lookup handle @@ -3358,6 +3716,19 @@ gns_resolver_lookup_record(struct GNUNET_CRYPTO_ShortHashCode zone, /******** END Record Resolver ***********/ +static void +finish_shorten (struct ResolverHandle *rh, + struct NameShortenHandle *nsh) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending %s as shorten result\n", nsh->result); + nsh->proc (nsh->proc_cls, nsh->result); + GNUNET_CONTAINER_DLL_remove (nsh_head, nsh_tail, rh); + GNUNET_free (nsh); + free_resolver_handle (rh); +} + + /** * Callback calles by namestore for a zone to name * result @@ -3409,25 +3780,24 @@ process_zone_to_name_shorten_shorten (void *cls, char tmp_name[MAX_DNS_NAME_LENGTH]; size_t answer_len; + rh->namestore_task = NULL; /* we found a match in our own root zone */ if (rd_len != 0) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "result strlen %d\n", strlen(name)); answer_len = strlen(rh->name) + strlen(name) + strlen(GNUNET_GNS_TLD) + 3; memset(result, 0, answer_len); if (strlen(rh->name) > 0) { - sprintf (result, "%s.%s.%s.%s.%s", + sprintf (result, "%s.%s.%s.%s", rh->name, name, - nsh->shorten_zone_name, nsh->private_zone_name, + nsh->shorten_zone_name, GNUNET_GNS_TLD); } else { - sprintf (result, "%s.%s.%s.%s", name, - nsh->shorten_zone_name, nsh->private_zone_name, + sprintf (result, "%s.%s.%s", name, + nsh->shorten_zone_name, GNUNET_GNS_TLD); } @@ -3445,9 +3815,9 @@ process_zone_to_name_shorten_shorten (void *cls, * shorten to our zone to a "" record??) */ - sprintf (result, "%s.%s.%s.%s", + sprintf (result, "%s.%s.%s", rh->name, - nsh->shorten_zone_name, nsh->private_zone_name, + nsh->shorten_zone_name, GNUNET_GNS_TLD); GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Our zone: Found %s as shorten result\n", result); @@ -3467,11 +3837,7 @@ process_zone_to_name_shorten_shorten (void *cls, */ if ((rh->authority_chain_head->next == NULL)) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending %s as shorten result\n", nsh->result); - nsh->proc(nsh->proc_cls, nsh->result); - GNUNET_free (nsh); - free_resolver_handle (rh); + finish_shorten (rh, nsh); return; } next_authority = rh->authority_chain_head; @@ -3488,7 +3854,9 @@ process_zone_to_name_shorten_shorten (void *cls, rh->authority_chain_tail, next_authority); - GNUNET_NAMESTORE_zone_to_name (namestore_handle, + GNUNET_free (next_authority); + + rh->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle, &rh->authority_chain_tail->zone, &rh->authority_chain_head->zone, &process_zone_to_name_shorten_root, @@ -3524,11 +3892,10 @@ process_zone_to_name_shorten_private (void *cls, char tmp_name[MAX_DNS_NAME_LENGTH]; size_t answer_len; + rh->namestore_task = NULL; /* we found a match in our own root zone */ if (rd_len != 0) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "result strlen %d\n", strlen(name)); answer_len = strlen(rh->name) + strlen(name) + strlen(GNUNET_GNS_TLD) + 3; memset(result, 0, answer_len); @@ -3563,10 +3930,10 @@ process_zone_to_name_shorten_private (void *cls, strcpy (nsh->result, result); } - if (nsh->shorten_zone != NULL) + if (0 != strcmp (nsh->shorten_zone_name, "")) { /* backtrack authorities for names in priv zone */ - GNUNET_NAMESTORE_zone_to_name (namestore_handle, + rh->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle, nsh->shorten_zone, &rh->authority_chain_head->zone, &process_zone_to_name_shorten_shorten, @@ -3580,11 +3947,7 @@ process_zone_to_name_shorten_private (void *cls, */ if ((rh->authority_chain_head->next == NULL)) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Sending %s as shorten result\n", nsh->result); - nsh->proc(nsh->proc_cls, nsh->result); - GNUNET_free(nsh); - free_resolver_handle(rh); + finish_shorten (rh, nsh); return; } next_authority = rh->authority_chain_head; @@ -3601,7 +3964,9 @@ process_zone_to_name_shorten_private (void *cls, rh->authority_chain_tail, next_authority); - GNUNET_NAMESTORE_zone_to_name (namestore_handle, + GNUNET_free (next_authority); + + rh->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle, &rh->authority_chain_tail->zone, &rh->authority_chain_head->zone, &process_zone_to_name_shorten_root, @@ -3638,11 +4003,10 @@ process_zone_to_name_shorten_root (void *cls, char tmp_name[MAX_DNS_NAME_LENGTH]; size_t answer_len; + rh->namestore_task = NULL; /* we found a match in our own root zone */ if (rd_len != 0) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "result strlen %d\n", strlen(name)); answer_len = strlen(rh->name) + strlen(name) + strlen(GNUNET_GNS_TLD) + 3; memset(result, 0, answer_len); @@ -3676,15 +4040,24 @@ process_zone_to_name_shorten_root (void *cls, strcpy (nsh->result, result); } - if (nsh->private_zone != NULL) + if (NULL != nsh->private_zone) { /* backtrack authorities for names in priv zone */ - GNUNET_NAMESTORE_zone_to_name (namestore_handle, + rh->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle, nsh->private_zone, &rh->authority_chain_head->zone, &process_zone_to_name_shorten_private, rh); } + else if (NULL != nsh->shorten_zone) + { + /* backtrack authorities for names in shorten zone */ + rh->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle, + nsh->shorten_zone, + &rh->authority_chain_head->zone, + &process_zone_to_name_shorten_shorten, + rh); + } else { /** @@ -3693,11 +4066,7 @@ process_zone_to_name_shorten_root (void *cls, */ if ((rh->authority_chain_head->next == NULL)) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Sending %s as shorten result\n", nsh->result); - nsh->proc(nsh->proc_cls, nsh->result); - GNUNET_free(nsh); - free_resolver_handle(rh); + finish_shorten (rh, nsh); return; } next_authority = rh->authority_chain_head; @@ -3714,7 +4083,9 @@ process_zone_to_name_shorten_root (void *cls, rh->authority_chain_tail, next_authority); - GNUNET_NAMESTORE_zone_to_name (namestore_handle, + GNUNET_free (next_authority); + + rh->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle, &rh->authority_chain_tail->zone, &rh->authority_chain_head->zone, &process_zone_to_name_shorten_root, @@ -3771,44 +4142,51 @@ handle_delegation_ns_shorten (void* cls, strcpy (nsh->result, result); } - else if (GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone, - nsh->private_zone) == 0) + else if (NULL != nsh->private_zone) { /** * This is our zone append .gnunet unless name is empty * (it shouldn't be, usually FIXME what happens if we * shorten to our zone to a "" record??) */ + if (GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone, + nsh->private_zone) == 0) + { - sprintf (result, "%s.%s.%s", - rh->name, nsh->private_zone_name, GNUNET_GNS_TLD); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Our zone: Found %s as shorten result %s\n", result); + sprintf (result, "%s.%s.%s", + rh->name, nsh->private_zone_name, GNUNET_GNS_TLD); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Our zone: Found %s as shorten result in private zone %s\n", + result); - if (strlen (nsh->result) > strlen (result)) - strcpy (nsh->result, result); + if (strlen (nsh->result) > strlen (result)) + strcpy (nsh->result, result); + } } - else if (GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone, - nsh->shorten_zone) == 0) + else if (NULL != nsh->shorten_zone) { /** * This is our zone append .gnunet unless name is empty * (it shouldn't be, usually FIXME what happens if we * shorten to our zone to a "" record??) */ + if (GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone, + nsh->shorten_zone) == 0) + { + sprintf (result, "%s.%s.%s", + rh->name, nsh->private_zone_name, GNUNET_GNS_TLD); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Our zone: Found %s as shorten result in shorten zone\n", + result); - sprintf (result, "%s.%s.%s", - rh->name, nsh->private_zone_name, GNUNET_GNS_TLD); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Our zone: Found %s as shorten result\n", result); - - if (strlen (nsh->result) > strlen (result)) - strcpy (nsh->result, result); + if (strlen (nsh->result) > strlen (result)) + strcpy (nsh->result, result); + } } /* backtrack authorities for names */ - GNUNET_NAMESTORE_zone_to_name (namestore_handle, + rh->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle, nsh->root_zone, &rh->authority_chain_head->zone, &process_zone_to_name_shorten_root, @@ -3866,9 +4244,7 @@ process_zone_to_name_zkey(void *cls, strcpy (nsh->result, new_name); - nsh->proc(nsh->proc_cls, new_name); - GNUNET_free(nsh); - free_resolver_handle(rh); + finish_shorten (rh, nsh); return; } @@ -3889,7 +4265,7 @@ process_zone_to_name_zkey(void *cls, /* Start delegation resolution in our namestore */ - resolve_delegation_ns(rh); + resolve_delegation_ns (rh); } @@ -3926,7 +4302,7 @@ gns_resolver_shorten_name (struct GNUNET_CRYPTO_ShortHashCode *zone, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting shorten for %s!\n", name); - if (is_canonical ((char*)name)) + if (is_canonical ((char*)name) == GNUNET_YES) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s is canonical. Returning verbatim\n", name); @@ -3945,14 +4321,18 @@ gns_resolver_shorten_name (struct GNUNET_CRYPTO_ShortHashCode *zone, strcpy (nsh->shorten_zone_name, shorten_zone_name); strcpy (nsh->result, name); + rh = GNUNET_malloc (sizeof (struct ResolverHandle)); rh->authority = *zone; rh->id = rid++; rh->priv_key = NULL; + rh->namestore_task = NULL; rh->proc = &handle_delegation_ns_shorten; rh->proc_cls = nsh; rh->id = rid++; rh->private_local_zone = *zone; + + GNUNET_CONTAINER_DLL_insert (nsh_head, nsh_tail, rh); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking for TLD...\n"); @@ -3983,11 +4363,12 @@ gns_resolver_shorten_name (struct GNUNET_CRYPTO_ShortHashCode *zone, "Cannot convert ZKEY %s to hash!\n", nzkey); GNUNET_free (rh); GNUNET_free (nsh); + GNUNET_CONTAINER_DLL_remove (nsh_head, nsh_tail, rh); proc (proc_cls, name); return; } - GNUNET_NAMESTORE_zone_to_name (namestore_handle, + rh->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle, zone, //ours &zkey, &process_zone_to_name_zkey, @@ -3995,7 +4376,7 @@ gns_resolver_shorten_name (struct GNUNET_CRYPTO_ShortHashCode *zone, return; } - else + else if (is_gnunet_tld (name) == GNUNET_YES) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TLD is gnunet\n"); @@ -4007,6 +4388,15 @@ gns_resolver_shorten_name (struct GNUNET_CRYPTO_ShortHashCode *zone, memcpy (rh->name, name, strlen (name)-strlen (GNUNET_GNS_TLD) - 1); } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unknown TLD in %s\n", name); + GNUNET_free (rh); + GNUNET_free (nsh); + GNUNET_CONTAINER_DLL_remove (nsh_head, nsh_tail, rh); + proc (proc_cls, name); + return; + } rh->authority_chain_head = GNUNET_malloc (sizeof (struct AuthorityChain)); rh->authority_chain_tail = rh->authority_chain_head; @@ -4019,6 +4409,24 @@ gns_resolver_shorten_name (struct GNUNET_CRYPTO_ShortHashCode *zone, /*********** END NAME SHORTEN ********************/ +/** + * Conclude get authority lookup + * + * @param rh resolver handle + * @param nah get authority lookup handle + */ +static void +finish_get_auth (struct ResolverHandle *rh, + struct GetNameAuthorityHandle *nah) +{ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Got authority result %s\n", nah->result); + + nah->proc(nah->proc_cls, nah->result); + GNUNET_CONTAINER_DLL_remove (nah_head, nah_tail, rh); + GNUNET_free(nah); + free_resolver_handle(rh); +} /** * Process result from namestore delegation lookup @@ -4036,7 +4444,6 @@ handle_delegation_result_ns_get_auth(void* cls, const struct GNUNET_NAMESTORE_RecordData *rd) { struct GetNameAuthorityHandle* nah; - char result[MAX_DNS_NAME_LENGTH]; size_t answer_len; nah = (struct GetNameAuthorityHandle*) rh->proc_cls; @@ -4053,7 +4460,7 @@ handle_delegation_result_ns_get_auth(void* cls, GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Building response!\n"); - if (is_canonical(rh->name)) + if (is_canonical (rh->name) == GNUNET_YES) { /** * We successfully resolved the authority in the ns @@ -4070,23 +4477,17 @@ handle_delegation_result_ns_get_auth(void* cls, answer_len = strlen(nah->name) - strlen(rh->name) + strlen(GNUNET_GNS_TLD) + 1; - memset(result, 0, answer_len); - strcpy(result, nah->name + strlen(rh->name) + 1); + memset(nah->result, 0, answer_len); + strcpy(nah->result, nah->name + strlen(rh->name) + 1); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Got authority result %s\n", result); - - nah->proc(nah->proc_cls, result); - GNUNET_free(nah); - free_resolver_handle(rh); + finish_get_auth (rh, nah); } else { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Unable to resolve authority for remaining %s!\n", rh->name); - nah->proc(nah->proc_cls, ""); - GNUNET_free(nah); - free_resolver_handle(rh); + strcpy(nah->result, ""); + finish_get_auth (rh, nah); } @@ -4121,6 +4522,9 @@ gns_resolver_get_authority(struct GNUNET_CRYPTO_ShortHashCode zone, rh->authority = zone; rh->id = rid++; rh->private_local_zone = pzone; + rh->namestore_task = NULL; + + GNUNET_CONTAINER_DLL_insert (nah_head, nah_tail, rh); if (strcmp(GNUNET_GNS_TLD, name) == 0) { @@ -4146,6 +4550,7 @@ gns_resolver_get_authority(struct GNUNET_CRYPTO_ShortHashCode zone, nah->proc = proc; nah->proc_cls = proc_cls; + strcpy (nah->result, ""); /* Start delegation resolution in our namestore */ resolve_delegation_ns(rh);