X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fgns%2Fgnunet-service-gns_resolver.c;h=7258f97a145db1d532cbae4ff7b4955ebdffe7c2;hb=9062e2e68f6675e65d45a1cc0d4cf7beac1ab007;hp=bbeea86f40bf2f44153c142bf8796a69305ea401;hpb=eec111fe95456619682d12859685d326ca161e46;p=oweals%2Fgnunet.git diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c index bbeea86f4..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,28 +141,36 @@ 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 = 1; + int ret = GNUNET_YES; if (*name != '_') - return 0; + return GNUNET_NO; if (NULL == strstr (name, "._")) - return 0; + return GNUNET_NO; ndup = GNUNET_strdup (name); strtok (ndup, "."); if (NULL == strtok (NULL, ".")) - ret = 0; + ret = GNUNET_NO; if (NULL == strtok (NULL, ".")) - ret = 0; + ret = GNUNET_NO; if (NULL != strtok (NULL, ".")) - ret = 0; + ret = GNUNET_NO; + + GNUNET_free (ndup); return ret; } @@ -130,16 +182,16 @@ is_srv (char* name) * 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) { char* ndup; char* tok; ndup = GNUNET_strdup (name); - tok = strtok (ndup, "."); + strtok (ndup, "."); for (tok = strtok (NULL, "."); tok != NULL; tok = strtok (NULL, ".")) { @@ -149,10 +201,10 @@ is_canonical(char* name) if (*tok == '_') continue; GNUNET_free (ndup); - return 0; + return GNUNET_NO; } GNUNET_free (ndup); - return 1; + return GNUNET_YES; } @@ -165,6 +217,26 @@ static void shorten_authority_chain (struct GetPseuAuthorityHandle *gph); +static void +create_pseu_cont (void* cls, int32_t success, const char* emsg) +{ + //FIXME do sth with error + struct GetPseuAuthorityHandle* gph = (struct GetPseuAuthorityHandle*)cls; + struct AuthorityChain *iter; + + gph->namestore_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) @@ -189,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, @@ -225,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, @@ -245,22 +318,12 @@ process_pseu_lookup_ns (void* cls, 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 } /** @@ -288,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, @@ -478,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) { @@ -566,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) { @@ -587,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, @@ -611,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, @@ -665,44 +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 cfg configuration handle + * @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)) { @@ -712,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 @@ -722,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; @@ -733,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) @@ -769,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 @@ -782,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); -} /** @@ -835,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, @@ -893,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 @@ -904,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, @@ -961,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 @@ -990,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); @@ -1000,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) && @@ -1031,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, @@ -1041,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); } } @@ -1078,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; @@ -1093,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 */ @@ -1119,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, @@ -1176,6 +1385,8 @@ process_record_result_ns (void* cls, 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); @@ -1201,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 @@ -1217,7 +1428,7 @@ 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); for (i=0; iid, name); continue; } @@ -1239,7 +1450,7 @@ process_record_result_ns (void* cls, == 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; } @@ -1252,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); @@ -1283,22 +1494,22 @@ 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.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); @@ -1309,12 +1520,12 @@ 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; @@ -1329,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 @@ -1367,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); } @@ -1411,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; } @@ -1434,8 +1629,7 @@ handle_dns_resolver (void *cls, rd.flags = 0; finish_lookup (rh, rlh, 1, &rd); - GNUNET_RESOLVER_request_cancel (rh->dns_resolver_handle); - free_resolver_handle (rh); + } /** @@ -1449,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; @@ -1503,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; } @@ -1520,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; } @@ -1532,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; } @@ -1544,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", @@ -1568,9 +1755,7 @@ read_dns_response (void *cls, rd.flags = 0; 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; } } @@ -1603,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"); @@ -1618,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) == @@ -1635,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; } @@ -1651,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, @@ -1700,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", @@ -1712,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, "")) @@ -1721,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); } @@ -1737,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; } @@ -1751,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; } @@ -1783,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; } @@ -1811,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) @@ -1827,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", @@ -1836,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; - } + vpn = (struct vpn_data*)rd->data; - 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)); + 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)); - 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_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) @@ -1876,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); } @@ -1911,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", @@ -1926,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, @@ -1951,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) @@ -1999,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, @@ -2053,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++) @@ -2078,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, @@ -2093,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 @@ -2169,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); @@ -2204,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 @@ -2236,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, @@ -2255,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; @@ -2275,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", @@ -2293,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; } @@ -2339,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); } @@ -2351,7 +2582,7 @@ process_delegation_result_dht(void* cls, 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; @@ -2365,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; } @@ -2373,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); } } @@ -2391,16 +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; @@ -2412,17 +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_TYPE_SRV) + rd[i].record_type != GNUNET_GNS_RECORD_SOA && + rd[i].record_type != GNUNET_GNS_RECORD_SRV) { p_rd[i].data = rd[i].data; continue; @@ -2448,45 +2686,47 @@ finish_lookup(struct ResolverHandle *rh, 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_SRV) + else if (rd[i].record_type == GNUNET_GNS_RECORD_SRV) { /* * Prio, weight and port */ - memcpy (new_srv_data, (char*)rd[i].data, sizeof (uint16_t) * 3); - offset = sizeof (uint16_t) * 3; - pos = new_srv_data+offset; - expand_plus(&pos, (char*)rd[i].data+(sizeof(uint16_t)*3), + 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); - offset += strlen(new_srv_data+(sizeof(uint16_t)*3))+1; p_rd[i].data = new_srv_data; - p_rd[i].data_size = offset; + p_rd[i].data_size = sizeof (struct srv_data) + strlen ((char*)&new_srv[1]) + 1; } - else if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_SOA) + 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; } @@ -2495,7 +2735,7 @@ finish_lookup(struct ResolverHandle *rh, rlh->proc(rlh->proc_cls, rd_count, p_rd); GNUNET_free(rlh); - + free_resolver_handle (rh); } /** @@ -2517,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); } @@ -2557,7 +2795,7 @@ handle_record_ns (void* cls, struct ResolverHandle *rh, 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); @@ -2580,7 +2818,7 @@ handle_record_ns (void* cls, struct ResolverHandle *rh, &rh->private_local_zone)) check_dht = GNUNET_NO; - if ((strcmp (rh->name, "+") != 0) && (is_srv (rh->name) != 0)) + if ((strcmp (rh->name, "+") != 0) && (is_srv (rh->name) == GNUNET_YES)) check_dht = GNUNET_NO; @@ -2595,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); } @@ -2622,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, ""); @@ -2696,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 */ @@ -2712,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", @@ -2727,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); } @@ -2772,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, @@ -2830,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; } @@ -2843,14 +3077,13 @@ 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); strcpy (rh->name, rh->authority_name); finish_lookup (rh, rlh, rd_count, rd); - free_resolver_handle (rh); return; } @@ -2875,6 +3108,7 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh, rlh->proc, rlh->proc_cls); GNUNET_free (rlh); + GNUNET_CONTAINER_DLL_remove (rlh_head, rlh_tail, rh); free_resolver_handle (rh); return; } @@ -2895,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, @@ -2908,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; } @@ -2934,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; } } @@ -2959,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; } @@ -2998,7 +3226,7 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh, 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", @@ -3058,7 +3286,8 @@ process_delegation_result_ns (void* cls, unsigned int i; struct GNUNET_TIME_Absolute et; - rh = (struct ResolverHandle *)cls; + 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); @@ -3138,7 +3367,7 @@ process_delegation_result_ns (void* cls, * A CNAME. Like regular DNS this means the is no other record for this * name. */ - if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_CNAME) + if (rd[i].record_type == GNUNET_GNS_RECORD_CNAME) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_DELEGATE_NS-%llu: CNAME found.\n", @@ -3166,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", @@ -3225,9 +3454,15 @@ process_delegation_result_ns (void* cls, 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, @@ -3246,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", @@ -3258,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); } } @@ -3283,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, @@ -3329,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); @@ -3337,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; @@ -3348,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) { @@ -3410,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; } } @@ -3439,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 @@ -3455,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 @@ -3506,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); } @@ -3542,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); @@ -3564,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; @@ -3585,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, @@ -3621,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); @@ -3660,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, @@ -3677,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; @@ -3698,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, @@ -3735,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); @@ -3773,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 { /** @@ -3790,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; @@ -3811,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, @@ -3868,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, @@ -3963,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; } @@ -3986,7 +4265,7 @@ process_zone_to_name_zkey(void *cls, /* Start delegation resolution in our namestore */ - resolve_delegation_ns(rh); + resolve_delegation_ns (rh); } @@ -4023,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); @@ -4042,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"); @@ -4080,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, @@ -4092,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"); @@ -4104,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; @@ -4116,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 @@ -4133,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; @@ -4150,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 @@ -4167,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); } @@ -4218,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) { @@ -4243,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);