X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fgns%2Fgnunet-service-gns_resolver.c;h=f180f6282bddf83a00fe80d3d34d008c3ec397b9;hb=009f7e51493126c71b5d84a5189f342d00c07c56;hp=e14497056d969a7ebaa5e4c4974b3b01cce973c1;hpb=98ad58b921d43d6385ca7e3089a6fee4688175cf;p=oweals%2Fgnunet.git diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c index e14497056..f180f6282 100644 --- a/src/gns/gnunet-service-gns_resolver.c +++ b/src/gns/gnunet-service-gns_resolver.c @@ -35,6 +35,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 +66,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 +101,36 @@ 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; + /** * a resolution identifier pool variable * FIXME overflow? @@ -97,6 +138,31 @@ static struct GetPseuAuthorityHandle *gph_tail; */ static unsigned long long rid = 0; +static int +is_srv (char* name) +{ + char* ndup; + int ret = 1; + + if (*name != '_') + return 0; + if (NULL == strstr (name, "._")) + return 0; + + ndup = GNUNET_strdup (name); + strtok (ndup, "."); + + if (NULL == strtok (NULL, ".")) + ret = 0; + + if (NULL == strtok (NULL, ".")) + ret = 0; + + if (NULL != strtok (NULL, ".")) + ret = 0; + + return ret; +} /** * Determine if this name is canonical. @@ -110,14 +176,23 @@ static unsigned long long rid = 0; static int is_canonical(char* name) { - uint32_t len = strlen(name); - int i; + char* ndup; + char* tok; + + ndup = GNUNET_strdup (name); + strtok (ndup, "."); - 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 +250,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 +287,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, @@ -211,22 +307,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 } /** @@ -254,7 +340,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 +530,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 +619,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 +641,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 +665,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,6 +719,7 @@ 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 max_bg_queries maximum number of parallel background queries in dht * @param ignore_pending ignore records that still require user confirmation * on lookup @@ -649,12 +738,22 @@ gns_resolver_init(struct GNUNET_NAMESTORE_Handle *nh, 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) @@ -677,8 +776,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 +833,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 +844,105 @@ 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); + 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 +953,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 +970,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 +1018,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 +1081,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 (%ds)timed out.\n", rh->id, rh->name, rh->timeout.rel_value); /** * Start resolution in bg @@ -869,7 +1092,7 @@ 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, @@ -926,7 +1149,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 +1178,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 +1190,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 +1221,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 +1242,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 +1283,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 +1298,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 +1324,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,12 +1365,12 @@ 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; @@ -1141,6 +1381,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); @@ -1166,11 +1408,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 @@ -1182,7 +1424,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; } @@ -1204,7 +1446,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; } @@ -1217,13 +1459,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); @@ -1253,17 +1495,17 @@ process_record_result_vpn (void* cls, int af, const void *address) 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); @@ -1274,12 +1516,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; @@ -1294,25 +1536,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 @@ -1332,22 +1562,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); } @@ -1376,14 +1603,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; } @@ -1399,8 +1625,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); + } /** @@ -1414,17 +1639,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; @@ -1468,10 +1692,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; } @@ -1485,8 +1707,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; } @@ -1497,8 +1717,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; } @@ -1509,7 +1727,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", @@ -1533,9 +1751,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; } } @@ -1568,7 +1784,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"); @@ -1583,7 +1799,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) == @@ -1600,8 +1816,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; } @@ -1616,6 +1830,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, @@ -1677,7 +1895,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, "")) @@ -1686,7 +1904,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); } @@ -1702,7 +1920,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; } @@ -1716,9 +1933,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; } @@ -1748,7 +1963,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; } @@ -1776,14 +1990,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) @@ -1801,38 +2011,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) @@ -1841,14 +2036,18 @@ 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?? rh->vpn_handle = GNUNET_VPN_redirect_to_peer (vpn_handle, - af, proto, - (struct GNUNET_PeerIdentity*)&peer_id, + af, ntohs (vpn->proto), + (struct GNUNET_PeerIdentity *)&vpn->peer, &serv_desc, GNUNET_NO, //nac GNUNET_TIME_UNIT_FOREVER_ABS, //FIXME @@ -1891,7 +2090,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, @@ -2018,6 +2217,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++) @@ -2043,7 +2243,7 @@ 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, @@ -2058,7 +2258,7 @@ 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 @@ -2072,6 +2272,40 @@ process_pkey_revocation_result_ns (void *cls, } +/** + * 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 @@ -2134,6 +2368,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); @@ -2169,8 +2405,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 @@ -2220,18 +2456,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; @@ -2240,8 +2492,8 @@ 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) { @@ -2259,32 +2511,13 @@ process_delegation_result_dht(void* cls, 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; } @@ -2304,7 +2537,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); } @@ -2312,10 +2545,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; @@ -2329,7 +2563,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; } @@ -2337,17 +2571,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); } } @@ -2355,15 +2589,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; @@ -2375,16 +2614,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; @@ -2407,34 +2650,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; } @@ -2443,7 +2702,7 @@ finish_lookup(struct ResolverHandle *rh, rlh->proc(rlh->proc_cls, rd_count, p_rd); GNUNET_free(rlh); - + free_resolver_handle (rh); } /** @@ -2465,20 +2724,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); } @@ -2500,10 +2757,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); @@ -2518,12 +2777,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) != 0) || - ((rh->status & RSL_RECORD_EXISTS) == 0) ) && - 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) != 0)) + 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); @@ -2531,17 +2800,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); } @@ -2558,7 +2825,7 @@ pop_tld(char* name, char* dest) { uint32_t len; - if (is_canonical(name)) + if (is_canonical (name)) { strcpy(dest, name); strcpy(name, ""); @@ -2632,7 +2899,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 */ @@ -2663,7 +2929,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); } @@ -2708,7 +2973,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, @@ -2756,6 +3022,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", @@ -2764,7 +3032,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; } @@ -2777,21 +3044,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) { @@ -2801,7 +3096,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, @@ -2814,13 +3108,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; } @@ -2840,7 +3133,6 @@ 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) @@ -2850,7 +3142,6 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh, "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; } } @@ -2865,13 +3156,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; } @@ -2890,9 +3180,19 @@ 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)) { @@ -2916,15 +3216,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); @@ -2963,30 +3254,31 @@ process_delegation_result_ns (void* cls, 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; } } @@ -3005,31 +3297,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; } @@ -3038,21 +3328,18 @@ process_delegation_result_ns (void* cls, * move on with query * Note only 1 pkey should have been returned.. anything else would be strange */ - 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); @@ -3076,7 +3363,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", @@ -3091,11 +3378,11 @@ 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; @@ -3106,16 +3393,16 @@ process_delegation_result_ns (void* cls, 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; } @@ -3125,19 +3412,19 @@ 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); /* 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, @@ -3193,7 +3480,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, @@ -3218,15 +3505,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; @@ -3247,9 +3534,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; @@ -3258,6 +3546,9 @@ 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; + + GNUNET_CONTAINER_DLL_insert (rlh_head, rlh_tail, rh); if (NULL == key) { @@ -3320,9 +3611,11 @@ 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; } @@ -3334,10 +3627,10 @@ gns_resolver_lookup_record(struct GNUNET_CRYPTO_ShortHashCode zone, /** * 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); } } @@ -3365,6 +3658,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 @@ -3416,25 +3722,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); } @@ -3452,9 +3757,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); @@ -3474,11 +3779,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; @@ -3495,7 +3796,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, @@ -3531,11 +3834,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); @@ -3570,10 +3872,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, @@ -3587,11 +3889,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; @@ -3608,7 +3906,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, @@ -3645,11 +3945,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); @@ -3683,15 +3982,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 { /** @@ -3700,11 +4008,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; @@ -3721,7 +4025,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, @@ -3778,44 +4084,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, @@ -3873,9 +4186,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; } @@ -3896,7 +4207,7 @@ process_zone_to_name_zkey(void *cls, /* Start delegation resolution in our namestore */ - resolve_delegation_ns(rh); + resolve_delegation_ns (rh); } @@ -3952,14 +4263,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"); @@ -3990,11 +4305,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, @@ -4026,6 +4342,18 @@ gns_resolver_shorten_name (struct GNUNET_CRYPTO_ShortHashCode *zone, /*********** END NAME SHORTEN ********************/ +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 @@ -4043,7 +4371,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; @@ -4077,23 +4404,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); } @@ -4128,6 +4449,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) { @@ -4153,6 +4477,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);