/*
This file is part of GNUnet.
- Copyright (C) 2011-2013 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2011-2013 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
*/
/**
#include "gnunet_dht_service.h"
#include "gnunet_gnsrecord_lib.h"
#include "gnunet_namecache_service.h"
-#include "gnunet_namestore_service.h"
#include "gnunet_dns_service.h"
#include "gnunet_resolver_service.h"
#include "gnunet_revocation_service.h"
#include "gnunet_tun_lib.h"
#include "gnunet_gns_service.h"
#include "gns.h"
+#include "gnunet-service-gns.h"
#include "gnunet-service-gns_resolver.h"
-#include "gnunet-service-gns_shorten.h"
#include "gnunet_vpn_service.h"
/**
* Default timeout for DNS lookups.
*/
-#define DNS_LOOKUP_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
+#define DNS_LOOKUP_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
/**
* Default timeout for VPN redirections.
/**
* Expiration time for the DNS record, 0 if we didn't
- * get anything useful (i.e. 'gethostbyname' was used).
+ * get anything useful (i.e. 'gethostbyname()' was used).
*/
uint64_t expiration_time;
*/
struct GNS_ResolverHandle *rh;
+ /**
+ * Handle for DNS resolution of the DNS nameserver.
+ */
+ struct GNUNET_RESOLVER_RequestHandle *dns_rh;
};
*/
struct AuthorityChain *ac_tail;
- /**
- * Private key of the shorten zone, NULL to not shorten.
- */
- struct GNUNET_CRYPTO_EcdsaPrivateKey *shorten_key;
-
/**
* ID of a task associated with the resolution process.
*/
- struct GNUNET_SCHEDULER_Task * task_id;
+ struct GNUNET_SCHEDULER_Task *task_id;
/**
* The name to resolve
* even though they consist of multiple labels.
*
* Examples:
- * a.b.gnu = not canonical
+ * a.b.gnu = not canonical
* a = canonical
* _foo._srv = canonical
* _f.bar = not canonical
* @param name the name to test
* @return #GNUNET_YES if canonical
*/
-static int
+/* dead, but keep for now */ int
is_canonical (const char *name)
{
const char *pos;
const char *dot;
- if (NULL == strchr (name, '.'))
+ if (NULL == strchr (name,
+ (unsigned char) '.'))
return GNUNET_YES;
if ('_' != name[0])
return GNUNET_NO;
pos = &name[1];
- while (NULL != (dot = strchr (pos, '.')))
+ while (NULL != (dot = strchr (pos,
+ (unsigned char) '.')))
if ('_' != dot[1])
return GNUNET_NO;
else
* Task scheduled to asynchronously fail a resolution.
*
* @param cls the 'struct GNS_ResolverHandle' of the resolution to fail
- * @param tc task context
*/
static void
-fail_resolution (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+fail_resolution (void *cls)
{
struct GNS_ResolverHandle *rh = cls;
}
rh->protocol = pe->p_proto;
rh->service = se->s_port;
+ GNUNET_free (proto_name);
+ GNUNET_free (srv_name);
}
return ret;
}
res->data_size = data_size;
res->record_type = record_type;
res->data = &res[1];
- memcpy (&res[1], data, data_size);
+ GNUNET_memcpy (&res[1], data, data_size);
GNUNET_CONTAINER_DLL_insert (rh->dns_result_head,
rh->dns_result_tail,
res);
* @param tc task context
*/
static void
-recursive_resolution (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc);
+recursive_resolution (void *cls);
/**
* Begin the resolution process from 'name', starting with
* the identification of the zone specified by 'name'.
*
- * @param rh resolution to perform
+ * @param cls closure with `struct GNS_ResolverHandle *rh`
*/
static void
-start_resolver_lookup (struct GNS_ResolverHandle *rh);
+start_resolver_lookup (void *cls);
/**
unsigned int rd_count;
unsigned int i;
+ (void) rs;
rh->dns_request = NULL;
GNUNET_SCHEDULER_cancel (rh->task_id);
rh->task_id = NULL;
(GNUNET_DNSPARSER_TYPE_CNAME == p->answers[0].type) &&
(GNUNET_DNSPARSER_TYPE_CNAME != rh->record_type) )
{
+ int af;
+
GNUNET_free (rh->name);
rh->name = GNUNET_strdup (p->answers[0].data.hostname);
rh->name_resolution_pos = strlen (rh->name);
- start_resolver_lookup (rh);
+ switch (rh->record_type)
+ {
+ case GNUNET_DNSPARSER_TYPE_A:
+ af = AF_INET;
+ break;
+ case GNUNET_DNSPARSER_TYPE_AAAA:
+ af = AF_INET6;
+ break;
+ default:
+ af = AF_UNSPEC;
+ break;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Doing standard DNS lookup for `%s'\n",
+ rh->name);
+ rh->std_resolve = GNUNET_RESOLVER_ip_get (rh->name,
+ af,
+ DNS_LOOKUP_TIMEOUT,
+ &handle_dns_result,
+ rh);
GNUNET_DNSPARSER_free_packet (p);
return;
}
buf_start = buf_off;
if (GNUNET_OK !=
GNUNET_DNSPARSER_builder_add_soa (buf,
- sizeof (buf),
- &buf_off,
- rec->data.soa))
+ sizeof (buf),
+ &buf_off,
+ rec->data.soa))
{
GNUNET_break (0);
skip++;
"Returning DNS response for `%s' with %u answers\n",
rh->ac_tail->label,
(unsigned int) p->num_answers);
- rh->proc (rh->proc_cls, rd_count - skip, rd);
+ rh->proc (rh->proc_cls,
+ rd_count - skip,
+ rd);
GNS_resolver_lookup_cancel (rh);
}
GNUNET_DNSPARSER_free_packet (p);
struct GNUNET_DNSPARSER_Packet *p;
char *dns_request;
size_t dns_request_length;
+ int ret;
ac = rh->ac_tail;
GNUNET_assert (NULL != ac);
UINT16_MAX);
p->flags.opcode = GNUNET_TUN_DNS_OPCODE_QUERY;
p->flags.recursion_desired = 1;
- if (GNUNET_OK !=
- GNUNET_DNSPARSER_pack (p, 1024, &dns_request, &dns_request_length))
+ ret = GNUNET_DNSPARSER_pack (p,
+ 1024,
+ &dns_request,
+ &dns_request_length);
+ if (GNUNET_OK != ret)
{
GNUNET_break (0);
- rh->proc (rh->proc_cls, 0, NULL);
+ rh->proc (rh->proc_cls,
+ 0,
+ NULL);
GNS_resolver_lookup_cancel (rh);
}
else
&fail_resolution,
rh);
}
- GNUNET_free (dns_request);
+ if (GNUNET_SYSERR != ret)
+ GNUNET_free (dns_request);
GNUNET_DNSPARSER_free_packet (p);
}
size_t nlen;
char *res;
struct AuthorityChain *ac;
+ int af;
nlen = strlen (cname);
if ( (nlen > 2) &&
rh);
return;
}
- /* name is absolute, start from the beginning */
+ /* name is absolute, go to DNS */
GNUNET_free (rh->name);
rh->name = GNUNET_strdup (cname);
rh->name_resolution_pos = strlen (rh->name);
- start_resolver_lookup (rh);
+ switch (rh->record_type)
+ {
+ case GNUNET_DNSPARSER_TYPE_A:
+ af = AF_INET;
+ break;
+ case GNUNET_DNSPARSER_TYPE_AAAA:
+ af = AF_INET6;
+ break;
+ default:
+ af = AF_UNSPEC;
+ break;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Doing standard DNS lookup for `%s'\n",
+ rh->name);
+ rh->std_resolve = GNUNET_RESOLVER_ip_get (rh->name,
+ af,
+ DNS_LOOKUP_TIMEOUT,
+ &handle_dns_result,
+ rh);
}
{
struct GNS_ResolverHandle *rh = cls;
struct AuthorityChain *ac;
- unsigned int j;
struct sockaddr *sa;
struct sockaddr_in v4;
struct sockaddr_in6 v6;
"Received %u results for IP address of DNS server for GNS2DNS transition\n",
rd_count);
/* enable cleanup of 'rh' handle that comes next... */
- GNUNET_CONTAINER_DLL_insert (rlh_head,
- rlh_tail,
- rh->g2dc->rh);
- rh->g2dc->rh = NULL;
+ if (NULL != rh->g2dc->rh)
+ {
+ GNUNET_CONTAINER_DLL_insert (rlh_head,
+ rlh_tail,
+ rh->g2dc->rh);
+ rh->g2dc->rh = NULL;
+ }
sa = NULL;
sa_len = 0;
- for (j=0;j<rd_count;j++)
+ for (unsigned int j=0;j<rd_count;j++)
{
switch (rd[j].record_type)
{
#if HAVE_SOCKADDR_IN_SIN_LEN
v4.sin_len = (u_char) sa_len;
#endif
- memcpy (&v4.sin_addr,
+ GNUNET_memcpy (&v4.sin_addr,
rd[j].data,
sizeof (struct in_addr));
sa = (struct sockaddr *) &v4;
#if HAVE_SOCKADDR_IN_SIN_LEN
v6.sin6_len = (u_char) sa_len;
#endif
- memcpy (&v6.sin6_addr,
+ GNUNET_memcpy (&v6.sin6_addr,
rd[j].data,
sizeof (struct in6_addr));
sa = (struct sockaddr *) &v6;
/* expand authority chain */
ac = GNUNET_new (struct AuthorityChain);
ac->rh = rh;
+ GNUNET_assert (strlen (rh->g2dc->ns) <= GNUNET_DNSPARSER_MAX_NAME_LENGTH);
strcpy (ac->authority_info.dns_authority.name,
rh->g2dc->ns);
- memcpy (&ac->authority_info.dns_authority.dns_ip,
+ GNUNET_memcpy (&ac->authority_info.dns_authority.dns_ip,
sa,
sa_len);
/* for DNS recursion, the label is the full DNS name,
rh->g2dc = NULL;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Will continue resolution using DNS server `%s' to resolve `%s'\n",
- GNUNET_a2s (sa, sa_len),
+ GNUNET_a2s (sa,
+ sa_len),
ac->label);
GNUNET_CONTAINER_DLL_insert_tail (rh->ac_head,
rh->ac_tail,
}
+/**
+ * Function called by the resolver for each address obtained from DNS.
+ *
+ * @param cls closure, a `struct Gns2DnsContext *`
+ * @param addr one of the addresses of the host, NULL for the last address
+ * @param addrlen length of @a addr
+ */
+static void
+handle_gns2dns_ip (void *cls,
+ const struct sockaddr *addr,
+ socklen_t addrlen)
+{
+ struct Gns2DnsContext *g2dc = cls;
+ struct GNUNET_GNSRECORD_Data rd;
+
+ if (NULL == addr)
+ {
+ /* DNS resolution failed */
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Failed to use DNS to resolve name of DNS resolver\n");
+ g2dc->rh->g2dc = NULL;
+ fail_resolution (g2dc->rh);
+ GNUNET_free (g2dc);
+ }
+ switch (addr->sa_family)
+ {
+ case AF_INET:
+ {
+ const struct sockaddr_in *v4 = (const struct sockaddr_in *) addr;
+
+ GNUNET_assert (sizeof (*v4) == addrlen);
+ rd.data = v4;
+ rd.data_size = sizeof (*v4);
+ rd.expiration_time = UINT64_MAX;
+ rd.record_type = GNUNET_DNSPARSER_TYPE_A;
+ rd.flags = 0;
+ break;
+ }
+ case AF_INET6:
+ {
+ const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *) addr;
+
+ GNUNET_assert (sizeof (*v6) == addrlen);
+ rd.data = v6;
+ rd.data_size = sizeof (v6);
+ rd.expiration_time = UINT64_MAX;
+ rd.record_type = GNUNET_DNSPARSER_TYPE_AAAA;
+ rd.flags = 0;
+ break;
+ }
+ default:
+ return;
+ }
+ GNUNET_RESOLVER_request_cancel (g2dc->dns_rh);
+ g2dc->dns_rh = NULL;
+ handle_gns2dns_result (g2dc->rh,
+ 1,
+ &rd);
+
+}
+
+
+
/**
* Process a records that were decrypted from a block.
*
struct GNS_ResolverHandle *rh = cls;
struct AuthorityChain *ac;
struct AuthorityChain *shorten_ac;
- unsigned int i;
char *cname;
struct VpnContext *vpn_ctx;
const struct GNUNET_TUN_GnsVpnRecord *vpn;
if ( (GNUNET_DNSPARSER_TYPE_A == rh->record_type) ||
(GNUNET_DNSPARSER_TYPE_AAAA == rh->record_type) )
{
- for (i=0;i<rd_count;i++)
+ for (unsigned int i=0;i<rd_count;i++)
{
switch (rd[i].record_type)
{
vpn_ctx->rd_data = GNUNET_malloc (vpn_ctx->rd_data_size);
vpn_ctx->rd_count = rd_count;
GNUNET_assert (vpn_ctx->rd_data_size ==
- GNUNET_GNSRECORD_records_serialize (rd_count,
- rd,
- vpn_ctx->rd_data_size,
- vpn_ctx->rd_data));
+ (size_t) GNUNET_GNSRECORD_records_serialize (rd_count,
+ rd,
+ vpn_ctx->rd_data_size,
+ vpn_ctx->rd_data));
vpn_ctx->vpn_request = GNUNET_VPN_redirect_to_peer (vpn_handle,
af,
ntohs (vpn->proto),
scratch_off = 0;
rd_off = 0;
shorten_ac = rh->ac_tail;
- for (i=0;i<rd_count;i++)
+ for (unsigned int i=0;i<rd_count;i++)
{
+ GNUNET_assert (rd_off <= i);
if ( (0 != rh->protocol) &&
(0 != rh->service) &&
(GNUNET_GNSRECORD_TYPE_BOX != rd[i].record_type) )
continue; /* we _only_ care about boxed records */
+ GNUNET_assert (rd_off < rd_count);
rd_new[rd_off] = rd[i];
/* Check if the embedded name(s) end in "+", and if so,
replace the "+" with the zone at "ac_tail", changing the name
- to a ".zkey". The name is allocated on the 'scratch' array,
+ to a ".ZONEKEY". The name is allocated on the 'scratch' array,
so we can free it afterwards. */
switch (rd[i].record_type)
{
}
else
{
+ GNUNET_assert (rd_off < rd_count);
rd_new[rd_off].data = &scratch[scratch_start];
rd_new[rd_off].data_size = scratch_off - scratch_start;
rd_off++;
}
else
{
+ GNUNET_assert (rd_off < rd_count);
rd_new[rd_off].data = &scratch[scratch_start];
rd_new[rd_off].data_size = scratch_off - scratch_start;
rd_off++;
}
else
{
+ GNUNET_assert (rd_off < rd_count);
rd_new[rd_off].data = &scratch[scratch_start];
rd_new[rd_off].data_size = scratch_off - scratch_start;
rd_off++;
}
else
{
+ GNUNET_assert (rd_off < rd_count);
rd_new[rd_off].data = &scratch[scratch_start];
rd_new[rd_off].data_size = scratch_off - scratch_start;
rd_off++;
GNUNET_break_op (0);
break;
}
- memcpy (&pub, rd[i].data, rd[i].data_size);
+ GNUNET_memcpy (&pub, rd[i].data, rd[i].data_size);
rd_off++;
if (GNUNET_GNSRECORD_TYPE_PKEY != rh->record_type)
{
(ntohs (box->service) == rh->service) )
{
/* Box matches, unbox! */
+ GNUNET_assert (rd_off < rd_count);
rd_new[rd_off].record_type = ntohl (box->record_type);
rd_new[rd_off].data_size -= sizeof (struct GNUNET_GNSRECORD_BoxRecord);
rd_new[rd_off].data = &box[1];
records (for modern, GNS-enabled applications) */
rd_off++;
}
+ break;
}
default:
rd_off++;
} /* end: switch */
} /* end: for rd_count */
- /* trigger shortening */
- if ((NULL != rh->shorten_key) &&
- (NULL != shorten_ac) &&
- (GNUNET_NO == shorten_ac->shortening_started) &&
- (NULL != shorten_ac->suggested_shortening_label))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Start shortening for label `%s' based on nick `%s'\n",
- shorten_ac->label,
- shorten_ac->suggested_shortening_label);
- shorten_ac->shortening_started = GNUNET_YES;
- GNS_shorten_start (shorten_ac->label,
- shorten_ac->suggested_shortening_label,
- &shorten_ac->authority_info.gns_authority,
- rh->shorten_key);
- }
-
/* yes, we are done, return result */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Returning GNS response for `%s' with %u answers\n",
rh->ac_tail->label,
rd_off);
- rh->proc (rh->proc_cls, rd_off, rd_new);
+ rh->proc (rh->proc_cls,
+ rd_off,
+ rd_new);
GNS_resolver_lookup_cancel (rh);
return;
}
do_recurse:
/* need to recurse, check if we can */
- for (i=0;i<rd_count;i++)
+ for (unsigned int i=0;i<rd_count;i++)
{
switch (rd[i].record_type)
{
ac->gns_authority = GNUNET_YES;
ac->suggested_shortening_label = NULL;
ac->shortening_started = GNUNET_NO;
- memcpy (&ac->authority_info.gns_authority,
+ GNUNET_memcpy (&ac->authority_info.gns_authority,
rd[i].data,
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
ac->label = resolver_lookup_get_next_label (rh);
struct Gns2DnsContext *g2dc;
char *ip;
char *ns;
+ const char *tld;
+ struct GNUNET_CRYPTO_EcdsaPublicKey zone;
+ struct in_addr v4;
+ struct in6_addr v6;
off = 0;
ns = GNUNET_DNSPARSER_parse_name (rd[i].data,
GNUNET_break_op (0);
GNUNET_free_non_null (ns);
GNUNET_free_non_null (ip);
- rh->proc (rh->proc_cls, 0, NULL);
- GNS_resolver_lookup_cancel (rh);
+ fail_resolution (rh);
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Resolving `%s' to determine IP address of DNS server for GNS2DNS transition\n",
- ip);
/* resolve 'ip' to determine the IP(s) of the DNS
- resolver to use */
+ resolver to use for lookup of 'ns' */
g2dc = GNUNET_new (struct Gns2DnsContext);
g2dc->ns = ns;
+ rh->g2dc = g2dc;
+ /* check if 'ip' is already an IPv4/IPv6 address */
+ if (1 == inet_pton (AF_INET,
+ ip,
+ &v4))
+ {
+ /* name is IPv4 address, pretend it's an A record */
+ struct GNUNET_GNSRECORD_Data rd;
+
+ GNUNET_free (ip);
+ rd.data = &v4;
+ rd.data_size = sizeof (v4);
+ rd.expiration_time = UINT64_MAX;
+ rd.record_type = GNUNET_DNSPARSER_TYPE_A;
+ rd.flags = 0;
+ handle_gns2dns_result (rh,
+ 1,
+ &rd);
+ return;
+ }
+ if (1 == inet_pton (AF_INET6,
+ ip,
+ &v6))
+ {
+ /* name is IPv6 address, pretend it's an AAAA record */
+ struct GNUNET_GNSRECORD_Data rd;
+
+ GNUNET_free (ip);
+ rd.data = &v6;
+ rd.data_size = sizeof (v6);
+ rd.expiration_time = UINT64_MAX;
+ rd.record_type = GNUNET_DNSPARSER_TYPE_AAAA;
+ rd.flags = 0;
+ handle_gns2dns_result (rh,
+ 1,
+ &rd);
+ return;
+ }
+
+ tld = GNS_get_tld (ip);
+ if (0 != strcmp (tld,
+ "+"))
+ {
+ /* 'ip' is a DNS name */
+ g2dc->dns_rh = GNUNET_RESOLVER_ip_get (ip,
+ AF_UNSPEC,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &handle_gns2dns_ip,
+ g2dc);
+ GNUNET_free (ip);
+ return;
+ }
+
+ /* 'ip' should be a GNS name */
g2dc->rh = GNUNET_new (struct GNS_ResolverHandle);
- g2dc->rh->authority_zone = rh->ac_tail->authority_info.gns_authority;
- ip = translate_dot_plus (rh, ip);
+
+ ip = translate_dot_plus (rh,
+ ip);
+ tld = GNS_get_tld (ip);
+ if (GNUNET_OK !=
+ GNUNET_GNSRECORD_zkey_to_pkey (tld,
+ &zone))
+ {
+ GNUNET_break_op (0);
+ GNUNET_free_non_null (ns);
+ GNUNET_free_non_null (ip);
+ GNUNET_free (g2dc);
+ fail_resolution (rh);
+ return;
+ }
+ g2dc->rh->authority_zone = zone;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Resolving `%s' to determine IP address of DNS server for GNS2DNS transition for `%s'\n",
+ ip,
+ ns);
g2dc->rh->name = ip;
- g2dc->rh->name_resolution_pos = strlen (ip);
+ g2dc->rh->name_resolution_pos = strlen (ip) - strlen (tld) - 1;
g2dc->rh->proc = &handle_gns2dns_result;
g2dc->rh->proc_cls = rh;
g2dc->rh->record_type = GNUNET_GNSRECORD_TYPE_ANY;
g2dc->rh->options = GNUNET_GNS_LO_DEFAULT;
g2dc->rh->loop_limiter = rh->loop_limiter + 1;
- rh->g2dc = g2dc;
- start_resolver_lookup (g2dc->rh);
+ g2dc->rh->task_id
+ = GNUNET_SCHEDULER_add_now (&start_resolver_lookup,
+ g2dc->rh);
return;
}
case GNUNET_DNSPARSER_TYPE_CNAME:
}
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
_("GNS lookup recursion failed (no delegation record found)\n"));
- rh->proc (rh->proc_cls, 0, NULL);
+ rh->proc (rh->proc_cls,
+ 0,
+ NULL);
GNS_resolver_lookup_cancel (rh);
}
struct CacheOps *co = cls;
co->namecache_qe_cache = NULL;
- if (NULL != emsg)
+ if (GNUNET_OK != success)
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
_("Failed to cache GNS resolution: %s\n"),
emsg);
const struct GNUNET_PeerIdentity *put_path,
unsigned int put_path_length,
enum GNUNET_BLOCK_Type type,
- size_t size, const void *data)
+ size_t size,
+ const void *data)
{
struct GNS_ResolverHandle *rh = cls;
struct AuthorityChain *ac = rh->ac_tail;
const struct GNUNET_GNSRECORD_Block *block;
struct CacheOps *co;
+ (void) exp;
+ (void) key;
+ (void) get_path;
+ (void) get_path_length;
+ (void) put_path;
+ (void) put_path_length;
+ (void) type;
GNUNET_DHT_get_stop (rh->get_handle);
rh->get_handle = NULL;
GNUNET_CONTAINER_heap_remove_node (rh->dht_heap_node);
* Task scheduled to continue with the resolution process.
*
* @param cls the `struct GNS_ResolverHandle` of the resolution
- * @param tc task context
*/
static void
-recursive_resolution (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+recursive_resolution (void *cls)
{
struct GNS_ResolverHandle *rh = cls;
* Begin the resolution process from 'name', starting with
* the identification of the zone specified by 'name'.
*
- * @param rh resolution to perform
+ * @param cls the `struct GNS_ResolverHandle`
*/
static void
-start_resolver_lookup (struct GNS_ResolverHandle *rh)
+start_resolver_lookup (void *cls)
{
+ struct GNS_ResolverHandle *rh = cls;
struct AuthorityChain *ac;
- char *y;
struct in_addr v4;
struct in6_addr v6;
+ rh->task_id = NULL;
if (1 == inet_pton (AF_INET,
rh->name,
&v4))
GNS_resolver_lookup_cancel (rh);
return;
}
- if ( ( (GNUNET_YES == is_canonical (rh->name)) &&
- (0 != strcmp (GNUNET_GNS_TLD, rh->name)) ) ||
- ( (GNUNET_YES != is_gnu_tld (rh->name)) &&
- (GNUNET_YES != is_zkey_tld (rh->name)) ) )
- {
- /* use standard DNS lookup */
- int af;
- switch (rh->record_type)
- {
- case GNUNET_DNSPARSER_TYPE_A:
- af = AF_INET;
- break;
- case GNUNET_DNSPARSER_TYPE_AAAA:
- af = AF_INET6;
- break;
- default:
- af = AF_UNSPEC;
- break;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Doing standard DNS lookup for `%s'\n",
- rh->name);
- rh->std_resolve = GNUNET_RESOLVER_ip_get (rh->name,
- af,
- DNS_LOOKUP_TIMEOUT,
- &handle_dns_result,
- rh);
- return;
- }
- if (is_zkey_tld (rh->name))
- {
- /* Name ends with ".zkey", try to replace authority zone with zkey
- authority */
- GNUNET_free (resolver_lookup_get_next_label (rh)); /* will return "zkey" */
- y = resolver_lookup_get_next_label (rh); /* will return 'y' coordinate */
- if ( (NULL == y) ||
- (GNUNET_OK !=
- GNUNET_CRYPTO_ecdsa_public_key_from_string (y,
- strlen (y),
- &rh->authority_zone)) )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _("Hostname `%s' is not well-formed, resolution fails\n"),
- rh->name);
- rh->task_id = GNUNET_SCHEDULER_add_now (&fail_resolution, rh);
- }
- GNUNET_free_non_null (y);
- }
- else
- {
- /* Name ends with ".gnu", eat ".gnu" and continue with resolution */
- GNUNET_free (resolver_lookup_get_next_label (rh));
- }
ac = GNUNET_new (struct AuthorityChain);
ac->rh = rh;
ac->label = resolver_lookup_get_next_label (rh);
ac->suggested_shortening_label = NULL;
if (NULL == ac->label)
- /* name was just "gnu", so we default to label '+' */
+ /* name was just the "TLD", so we default to label
+ #GNUNET_GNS_MASTERZONE_STR */
ac->label = GNUNET_strdup (GNUNET_GNS_MASTERZONE_STR);
ac->gns_authority = GNUNET_YES;
ac->authority_info.gns_authority = rh->authority_zone;
* @param zone the zone to perform the lookup in
* @param record_type the record type to look up
* @param name the name to look up
- * @param shorten_key a private key for use with PSEU import (can be NULL)
* @param options local options to control local lookup
* @param proc the processor to call on result
* @param proc_cls the closure to pass to @a proc
GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
uint32_t record_type,
const char *name,
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *shorten_key,
enum GNUNET_GNS_LocalOptions options,
- GNS_ResultProcessor proc, void *proc_cls)
+ GNS_ResultProcessor proc,
+ void *proc_cls)
{
struct GNS_ResolverHandle *rh;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- (NULL == shorten_key)
- ? "Starting lookup for `%s' with shortening disabled\n"
- : "Starting lookup for `%s' with shortening enabled\n",
+ "Starting lookup for `%s'\n",
name);
rh = GNUNET_new (struct GNS_ResolverHandle);
GNUNET_CONTAINER_DLL_insert (rlh_head,
rh->record_type = record_type;
rh->name = GNUNET_strdup (name);
rh->name_resolution_pos = strlen (name);
- if (NULL != shorten_key)
- {
- rh->shorten_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey);
- *rh->shorten_key = *shorten_key;
- }
- start_resolver_lookup (rh);
+ rh->task_id = GNUNET_SCHEDULER_add_now (&start_resolver_lookup,
+ rh);
return rh;
}
GNS_resolver_lookup_cancel (rh->g2dc->rh);
rh->g2dc->rh = NULL;
}
+ if (NULL != rh->g2dc->dns_rh)
+ {
+ GNUNET_RESOLVER_request_cancel (rh->g2dc->dns_rh);
+ rh->g2dc->rh = NULL;
+ }
GNUNET_free (rh->g2dc->ns);
GNUNET_free (rh->g2dc);
rh->g2dc = NULL;
dr);
GNUNET_free (dr);
}
- GNUNET_free_non_null (rh->shorten_key);
GNUNET_free (rh->name);
GNUNET_free (rh);
}
dht_lookup_heap =
GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
max_allowed_background_queries = max_bg_queries;
- if (GNUNET_SYSERR == (use_cache = GNUNET_CONFIGURATION_get_value_yesno (c,
- "gns",
- "USE_CACHE")))
+ if (GNUNET_SYSERR == (use_cache =
+ GNUNET_CONFIGURATION_get_value_yesno (c,
+ "gns",
+ "USE_CACHE")))
use_cache = GNUNET_YES;
if (GNUNET_NO == use_cache)
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Namecache disabled\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Namecache disabled\n");
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (c,
}
-/* *************** common helper functions (do not really belong here) *********** */
-
-/**
- * Checks if @a name ends in ".TLD"
- *
- * @param name the name to check
- * @param tld the TLD to check for
- * @return GNUNET_YES or GNUNET_NO
- */
-int
-is_tld (const char* name, const char* tld)
-{
- size_t offset = 0;
-
- if (strlen (name) <= strlen (tld))
- return GNUNET_NO;
- offset = strlen (name) - strlen (tld);
- if (0 != strcmp (name + offset, tld))
- return GNUNET_NO;
- return GNUNET_YES;
-}
-
-
/* end of gnunet-service-gns_resolver.c */