#include "gns.h"
#include "gnunet-service-gns_resolver.h"
-#define DHT_OPERATION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
#define DHT_LOOKUP_TIMEOUT DHT_OPERATION_TIMEOUT
#define DHT_GNS_REPLICATION_LEVEL 5
#define MAX_DNS_LABEL_LENGTH 63
*/
static unsigned long long max_allowed_background_queries;
+/**
+ * Wheather or not to ignore pending records
+ */
+static int ignore_pending_records;
+
/**
* Our local zone
*/
GNUNET_NAMESTORE_lookup_record(namestore_handle,
&gph->zone,
gph->new_name,
- GNUNET_GNS_RECORD_PSEU,
+ GNUNET_NAMESTORE_TYPE_ANY,
&process_pseu_lookup_ns,
gph);
return;
new_pkey.data_size = sizeof(struct GNUNET_CRYPTO_ShortHashCode);
new_pkey.data = &gph->new_zone;
new_pkey.record_type = GNUNET_GNS_RECORD_PKEY;
+ new_pkey.flags = GNUNET_NAMESTORE_RF_AUTHORITY
+ | GNUNET_NAMESTORE_RF_PRIVATE
+ | GNUNET_NAMESTORE_RF_PENDING;
GNUNET_NAMESTORE_record_create (namestore_handle,
gph->key,
gph->new_name,
* @param dh the dht handle
* @param lz the local zone's hash
* @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,
- unsigned long long max_bg_queries)
+ unsigned long long max_bg_queries,
+ int ignore_pending)
{
namestore_handle = nh;
dht_handle = dh;
dht_lookup_heap =
GNUNET_CONTAINER_heap_create(GNUNET_CONTAINER_HEAP_ORDER_MIN);
max_allowed_background_queries = max_bg_queries;
+ ignore_pending_records = ignore_pending;
if ((namestore_handle != NULL) && (dht_handle != NULL))
{
ResolverCleanupContinuation cont = cls;
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
- "GNS_CLEANUP-%d: Terminating background lookup for %s\n",
+ "GNS_CLEANUP-%llu: Terminating background lookup for %s\n",
rh->id, rh->name);
GNUNET_DHT_get_stop(rh->get_handle);
rh->get_handle = NULL;
if (name != NULL)
{
- rh->status |= EXISTS;
+ rh->status |= RSL_RECORD_EXISTS;
}
if (remaining_time.rel_value == 0)
{
- rh->status |= EXPIRED;
+ rh->status |= RSL_RECORD_EXPIRED;
}
if (rd_count == 0)
if (rd[i].record_type != rlh->record_type)
continue;
+
+ if (ignore_pending_records &&
+ (rd[i].flags & GNUNET_NAMESTORE_RF_PENDING))
+ {
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+ "GNS_PHASE_REC-%d: Record %s is awaiting user confirmation. Skipping\n",
+ rh->id, name);
+ continue;
+ }
if ((GNUNET_TIME_absolute_get_remaining (rd[i].expiration)).rel_value
== 0)
"GNS_PHASE_DELEGATE_DHT-%llu: dht lookup for query %s (%ds)timed out.\n",
rh->id, rh->authority_name, rh->timeout.rel_value);
- rh->status |= TIMED_OUT;
+ rh->status |= RSL_TIMED_OUT;
rh->timeout_task = GNUNET_SCHEDULER_NO_TASK;
/**
* There are 4 conditions that have to met for us to consult the DHT:
- * 1. The entry in the DHT is EXPIRED AND
+ * 1. The entry in the DHT is RSL_RECORD_EXPIRED AND
* 2. No entry in the NS existed AND
* 3. The zone queried is not the local resolver's zone AND
* 4. The name that was looked up is '+'
* the DHT for the authority in the authority lookup phase (and thus
* would already have an entry in the NS for the record)
*/
- if (rh->status & (EXPIRED | !EXISTS) &&
+ if (rh->status & (RSL_RECORD_EXPIRED | !RSL_RECORD_EXISTS) &&
GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
&local_zone) &&
(strcmp(rh->name, "+") == 0))
{
struct RecordLookupHandle* rlh;
rlh = (struct RecordLookupHandle*) cls;
+
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+ "GNS_PHASE_DELEGATE_NS-%llu: Resolution status: %d.\n",
+ rh->id, rh->status);
if (strcmp(rh->name, "") == 0)
{
* and exists
* or we are authority
**/
- if ((rh->status & (EXISTS | !EXPIRED)) ||
- !GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
- &rh->authority_chain_tail->zone))
+ if (((rh->status & RSL_RECORD_EXISTS) && (!(rh->status & RSL_RECORD_EXPIRED)))
+ || !GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
+ &local_zone))
{
if (is_canonical(rh->name))
{
if (name != NULL)
{
- rh->status |= EXISTS;
+ 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)
{
- rh->status |= EXPIRED;
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+ "GNS_PHASE_DELEGATE_NS-%llu: Record set %s expired.\n",
+ rh->id, name);
+ rh->status |= RSL_RECORD_EXPIRED;
}
/**
if (rd[i].record_type != GNUNET_GNS_RECORD_PKEY)
continue;
- if (rd[i].flags & GNUNET_NAMESTORE_RF_PENDING)
+ if (ignore_pending_records &&
+ (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: Authority lookup and no PKEY...\n", rh->id);
- rh->proc(rh->proc_cls, rh, 0, NULL);
+ /**
+ * If we have found some records for the LAST label
+ * we return the results. Else null.
+ */
+ 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);
+ rh->proc(rh->proc_cls, rh, rd_count, rd);
+ }
+ else
+ {
+ rh->proc(rh->proc_cls, rh, 0, NULL);
+ }
}
GNUNET_NAMESTORE_lookup_record(namestore_handle,
&rh->authority,
rh->authority_name,
- GNUNET_GNS_RECORD_PKEY,
+ GNUNET_GNS_RECORD_ANY,
&process_delegation_result_ns,
rh);