GNUnet  0.19.5
gnunet-service-gns_resolver.c File Reference

GNU Name System resolver logic. More...

Include dependency graph for gnunet-service-gns_resolver.c:

Go to the source code of this file.

Data Structures

struct  Gns2DnsPending
 Element of a resolution process for looking up the responsible DNS server hostname in a GNS2DNS recursive resolution. More...
 
struct  AuthorityChain
 DLL to hold the authority chain we had to pass in the resolution process. More...
 
struct  DnsResult
 A result we got from DNS. More...
 
struct  GNS_ResolverHandle
 Handle to a currently pending resolution. More...
 
struct  CacheOps
 Active namestore caching operations. More...
 

Macros

#define DHT_LOOKUP_TIMEOUT
 Default DHT timeout for lookups. More...
 
#define DNS_LOOKUP_TIMEOUT
 Default timeout for DNS lookups. More...
 
#define DHT_GNS_REPLICATION_LEVEL   10
 DHT replication level. More...
 

Functions

int is_canonical (const char *name)
 Determine if this name is canonical (is a legal name in a zone, without delegation); note that we do not test that the name does not contain illegal characters, we only test for delegation. More...
 
static char * translate_dot_plus (struct GNS_ResolverHandle *rh, char *name)
 Expands a name ending in . More...
 
static void GNS_resolver_lookup_cancel_ (void *cls)
 Wrapper around GNS_resolver_lookup_cancel() as a task. More...
 
static void fail_resolution (struct GNS_ResolverHandle *rh)
 Function called to asynchronously fail a resolution. More...
 
static void timeout_resolution (void *cls)
 Function called when a resolution times out. More...
 
static char * resolver_lookup_get_next_label (struct GNS_ResolverHandle *rh)
 Get the next, rightmost label from the name that we are trying to resolve, and update the resolution position accordingly. More...
 
static void transmit_lookup_dns_result (struct GNS_ResolverHandle *rh)
 Gives the cumulative result obtained to the callback and clean up the request. More...
 
static void add_dns_result (struct GNS_ResolverHandle *rh, uint64_t expiration_time, uint32_t record_type, size_t data_size, const void *data)
 Add a result from DNS to the records to be returned to the application. More...
 
static void handle_dns_result (void *cls, const struct sockaddr *addr, socklen_t addrlen)
 We had to do a DNS lookup. More...
 
static void recursive_resolution (void *cls)
 Task scheduled to continue with the resolution process. More...
 
static void start_resolver_lookup (void *cls)
 Begin the resolution process from 'name', starting with the identification of the zone specified by 'name'. More...
 
static void dns_result_parser (void *cls, const struct GNUNET_TUN_DnsHeader *dns, size_t dns_len)
 Function called with the result of a DNS resolution. More...
 
static void recursive_dns_resolution (struct GNS_ResolverHandle *rh)
 Perform recursive DNS resolution. More...
 
static void handle_gns_redirect_result (struct GNS_ResolverHandle *rh, const char *rname)
 We encountered a REDIRECT record during our resolution. More...
 
static void handle_gns_cname_result (struct GNS_ResolverHandle *rh, const char *cname)
 We encountered a CNAME record during our resolution. More...
 
static void handle_gns_resolution_result (void *cls, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
 Process records that were decrypted from a block. More...
 
static void continue_with_gns2dns (struct AuthorityChain *ac)
 We have resolved one or more of the nameservers for a GNS2DNS lookup. More...
 
static void handle_gns2dns_result (void *cls, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
 We've resolved the IP address for the DNS resolver to use after encountering a GNS2DNS record. More...
 
static void handle_gns2dns_ip (void *cls, const struct sockaddr *addr, socklen_t addrlen)
 Function called by the resolver for each address obtained from DNS. More...
 
static void recursive_redirect_resolution (struct GNS_ResolverHandle *rh, const struct GNUNET_GNSRECORD_Data *rd)
 We found a REDIRECT record, perform recursive resolution on it. More...
 
static void recursive_cname_resolution (struct GNS_ResolverHandle *rh, const struct GNUNET_GNSRECORD_Data *rd)
 We found a CNAME record, perform recursive resolution on it. More...
 
static void recursive_pkey_resolution (struct GNS_ResolverHandle *rh, const struct GNUNET_GNSRECORD_Data *rd)
 We found a PKEY record, perform recursive resolution on it. More...
 
static int recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
 We found one or more GNS2DNS records, perform recursive resolution on it. More...
 
static void namecache_cache_continuation (void *cls, int32_t success, const char *emsg)
 Function called once the namestore has completed the request for caching a block. More...
 
static void handle_dht_response (void *cls, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const struct GNUNET_PeerIdentity *trunc_peer, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *put_path, unsigned int put_path_length, enum GNUNET_BLOCK_Type type, size_t size, const void *data)
 Iterator called on each result obtained for a DHT operation that expects a reply. More...
 
static void start_dht_request (struct GNS_ResolverHandle *rh, const struct GNUNET_HashCode *query)
 Initiate a DHT query for a set of GNS records. More...
 
static void handle_gns_namecache_resolution_result (void *cls, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
 Process a records that were decrypted from a block that we got from the namecache. More...
 
static void handle_namecache_block_response (void *cls, const struct GNUNET_GNSRECORD_Block *block)
 Process a record that was stored in the namecache. More...
 
static void recursive_gns_resolution_namecache (struct GNS_ResolverHandle *rh)
 Lookup tail of our authority chain in the namecache. More...
 
static void handle_revocation_result (void *cls, int is_valid)
 Function called with the result from a revocation check. More...
 
static void recursive_gns_resolution_revocation (struct GNS_ResolverHandle *rh)
 Perform revocation check on tail of our authority chain. More...
 
struct GNS_ResolverHandleGNS_resolver_lookup (const struct GNUNET_IDENTITY_PublicKey *zone, uint32_t record_type, const char *name, enum GNUNET_GNS_LocalOptions options, uint16_t recursion_depth_limit, GNS_ResultProcessor proc, void *proc_cls)
 Lookup of a record in a specific zone calls lookup result processor on result. More...
 
void GNS_resolver_lookup_cancel (struct GNS_ResolverHandle *rh)
 Cancel active resolution (i.e. More...
 
void GNS_resolver_init (struct GNUNET_NAMECACHE_Handle *nc, struct GNUNET_DHT_Handle *dht, const struct GNUNET_CONFIGURATION_Handle *c, unsigned long long max_bg_queries)
 Initialize the resolver. More...
 
void GNS_resolver_done ()
 Shutdown resolver. More...
 

Variables

static struct GNUNET_NAMECACHE_Handlenamecache_handle
 Our handle to the namecache service. More...
 
static struct GNUNET_DHT_Handledht_handle
 Resolver handle to the dht. More...
 
static struct GNUNET_CONTAINER_Heapdht_lookup_heap
 Heap for limiting parallel DHT lookups. More...
 
static unsigned long long max_allowed_background_queries
 Maximum amount of parallel queries to the DHT. More...
 
static struct GNS_ResolverHandlerlh_head
 Head of resolver lookup list. More...
 
static struct GNS_ResolverHandlerlh_tail
 Tail of resolver lookup list. More...
 
static struct CacheOpsco_head
 Organized in a DLL. More...
 
static struct CacheOpsco_tail
 Organized in a DLL. More...
 
static int disable_cache
 Use namecache. More...
 
static const struct GNUNET_CONFIGURATION_Handlecfg
 Global configuration. More...
 

Detailed Description

GNU Name System resolver logic.

Author
Martin Schanzenbach
Christian Grothoff

Definition in file gnunet-service-gns_resolver.c.

Macro Definition Documentation

◆ DHT_LOOKUP_TIMEOUT

#define DHT_LOOKUP_TIMEOUT
Value:
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:484

Default DHT timeout for lookups.

Definition at line 57 of file gnunet-service-gns_resolver.c.

◆ DNS_LOOKUP_TIMEOUT

#define DNS_LOOKUP_TIMEOUT
Value:

Default timeout for DNS lookups.

Definition at line 63 of file gnunet-service-gns_resolver.c.

◆ DHT_GNS_REPLICATION_LEVEL

#define DHT_GNS_REPLICATION_LEVEL   10

DHT replication level.

Definition at line 69 of file gnunet-service-gns_resolver.c.

Function Documentation

◆ is_canonical()

int is_canonical ( const char *  name)

Determine if this name is canonical (is a legal name in a zone, without delegation); note that we do not test that the name does not contain illegal characters, we only test for delegation.

Note that service records (like _foo._srv) are canonical names even though they consist of multiple labels.

Examples: a.b.gnu = not canonical a = canonical _foo._srv = canonical _f.bar = not canonical

Parameters
namethe name to test
Returns
GNUNET_YES if canonical

Definition at line 482 of file gnunet-service-gns_resolver.c.

483 {
484  const char *pos;
485  const char *dot;
486 
487  if (NULL == strchr (name,
488  (unsigned char) '.'))
489  return GNUNET_YES;
490  if ('_' != name[0])
491  return GNUNET_NO;
492  pos = &name[1];
493  while (NULL != (dot = strchr (pos,
494  (unsigned char) '.')))
495  if ('_' != dot[1])
496  return GNUNET_NO;
497  else
498  pos = dot + 1;
499  return GNUNET_YES;
500 }
@ GNUNET_YES
@ GNUNET_NO
const char * name

References GNUNET_NO, GNUNET_YES, and name.

◆ translate_dot_plus()

static char* translate_dot_plus ( struct GNS_ResolverHandle rh,
char *  name 
)
static

Expands a name ending in .

  • with the zone of origin.
Parameters
rhresolution context
namename to modify (to be free'd or returned)
Returns
updated name

Definition at line 513 of file gnunet-service-gns_resolver.c.

515 {
516  char *ret;
517  size_t s_len = strlen (name);
518 
519  if (0 != strcmp (&name[s_len - 2],
520  ".+"))
521  return name; /* did not end in ".+" */
524  "%.*s.%s",
525  (int) (s_len - 2),
526  name,
529  GNUNET_free (name);
530  return ret;
531 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
const char * GNUNET_GNSRECORD_pkey_to_zkey(const struct GNUNET_IDENTITY_PublicKey *pkey)
Convert public key to the respective absolute domain name in the ".zkey" pTLD.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_free(ptr)
Wrapper around free.
int gns_authority
GNUNET_YES if the authority was a GNS authority, GNUNET_NO if the authority was a DNS authority.
union AuthorityChain::@19 authority_info
Information about the resolver authority for this label.
struct AuthorityChain * ac_tail
DLL to store the authority chain.

References GNS_ResolverHandle::ac_tail, AuthorityChain::authority_info, AuthorityChain::gns_authority, GNUNET_asprintf(), GNUNET_assert, GNUNET_free, GNUNET_GNSRECORD_pkey_to_zkey(), GNUNET_YES, name, and ret.

Referenced by handle_gns_resolution_result(), and recursive_gns2dns_resolution().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNS_resolver_lookup_cancel_()

static void GNS_resolver_lookup_cancel_ ( void *  cls)
static

Wrapper around GNS_resolver_lookup_cancel() as a task.

Used for delayed cleanup so we can unwind the stack first.

Parameters
clsthe struct GNS_ResolverHandle

Definition at line 541 of file gnunet-service-gns_resolver.c.

542 {
543  struct GNS_ResolverHandle *rh = cls;
544 
545  rh->task_id = NULL;
547 }
void GNS_resolver_lookup_cancel(struct GNS_ResolverHandle *rh)
Cancel active resolution (i.e.
Handle to a currently pending resolution.
struct GNUNET_SCHEDULER_Task * task_id
ID of a task associated with the resolution process.

References GNS_resolver_lookup_cancel(), and GNS_ResolverHandle::task_id.

Referenced by dns_result_parser(), fail_resolution(), GNS_resolver_lookup_cancel(), handle_gns_resolution_result(), recursive_dns_resolution(), and start_resolver_lookup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ fail_resolution()

static void fail_resolution ( struct GNS_ResolverHandle rh)
static

Function called to asynchronously fail a resolution.

Parameters
rhthe resolution to fail

Definition at line 556 of file gnunet-service-gns_resolver.c.

557 {
558  rh->proc (rh->proc_cls,
559  0,
560  NULL);
561  GNUNET_assert (NULL == rh->task_id);
563  rh);
564 }
static void GNS_resolver_lookup_cancel_(void *cls)
Wrapper around GNS_resolver_lookup_cancel() as a task.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1299
void * proc_cls
closure passed to proc
GNS_ResultProcessor proc
called when resolution phase finishes

References GNS_resolver_lookup_cancel_(), GNUNET_assert, GNUNET_SCHEDULER_add_now(), GNS_ResolverHandle::proc, GNS_ResolverHandle::proc_cls, and GNS_ResolverHandle::task_id.

Referenced by continue_with_gns2dns(), dns_result_parser(), handle_dht_response(), handle_gns_resolution_result(), handle_namecache_block_response(), handle_revocation_result(), recursive_cname_resolution(), recursive_pkey_resolution(), recursive_resolution(), start_dht_request(), and timeout_resolution().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ timeout_resolution()

static void timeout_resolution ( void *  cls)
static

Function called when a resolution times out.

Parameters
clsthe struct GNS_ResolverHandle

Definition at line 573 of file gnunet-service-gns_resolver.c.

574 {
575  struct GNS_ResolverHandle *rh = cls;
576 
577  rh->task_id = NULL;
578  fail_resolution (rh);
579 }
static void fail_resolution(struct GNS_ResolverHandle *rh)
Function called to asynchronously fail a resolution.

References fail_resolution(), and GNS_ResolverHandle::task_id.

Referenced by recursive_dns_resolution().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ resolver_lookup_get_next_label()

static char* resolver_lookup_get_next_label ( struct GNS_ResolverHandle rh)
static

Get the next, rightmost label from the name that we are trying to resolve, and update the resolution position accordingly.

Labels usually consist of up to 63 characters without a period ("."); however, we use a special convention to support SRV and TLSA records where the domain name includes an encoding for a service and protocol in the name. The syntax (see RFC 2782) here is "_Service._Proto.Name" and in this special case we include the "_Service._Proto" in the rightmost label. Thus, for "_443._tcp.foo.bar" we first return the label "bar" and then the label "_443._tcp.foo". The special case is detected by the presence of labels beginning with an underscore. Whenever a label begins with an underscore, it is combined with the label to its right (and the "." is preserved).

Parameters
rhhandle to the resolution operation to get the next label from
Returns
NULL if there are no more labels

Do not advance a label. This seems to be a name only consisting of a BOX indicator (_443,_tcp). Which means, it is a BOX under the empty label. leaving name_resolution_pos as is and returning empty label.

Definition at line 600 of file gnunet-service-gns_resolver.c.

601 {
602  const char *rp;
603  const char *dot;
604  size_t len;
605  char *ret;
606  char *srv_name;
607  char *proto_name;
608  struct protoent *pe;
609  struct servent *se;
610 
611  if (0 == rh->name_resolution_pos)
612  return NULL;
613  dot = memrchr (rh->name,
614  (int) '.',
615  rh->name_resolution_pos);
616  if (NULL == dot)
617  {
618  /* done, this was the last one */
619  len = rh->name_resolution_pos;
620  rp = rh->name;
621  rh->name_resolution_pos = 0;
622  }
623  else if (('_' == dot[1]) &&
624  ('_' == rh->name[0]) &&
625  (dot == memchr (rh->name, (int) '.', rh->name_resolution_pos)))
626  {
634  len = strlen (GNUNET_GNS_EMPTY_LABEL_AT);
635  }
636  else
637  {
638  /* advance by one label */
639  len = rh->name_resolution_pos - (dot - rh->name) - 1;
640  rp = dot + 1;
641  rh->name_resolution_pos = dot - rh->name;
642  }
643  rh->protocol = 0;
644  rh->service = 0;
645  ret = GNUNET_strndup (rp, len);
646  /* If we have labels starting with underscore with label on
647  * the right (SRV/DANE/BOX case), determine port/protocol;
648  * The format of `rh->name` must be "_PORT._PROTOCOL".
649  */
650  if (('_' == rh->name[0]) &&
651  (NULL != (dot = memrchr (rh->name,
652  (int) '.',
653  rh->name_resolution_pos))) &&
654  ('_' == dot[1]) &&
655  (NULL == memrchr (rh->name,
656  (int) '.',
657  dot - rh->name)))
658  {
659  srv_name = GNUNET_strndup (&rh->name[1],
660  (dot - rh->name) - 1);
661  proto_name = GNUNET_strndup (&dot[2],
662  rh->name_resolution_pos - (dot - rh->name)
663  - 2);
664  rh->name_resolution_pos = 0;
665  pe = getprotobyname (proto_name);
666  if (NULL == pe)
667  {
669  _ ("Protocol `%s' unknown, skipping labels.\n"),
670  proto_name);
671  GNUNET_free (proto_name);
672  GNUNET_free (srv_name);
673  return ret;
674  }
675  se = getservbyname (srv_name,
676  proto_name);
677  if (NULL == se)
678  {
680  _ (
681  "Service `%s' unknown for protocol `%s', trying as number.\n"),
682  srv_name,
683  proto_name);
684  if (1 != sscanf (srv_name, "%u", &rh->service))
685  {
687  _ ("Service `%s' not a port, skipping service labels.\n"),
688  srv_name);
689  GNUNET_free (proto_name);
690  GNUNET_free (srv_name);
691  return ret;
692  }
693  }
694  else
695  {
696  rh->service = ntohs (se->s_port);
697  }
698  rh->protocol = pe->p_proto;
699  GNUNET_free (proto_name);
700  GNUNET_free (srv_name);
701  }
702  return ret;
703 }
#define memrchr(s, c, n)
Definition: compat.h:49
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static char * rp
Relying party.
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
#define GNUNET_log(kind,...)
@ GNUNET_ERROR_TYPE_WARNING
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
size_t name_resolution_pos
Current offset in name where we are resolving.
int service
For SRV and TLSA records, the number of the service specified in the name.
char * name
The name to resolve.
int protocol
For SRV and TLSA records, the number of the protocol specified in the name.

References _, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_GNS_EMPTY_LABEL_AT, GNUNET_log, GNUNET_strndup, len, memrchr, GNS_ResolverHandle::name, GNS_ResolverHandle::name_resolution_pos, GNS_ResolverHandle::protocol, ret, rp, and GNS_ResolverHandle::service.

Referenced by handle_gns_redirect_result(), recursive_pkey_resolution(), and start_resolver_lookup().

Here is the caller graph for this function:

◆ transmit_lookup_dns_result()

static void transmit_lookup_dns_result ( struct GNS_ResolverHandle rh)
static

Gives the cumulative result obtained to the callback and clean up the request.

Parameters
rhresolution process that has culminated in a result

If this is a LEHO, we added this before. It must be a supplemental record #LSD0001

Definition at line 712 of file gnunet-service-gns_resolver.c.

713 {
714  struct DnsResult *pos;
715  unsigned int n;
716  unsigned int i;
717 
718  n = 0;
719  for (pos = rh->dns_result_head; NULL != pos; pos = pos->next)
720  n++;
721  {
722  struct GNUNET_GNSRECORD_Data rd[n];
723 
724  i = 0;
725  for (pos = rh->dns_result_head; NULL != pos; pos = pos->next)
726  {
727  rd[i].data = pos->data;
728  rd[i].data_size = pos->data_size;
729  rd[i].record_type = pos->record_type;
737  if (0 == pos->expiration_time)
738  {
740  rd[i].expiration_time = 0;
741  }
742  else
743  {
745  }
746  i++;
747  }
748  GNUNET_assert (i == n);
750  "Transmitting standard DNS result with %u records\n",
751  n);
752  rh->proc (rh->proc_cls,
753  n,
754  rd);
755  }
757 }
#define GNUNET_GNSRECORD_TYPE_LEHO
GNS legacy hostname.
static struct GNUNET_GNSRECORD_Data rd[50]
The record data under a single label.
@ GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION
This expiration time of the record is a relative time (not an absolute time).
@ GNUNET_GNSRECORD_RF_SUPPLEMENTAL
This is a supplemental record.
@ GNUNET_GNSRECORD_RF_NONE
Entry for no flags / cleared flags.
@ GNUNET_ERROR_TYPE_DEBUG
A result we got from DNS.
struct DnsResult * next
Kept in DLL.
size_t data_size
Number of bytes in data.
uint32_t record_type
Type of the GNS/DNS record.
uint64_t expiration_time
Expiration time for the DNS record, 0 if we didn't get anything useful (i.e.
const void * data
Binary value stored in the DNS record (appended to this struct)
struct DnsResult * dns_result_head
DLL of results we got from DNS.
uint32_t record_type
Type of the GNS/DNS record.
const void * data
Binary value stored in the DNS record.
size_t data_size
Number of bytes in data.
enum GNUNET_GNSRECORD_Flags flags
Flags for the record.
uint64_t expiration_time
Expiration time for the DNS record.

References DnsResult::data, GNUNET_GNSRECORD_Data::data, DnsResult::data_size, GNUNET_GNSRECORD_Data::data_size, GNS_ResolverHandle::dns_result_head, DnsResult::expiration_time, GNUNET_GNSRECORD_Data::expiration_time, GNUNET_GNSRECORD_Data::flags, GNS_resolver_lookup_cancel(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_GNSRECORD_RF_NONE, GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION, GNUNET_GNSRECORD_RF_SUPPLEMENTAL, GNUNET_GNSRECORD_TYPE_LEHO, GNUNET_log, DnsResult::next, GNS_ResolverHandle::proc, GNS_ResolverHandle::proc_cls, rd, DnsResult::record_type, and GNUNET_GNSRECORD_Data::record_type.

Referenced by handle_dns_result().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_dns_result()

static void add_dns_result ( struct GNS_ResolverHandle rh,
uint64_t  expiration_time,
uint32_t  record_type,
size_t  data_size,
const void *  data 
)
static

Add a result from DNS to the records to be returned to the application.

Parameters
rhresolution request to extend with a result
expiration_timeexpiration time for the answer
record_typeDNS record type of the answer
data_sizenumber of bytes in data
databinary data to return in DNS record

Definition at line 770 of file gnunet-service-gns_resolver.c.

775 {
776  struct DnsResult *res;
777 
778  res = GNUNET_malloc (sizeof(struct DnsResult) + data_size);
779  res->expiration_time = expiration_time;
780  res->data_size = data_size;
781  res->record_type = record_type;
782  res->data = &res[1];
783  GNUNET_memcpy (&res[1],
784  data,
785  data_size);
787  rh->dns_result_tail,
788  res);
789 }
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
static int res
uint32_t data
The data value.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_malloc(size)
Wrapper around malloc.
struct DnsResult * dns_result_tail
DLL of results we got from DNS.

References data, data_size, GNS_ResolverHandle::dns_result_head, GNS_ResolverHandle::dns_result_tail, DnsResult::expiration_time, GNUNET_CONTAINER_DLL_insert, GNUNET_malloc, GNUNET_memcpy, DnsResult::record_type, and res.

Referenced by dns_result_parser(), and handle_dns_result().

Here is the caller graph for this function:

◆ handle_dns_result()

static void handle_dns_result ( void *  cls,
const struct sockaddr *  addr,
socklen_t  addrlen 
)
static

We had to do a DNS lookup.

Convert the result (if any) and return it.

Parameters
clsclosure with the struct GNS_ResolverHandle
addrone of the addresses of the host, NULL for the last address
addrlenlength of the address

Definition at line 801 of file gnunet-service-gns_resolver.c.

804 {
805  struct GNS_ResolverHandle *rh = cls;
806  const struct sockaddr_in *sa4;
807  const struct sockaddr_in6 *sa6;
808 
809  if (NULL == addr)
810  {
811  rh->std_resolve = NULL;
813  return;
814  }
816  "Received %u bytes of DNS IP data\n",
817  addrlen);
818  switch (addr->sa_family)
819  {
820  case AF_INET:
821  sa4 = (const struct sockaddr_in *) addr;
822  add_dns_result (rh,
823  0 /* expiration time is unknown */,
825  sizeof(struct in_addr),
826  &sa4->sin_addr);
827  break;
828 
829  case AF_INET6:
830  sa6 = (const struct sockaddr_in6 *) addr;
831  add_dns_result (rh,
832  0 /* expiration time is unknown */,
834  sizeof(struct in6_addr),
835  &sa6->sin6_addr);
836  break;
837 
838  default:
839  GNUNET_break (0);
840  break;
841  }
842 }
static void transmit_lookup_dns_result(struct GNS_ResolverHandle *rh)
Gives the cumulative result obtained to the callback and clean up the request.
static void add_dns_result(struct GNS_ResolverHandle *rh, uint64_t expiration_time, uint32_t record_type, size_t data_size, const void *data)
Add a result from DNS to the records to be returned to the application.
#define GNUNET_DNSPARSER_TYPE_A
#define GNUNET_DNSPARSER_TYPE_AAAA
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
struct GNUNET_RESOLVER_RequestHandle * std_resolve
Handle for standard DNS resolution, NULL if none is active.

References add_dns_result(), GNUNET_break, GNUNET_DNSPARSER_TYPE_A, GNUNET_DNSPARSER_TYPE_AAAA, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNS_ResolverHandle::std_resolve, and transmit_lookup_dns_result().

Referenced by dns_result_parser(), handle_gns_cname_result(), and handle_gns_redirect_result().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ recursive_resolution()

static void recursive_resolution ( void *  cls)
static

Task scheduled to continue with the resolution process.

Parameters
clsthe 'struct GNS_ResolverHandle' of the resolution

Definition at line 2691 of file gnunet-service-gns_resolver.c.

2692 {
2693  struct GNS_ResolverHandle *rh = cls;
2694 
2695  rh->task_id = NULL;
2696  if (rh->loop_threshold < rh->loop_limiter++)
2697  {
2699  "Encountered unbounded recursion resolving `%s'\n",
2700  rh->name);
2701  fail_resolution (rh);
2702  return;
2703  }
2704  if (GNUNET_YES == rh->ac_tail->gns_authority)
2706  else
2708 }
static void recursive_gns_resolution_revocation(struct GNS_ResolverHandle *rh)
Perform revocation check on tail of our authority chain.
static void recursive_dns_resolution(struct GNS_ResolverHandle *rh)
Perform recursive DNS resolution.
unsigned int loop_limiter
We increment the loop limiter for each step in a recursive resolution.
unsigned int loop_threshold
Maximum value of loop_limiter allowed by client.

References GNS_ResolverHandle::ac_tail, fail_resolution(), AuthorityChain::gns_authority, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_YES, GNS_ResolverHandle::loop_limiter, GNS_ResolverHandle::loop_threshold, GNS_ResolverHandle::name, recursive_dns_resolution(), recursive_gns_resolution_revocation(), and GNS_ResolverHandle::task_id.

Referenced by continue_with_gns2dns(), handle_gns_redirect_result(), handle_gns_resolution_result(), recursive_pkey_resolution(), and start_resolver_lookup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ start_resolver_lookup()

static void start_resolver_lookup ( void *  cls)
static

Begin the resolution process from 'name', starting with the identification of the zone specified by 'name'.

Parameters
clsclosure with struct GNS_ResolverHandle *rh

Definition at line 2712 of file gnunet-service-gns_resolver.c.

2713 {
2714  struct GNS_ResolverHandle *rh = cls;
2715  struct AuthorityChain *ac;
2716  struct in_addr v4;
2717  struct in6_addr v6;
2718 
2719  rh->task_id = NULL;
2720  if (1 == inet_pton (AF_INET,
2721  rh->name,
2722  &v4))
2723  {
2724  /* name is IPv4 address, pretend it's an A record */
2725  struct GNUNET_GNSRECORD_Data rd;
2726 
2727  rd.data = &v4;
2728  rd.data_size = sizeof(v4);
2729  rd.expiration_time = UINT64_MAX;
2731  rd.flags = 0;
2732  rh->proc (rh->proc_cls,
2733  1,
2734  &rd);
2735  GNUNET_assert (NULL == rh->task_id);
2737  rh);
2738  return;
2739  }
2740  if (1 == inet_pton (AF_INET6,
2741  rh->name,
2742  &v6))
2743  {
2744  /* name is IPv6 address, pretend it's an AAAA record */
2745  struct GNUNET_GNSRECORD_Data rd;
2746 
2747  rd.data = &v6;
2748  rd.data_size = sizeof(v6);
2749  rd.expiration_time = UINT64_MAX;
2751  rd.flags = 0;
2752  rh->proc (rh->proc_cls,
2753  1,
2754  &rd);
2755  GNUNET_assert (NULL == rh->task_id);
2757  rh);
2758  return;
2759  }
2760 
2761  ac = GNUNET_new (struct AuthorityChain);
2762  ac->rh = rh;
2763  ac->label = resolver_lookup_get_next_label (rh);
2764  if (NULL == ac->label)
2765  /* name was just the "TLD", so we default to label
2766  #GNUNET_GNS_EMPTY_LABEL_AT */
2768  ac->gns_authority = GNUNET_YES;
2769  ac->authority_info.gns_authority = rh->authority_zone;
2771  rh->ac_tail,
2772  ac);
2774  rh);
2775 }
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
static void recursive_resolution(void *cls)
Task scheduled to continue with the resolution process.
static char * resolver_lookup_get_next_label(struct GNS_ResolverHandle *rh)
Get the next, rightmost label from the name that we are trying to resolve, and update the resolution ...
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
DLL to hold the authority chain we had to pass in the resolution process.
struct AuthorityChain * ac_head
DLL to store the authority chain.
struct GNUNET_IDENTITY_PublicKey authority_zone
The top-level GNS authoritative zone to query.

References ac, GNS_ResolverHandle::ac_head, GNS_ResolverHandle::ac_tail, GNS_ResolverHandle::authority_zone, GNUNET_GNSRECORD_Data::data, GNUNET_GNSRECORD_Data::data_size, GNUNET_GNSRECORD_Data::expiration_time, GNUNET_GNSRECORD_Data::flags, GNS_resolver_lookup_cancel_(), GNUNET_assert, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_DNSPARSER_TYPE_A, GNUNET_DNSPARSER_TYPE_AAAA, GNUNET_GNS_EMPTY_LABEL_AT, GNUNET_new, GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_YES, GNS_ResolverHandle::name, GNS_ResolverHandle::proc, GNS_ResolverHandle::proc_cls, rd, GNUNET_GNSRECORD_Data::record_type, recursive_resolution(), resolver_lookup_get_next_label(), and GNS_ResolverHandle::task_id.

Referenced by GNS_resolver_lookup(), and recursive_gns2dns_resolution().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dns_result_parser()

static void dns_result_parser ( void *  cls,
const struct GNUNET_TUN_DnsHeader dns,
size_t  dns_len 
)
static

Function called with the result of a DNS resolution.

Parameters
clsthe request handle of the resolution that we were attempting to make
dnsdns response, never NULL
dns_lennumber of bytes in dns

Definition at line 873 of file gnunet-service-gns_resolver.c.

876 {
877  struct GNS_ResolverHandle *rh = cls;
878  struct GNUNET_DNSPARSER_Packet *p;
879  const struct GNUNET_DNSPARSER_Record *rec;
880  unsigned int rd_count;
881 
882  if (NULL == dns)
883  {
884  rh->dns_request = NULL;
886  rh->task_id = NULL;
887  fail_resolution (rh);
888  return;
889  }
890  if (rh->original_dns_id != dns->id)
891  {
892  /* DNS answer, but for another query */
893  return;
894  }
895  p = GNUNET_DNSPARSER_parse ((const char *) dns,
896  dns_len);
897  if (NULL == p)
898  {
900  _ ("Failed to parse DNS response\n"));
901  return;
902  }
903 
904  /* We got a result from DNS */
906  "Received DNS response for `%s' with %u answers\n",
907  rh->ac_tail->label,
908  (unsigned int) p->num_answers);
909  if ((p->num_answers > 0) &&
910  (GNUNET_DNSPARSER_TYPE_CNAME == p->answers[0].type) &&
912  {
913  int af;
914 
916  "Got CNAME `%s' from DNS for `%s'\n",
917  p->answers[0].data.hostname,
918  rh->name);
919  if (NULL != rh->std_resolve)
920  {
922  "Multiple CNAME results from DNS resolving `%s'! Not really allowed...\n",
923  rh->name);
925  }
926  GNUNET_free (rh->name);
927  rh->name = GNUNET_strdup (p->answers[0].data.hostname);
928  rh->name_resolution_pos = strlen (rh->name);
929  switch (rh->record_type)
930  {
932  af = AF_INET;
933  break;
934 
936  af = AF_INET6;
937  break;
938 
939  default:
940  af = AF_UNSPEC;
941  break;
942  }
943  if (NULL != rh->leho)
944  add_dns_result (rh,
945  GNUNET_TIME_UNIT_HOURS.rel_value_us,
947  strlen (rh->leho),
948  rh->leho);
950  af,
953  rh);
956  rh->dns_request = NULL;
957  return;
958  }
959 
960  /* convert from (parsed) DNS to (binary) GNS format! */
961  rd_count = p->num_answers + p->num_authority_records
962  + p->num_additional_records;
963  {
964  struct GNUNET_GNSRECORD_Data rd[rd_count + 1]; /* +1 for LEHO */
965  int skip;
966  char buf[UINT16_MAX];
967  size_t buf_off;
968  size_t buf_start;
969 
970  buf_off = 0;
971  skip = 0;
972  memset (rd,
973  0,
974  sizeof(rd));
975  for (unsigned int i = 0; i < rd_count; i++)
976  {
977  if (i < p->num_answers)
978  rec = &p->answers[i];
979  else if (i < p->num_answers + p->num_authority_records)
980  rec = &p->authority_records[i - p->num_answers];
981  else
982  rec = &p->additional_records[i - p->num_answers
983  - p->num_authority_records];
984  /* As we copied the full DNS name to 'rh->ac_tail->label', this
985  should be the correct check to see if this record is actually
986  a record for our label... */
987  if (0 != strcmp (rec->name,
988  rh->ac_tail->label))
989  {
991  "Dropping record `%s', does not match desired name `%s'\n",
992  rec->name,
993  rh->ac_tail->label);
994  skip++;
995  continue;
996  }
997  rd[i - skip].record_type = rec->type;
999  switch (rec->type)
1000  {
1002  if (rec->data.raw.data_len != sizeof(struct in_addr))
1003  {
1004  GNUNET_break_op (0);
1005  skip++;
1006  continue;
1007  }
1008  rd[i - skip].data_size = rec->data.raw.data_len;
1009  rd[i - skip].data = rec->data.raw.data;
1010  break;
1011 
1013  if (rec->data.raw.data_len != sizeof(struct in6_addr))
1014  {
1015  GNUNET_break_op (0);
1016  skip++;
1017  continue;
1018  }
1019  rd[i - skip].data_size = rec->data.raw.data_len;
1020  rd[i - skip].data = rec->data.raw.data;
1021  break;
1022 
1026  buf_start = buf_off;
1027  if (GNUNET_OK !=
1029  sizeof(buf),
1030  &buf_off,
1031  rec->data.hostname))
1032  {
1033  GNUNET_break (0);
1034  skip++;
1035  continue;
1036  }
1037  rd[i - skip].data_size = buf_off - buf_start;
1038  rd[i - skip].data = &buf[buf_start];
1039  break;
1040 
1042  buf_start = buf_off;
1043  if (GNUNET_OK !=
1045  sizeof(buf),
1046  &buf_off,
1047  rec->data.soa))
1048  {
1049  GNUNET_break (0);
1050  skip++;
1051  continue;
1052  }
1053  rd[i - skip].data_size = buf_off - buf_start;
1054  rd[i - skip].data = &buf[buf_start];
1055  break;
1056 
1058  buf_start = buf_off;
1059  if (GNUNET_OK !=
1061  sizeof(buf),
1062  &buf_off,
1063  rec->data.mx))
1064  {
1065  GNUNET_break (0);
1066  skip++;
1067  continue;
1068  }
1069  rd[i - skip].data_size = buf_off - buf_start;
1070  rd[i - skip].data = &buf[buf_start];
1071  break;
1072 
1074  buf_start = buf_off;
1075  if (GNUNET_OK !=
1077  sizeof(buf),
1078  &buf_off,
1079  rec->data.srv))
1080  {
1081  GNUNET_break (0);
1082  skip++;
1083  continue;
1084  }
1085  rd[i - skip].data_size = buf_off - buf_start;
1086  rd[i - skip].data = &buf[buf_start];
1087  break;
1088 
1089  default:
1091  _ ("Skipping record of unsupported type %d\n"),
1092  rec->type);
1093  skip++;
1094  continue;
1095  }
1096  } /* end of for all records in answer */
1097  if (NULL != rh->leho)
1098  {
1102  rd[rd_count - skip].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us;
1103  rd[rd_count - skip].data = rh->leho;
1104  rd[rd_count - skip].data_size = strlen (rh->leho);
1105  skip--; /* skip one LESS */
1107  "Adding LEHO %s\n",
1108  rh->leho);
1109  }
1111  "Returning DNS response for `%s' with %u answers\n",
1112  rh->ac_tail->label,
1113  (unsigned int) (rd_count - skip));
1114  rh->proc (rh->proc_cls,
1115  rd_count - skip,
1116  rd);
1118  rh->dns_request = NULL;
1119  }
1121  if (NULL != rh->task_id)
1122  GNUNET_SCHEDULER_cancel (rh->task_id); /* should be timeout task */
1124  rh);
1125 }
static unsigned int rd_count
Number of records for currently parsed set.
#define DNS_LOOKUP_TIMEOUT
Default timeout for DNS lookups.
static void handle_dns_result(void *cls, const struct sockaddr *addr, socklen_t addrlen)
We had to do a DNS lookup.
static char buf[2048]
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38
int GNUNET_DNSPARSER_builder_add_name(char *dst, size_t dst_len, size_t *off, const char *name)
Add a DNS name to the UDP packet at the given location, converting the name to IDNA notation as neces...
Definition: dnsparser.c:889
void GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p)
Free memory taken by a packet.
Definition: dnsparser.c:854
#define GNUNET_DNSPARSER_TYPE_SRV
#define GNUNET_DNSPARSER_TYPE_SOA
#define GNUNET_DNSPARSER_TYPE_PTR
struct GNUNET_DNSPARSER_Packet * GNUNET_DNSPARSER_parse(const char *udp_payload, size_t udp_payload_length)
Parse a UDP payload of a DNS packet in to a nice struct for further processing and manipulation.
Definition: dnsparser.c:656
#define GNUNET_DNSPARSER_TYPE_NS
int GNUNET_DNSPARSER_builder_add_soa(char *dst, size_t dst_len, size_t *off, const struct GNUNET_DNSPARSER_SoaRecord *soa)
Add an SOA record to the UDP packet at the given location.
Definition: dnsparser.c:1079
#define GNUNET_DNSPARSER_TYPE_CNAME
int GNUNET_DNSPARSER_builder_add_mx(char *dst, size_t dst_len, size_t *off, const struct GNUNET_DNSPARSER_MxRecord *mx)
Add an MX record to the UDP packet at the given location.
Definition: dnsparser.c:1003
int GNUNET_DNSPARSER_builder_add_srv(char *dst, size_t dst_len, size_t *off, const struct GNUNET_DNSPARSER_SrvRecord *srv)
Add an SRV record to the UDP packet at the given location.
Definition: dnsparser.c:1120
#define GNUNET_DNSPARSER_TYPE_MX
void GNUNET_DNSSTUB_resolve_cancel(struct GNUNET_DNSSTUB_RequestSocket *rs)
Cancel DNS resolution.
Definition: dnsstub.c:562
@ GNUNET_OK
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
@ GNUNET_ERROR_TYPE_INFO
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
struct GNUNET_RESOLVER_RequestHandle * GNUNET_RESOLVER_ip_get(const char *hostname, int af, struct GNUNET_TIME_Relative timeout, GNUNET_RESOLVER_AddressCallback callback, void *callback_cls)
Convert a string to one or more IP addresses.
Definition: resolver_api.c:940
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
#define GNUNET_TIME_UNIT_HOURS
One hour.
char * label
label/name corresponding to the authority
char * leho
Legacy Hostname to use if we encountered GNS2DNS record and thus can deduct the LEHO from that transi...
int record_type
Desired type for the resolution.
uint16_t original_dns_id
16 bit random ID we used in the dns_request.
struct GNUNET_DNSSTUB_RequestSocket * dns_request
Socket for a DNS request, NULL if none is active.
Easy-to-process, parsed version of a DNS packet.
void * data
Binary record data.
size_t data_len
Number of bytes in data.
A DNS response record.
struct GNUNET_DNSPARSER_SoaRecord * soa
SOA data for SOA records.
struct GNUNET_DNSPARSER_SrvRecord * srv
SRV data for SRV records.
struct GNUNET_DNSPARSER_MxRecord * mx
MX data for MX records.
char * hostname
For NS, CNAME and PTR records, this is the uncompressed 0-terminated hostname.
uint16_t type
See GNUNET_DNSPARSER_TYPE_*.
struct GNUNET_TIME_Absolute expiration_time
When does the record expire?
union GNUNET_DNSPARSER_Record::@24 data
Payload of the record (which one of these is valid depends on the 'type').
char * name
Name of the record that the query is for (0-terminated).
struct GNUNET_DNSPARSER_RawRecord raw
Raw data for all other types.
uint64_t abs_value_us
The actual value.
uint16_t id
Unique identifier for the request/response.

References _, GNUNET_TIME_Absolute::abs_value_us, GNS_ResolverHandle::ac_tail, add_dns_result(), buf, GNUNET_DNSPARSER_RawRecord::data, GNUNET_DNSPARSER_Record::data, GNUNET_GNSRECORD_Data::data, GNUNET_DNSPARSER_RawRecord::data_len, GNUNET_GNSRECORD_Data::data_size, DNS_LOOKUP_TIMEOUT, GNS_ResolverHandle::dns_request, GNUNET_DNSPARSER_Record::expiration_time, GNUNET_GNSRECORD_Data::expiration_time, fail_resolution(), GNUNET_GNSRECORD_Data::flags, GNS_resolver_lookup_cancel_(), GNUNET_break, GNUNET_break_op, GNUNET_DNSPARSER_builder_add_mx(), GNUNET_DNSPARSER_builder_add_name(), GNUNET_DNSPARSER_builder_add_soa(), GNUNET_DNSPARSER_builder_add_srv(), GNUNET_DNSPARSER_free_packet(), GNUNET_DNSPARSER_parse(), GNUNET_DNSPARSER_TYPE_A, GNUNET_DNSPARSER_TYPE_AAAA, GNUNET_DNSPARSER_TYPE_CNAME, GNUNET_DNSPARSER_TYPE_MX, GNUNET_DNSPARSER_TYPE_NS, GNUNET_DNSPARSER_TYPE_PTR, GNUNET_DNSPARSER_TYPE_SOA, GNUNET_DNSPARSER_TYPE_SRV, GNUNET_DNSSTUB_resolve_cancel(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION, GNUNET_GNSRECORD_RF_SUPPLEMENTAL, GNUNET_GNSRECORD_TYPE_LEHO, GNUNET_log, GNUNET_OK, GNUNET_RESOLVER_ip_get(), GNUNET_RESOLVER_request_cancel(), GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_strdup, GNUNET_TIME_UNIT_HOURS, handle_dns_result(), GNUNET_DNSPARSER_Record::hostname, GNUNET_TUN_DnsHeader::id, AuthorityChain::label, GNS_ResolverHandle::leho, GNUNET_DNSPARSER_Record::mx, GNS_ResolverHandle::name, GNUNET_DNSPARSER_Record::name, GNS_ResolverHandle::name_resolution_pos, GNS_ResolverHandle::original_dns_id, p, GNS_ResolverHandle::proc, GNS_ResolverHandle::proc_cls, GNUNET_DNSPARSER_Record::raw, rd, rd_count, GNS_ResolverHandle::record_type, GNUNET_GNSRECORD_Data::record_type, GNUNET_DNSPARSER_Record::soa, GNUNET_DNSPARSER_Record::srv, GNS_ResolverHandle::std_resolve, GNS_ResolverHandle::task_id, and GNUNET_DNSPARSER_Record::type.

Referenced by recursive_dns_resolution().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ recursive_dns_resolution()

static void recursive_dns_resolution ( struct GNS_ResolverHandle rh)
static

Perform recursive DNS resolution.

Asks the given DNS resolver to resolve "rh->dns_name", possibly recursively proceeding following NS delegations, CNAMES, etc., until 'rh->loop_limiter' bounds us or we find the answer.

Parameters
rhresolution information

Definition at line 1137 of file gnunet-service-gns_resolver.c.

1138 {
1139  struct AuthorityChain *ac;
1140  struct GNUNET_DNSPARSER_Query *query;
1141  struct GNUNET_DNSPARSER_Packet *p;
1142  char *dns_request;
1143  size_t dns_request_length;
1144  int ret;
1145 
1146  ac = rh->ac_tail;
1147  GNUNET_assert (NULL != ac);
1149  "Starting DNS lookup for `%s'\n",
1150  ac->label);
1151  GNUNET_assert (GNUNET_NO == ac->gns_authority);
1152  query = GNUNET_new (struct GNUNET_DNSPARSER_Query);
1153  query->name = GNUNET_strdup (ac->label);
1154  query->type = rh->record_type;
1157  p->queries = query;
1158  p->num_queries = 1;
1160  UINT16_MAX);
1161  p->flags.opcode = GNUNET_TUN_DNS_OPCODE_QUERY;
1162  p->flags.recursion_desired = 1;
1164  1024,
1165  &dns_request,
1166  &dns_request_length);
1167  if (GNUNET_OK != ret)
1168  {
1169  GNUNET_break (0);
1170  rh->proc (rh->proc_cls,
1171  0,
1172  NULL);
1173  GNUNET_assert (NULL == rh->task_id);
1175  rh);
1176  }
1177  else
1178  {
1179  rh->original_dns_id = p->id;
1180  GNUNET_assert (NULL != ac->authority_info.dns_authority.dns_handle);
1181  GNUNET_assert (NULL == rh->dns_request);
1182  rh->leho = GNUNET_strdup (ac->label);
1184  ac->authority_info.dns_authority.dns_handle,
1185  dns_request,
1186  dns_request_length,
1188  rh);
1191  rh);
1192  }
1193  if (GNUNET_SYSERR != ret)
1194  GNUNET_free (dns_request);
1196 }
static void dns_result_parser(void *cls, const struct GNUNET_TUN_DnsHeader *dns, size_t dns_len)
Function called with the result of a DNS resolution.
static void timeout_resolution(void *cls)
Function called when a resolution times out.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_NONCE
Randomness for IVs etc.
int GNUNET_DNSPARSER_pack(const struct GNUNET_DNSPARSER_Packet *p, uint16_t max, char **buf, size_t *buf_length)
Given a DNS packet p, generate the corresponding UDP payload.
Definition: dnsparser.c:1259
struct GNUNET_DNSSTUB_RequestSocket * GNUNET_DNSSTUB_resolve(struct GNUNET_DNSSTUB_Context *ctx, const void *request, size_t request_len, GNUNET_DNSSTUB_ResultCallback rc, void *rc_cls)
Perform DNS resolution using our default IP from init.
Definition: dnsstub.c:526
@ GNUNET_SYSERR
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1272
#define GNUNET_TUN_DNS_CLASS_INTERNET
A few common DNS classes (ok, only one is common, but I list a couple more to make it clear what we'r...
#define GNUNET_TUN_DNS_OPCODE_QUERY
uint16_t dns_traffic_class
See GNUNET_TUN_DNS_CLASS_*.
uint16_t type
See GNUNET_DNSPARSER_TYPE_*.
char * name
Name of the record that the query is for (0-terminated).

References ac, GNS_ResolverHandle::ac_tail, DNS_LOOKUP_TIMEOUT, GNS_ResolverHandle::dns_request, dns_result_parser(), GNUNET_DNSPARSER_Query::dns_traffic_class, GNS_resolver_lookup_cancel_(), GNUNET_assert, GNUNET_break, GNUNET_CRYPTO_QUALITY_NONCE, GNUNET_CRYPTO_random_u32(), GNUNET_DNSPARSER_free_packet(), GNUNET_DNSPARSER_pack(), GNUNET_DNSSTUB_resolve(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_SYSERR, GNUNET_TUN_DNS_CLASS_INTERNET, GNUNET_TUN_DNS_OPCODE_QUERY, GNS_ResolverHandle::leho, GNUNET_DNSPARSER_Query::name, GNS_ResolverHandle::original_dns_id, p, GNS_ResolverHandle::proc, GNS_ResolverHandle::proc_cls, GNS_ResolverHandle::record_type, ret, GNS_ResolverHandle::task_id, timeout_resolution(), and GNUNET_DNSPARSER_Query::type.

Referenced by recursive_resolution().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_gns_redirect_result()

static void handle_gns_redirect_result ( struct GNS_ResolverHandle rh,
const char *  rname 
)
static

We encountered a REDIRECT record during our resolution.

Merge it into our chain.

Parameters
rhresolution we are performing
rnamevalue of the redirect record we got for the current authority chain tail

Definition at line 1208 of file gnunet-service-gns_resolver.c.

1210 {
1211  size_t nlen;
1212  char *res;
1213  const char *tld;
1214  struct AuthorityChain *ac;
1215  int af;
1217 
1219  "Handling GNS REDIRECT result `%s'\n",
1220  rname);
1221  nlen = strlen (rname);
1222  tld = GNS_get_tld (rname);
1223  if (0 == strcmp ("+", tld))
1224  {
1225  /* REDIRECT resolution continues relative to current domain */
1226  if (0 == rh->name_resolution_pos)
1227  {
1228  res = GNUNET_strndup (rname, nlen - 2);
1229  rh->name_resolution_pos = nlen - 2;
1230  }
1231  else
1232  {
1233  GNUNET_asprintf (&res,
1234  "%.*s.%.*s",
1235  (int) rh->name_resolution_pos,
1236  rh->name,
1237  (int) (nlen - 2),
1238  rname);
1239  rh->name_resolution_pos = strlen (res);
1240  }
1241  GNUNET_free (rh->name);
1242  rh->name = res;
1243  ac = GNUNET_new (struct AuthorityChain);
1244  ac->rh = rh;
1245  ac->gns_authority = GNUNET_YES;
1246  ac->authority_info.gns_authority =
1248  ac->label = resolver_lookup_get_next_label (rh);
1249  /* add AC to tail */
1251  rh->ac_tail,
1252  ac);
1254  rh);
1255  return;
1256  }
1258  {
1259  /* REDIRECT resolution continues relative to current domain */
1260  if (0 == rh->name_resolution_pos)
1261  {
1262  GNUNET_asprintf (&res,
1263  "%.*s",
1264  (int) (strlen (rname) - (strlen (tld) + 1)),
1265  rname);
1266  }
1267  else
1268  {
1269  GNUNET_asprintf (&res,
1270  "%.*s.%.*s",
1271  (int) rh->name_resolution_pos,
1272  rh->name,
1273  (int) (strlen (rname) - (strlen (tld) + 1)),
1274  rname);
1275  }
1276  rh->name_resolution_pos = strlen (res);
1277  GNUNET_free (rh->name);
1278  rh->name = res;
1279  ac = GNUNET_new (struct AuthorityChain);
1280  ac->rh = rh;
1281  ac->gns_authority = GNUNET_YES;
1282  ac->authority_info.gns_authority = zone;
1283  ac->label = resolver_lookup_get_next_label (rh);
1284  /* add AC to tail */
1286  rh->ac_tail,
1287  ac);
1289  rh);
1290  return;
1291  }
1292 
1294  "Got REDIRECT `%s' from GNS for `%s'\n",
1295  rname,
1296  rh->name);
1297  if (NULL != rh->std_resolve)
1298  {
1300  "Multiple REDIRECT results from GNS resolving `%s'! Not really allowed...\n",
1301  rh->name);
1303  }
1304  /* name is absolute, go to DNS */
1305  GNUNET_free (rh->name);
1306  rh->name = GNUNET_strdup (rname);
1307  rh->name_resolution_pos = strlen (rh->name);
1308  switch (rh->record_type)
1309  {
1311  af = AF_INET;
1312  break;
1313 
1315  af = AF_INET6;
1316  break;
1317 
1318  default:
1319  af = AF_UNSPEC;
1320  break;
1321  }
1323  "Doing standard DNS lookup for `%s'\n",
1324  rh->name);
1325 
1327  af,
1330  rh);
1331 }
static char * zone
Name of the zone being managed.
const char * GNS_get_tld(const char *name)
Obtain the TLD of the given name.
int GNUNET_GNSRECORD_zkey_to_pkey(const char *zkey, struct GNUNET_IDENTITY_PublicKey *pkey)
Convert an absolute domain name to the respective public key.
An identity key as per LSD0001.

References ac, GNS_ResolverHandle::ac_head, GNS_ResolverHandle::ac_tail, AuthorityChain::authority_info, DNS_LOOKUP_TIMEOUT, AuthorityChain::gns_authority, GNS_get_tld(), GNUNET_asprintf(), GNUNET_CONTAINER_DLL_insert_tail, GNUNET_DNSPARSER_TYPE_A, GNUNET_DNSPARSER_TYPE_AAAA, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_GNSRECORD_zkey_to_pkey(), GNUNET_log, GNUNET_new, GNUNET_OK, GNUNET_RESOLVER_ip_get(), GNUNET_RESOLVER_request_cancel(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_strndup, GNUNET_YES, handle_dns_result(), GNS_ResolverHandle::name, GNS_ResolverHandle::name_resolution_pos, GNS_ResolverHandle::record_type, recursive_resolution(), res, resolver_lookup_get_next_label(), GNS_ResolverHandle::std_resolve, GNS_ResolverHandle::task_id, and zone.

Referenced by handle_gns_resolution_result(), and recursive_redirect_resolution().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_gns_cname_result()

static void handle_gns_cname_result ( struct GNS_ResolverHandle rh,
const char *  cname 
)
static

We encountered a CNAME record during our resolution.

Merge it into our chain.

Parameters
rhresolution we are performing
cnamevalue of the cname record we got for the current authority chain tail

Definition at line 1343 of file gnunet-service-gns_resolver.c.

1345 {
1346  int af;
1347 
1348  GNUNET_free (rh->name);
1349  rh->name = GNUNET_strdup (cname);
1350  rh->name_resolution_pos = strlen (rh->name);
1351  switch (rh->record_type)
1352  {
1354  af = AF_INET;
1355  break;
1356 
1358  af = AF_INET6;
1359  break;
1360 
1361  default:
1362  af = AF_UNSPEC;
1363  break;
1364  }
1366  "Doing standard DNS lookup for `%s'\n",
1367  rh->name);
1368 
1370  af,
1373  rh);
1374 }

References DNS_LOOKUP_TIMEOUT, GNUNET_DNSPARSER_TYPE_A, GNUNET_DNSPARSER_TYPE_AAAA, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_RESOLVER_ip_get(), GNUNET_strdup, handle_dns_result(), GNS_ResolverHandle::name, GNS_ResolverHandle::name_resolution_pos, GNS_ResolverHandle::record_type, and GNS_ResolverHandle::std_resolve.

Referenced by handle_gns_resolution_result(), and recursive_cname_resolution().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_gns_resolution_result()

static void handle_gns_resolution_result ( void *  cls,
unsigned int  rd_count,
const struct GNUNET_GNSRECORD_Data rd 
)
static

Process records that were decrypted from a block.

Parameters
clsclosure with the 'struct GNS_ResolverHandle'
rd_countnumber of entries in rd array
rdarray of records with data to store

Definition at line 1894 of file gnunet-service-gns_resolver.c.

1897 {
1898  struct GNS_ResolverHandle *rh = cls;
1899  char *cname;
1900  char scratch[UINT16_MAX];
1901  size_t scratch_off;
1902  size_t scratch_start;
1903  size_t off;
1904  struct GNUNET_GNSRECORD_Data rd_new[rd_count];
1905  unsigned int rd_off;
1906 
1908  "Resolution succeeded for `%s' in zone %s, got %u records\n",
1909  rh->ac_tail->label,
1911  rd_count);
1912  if (0 == rd_count)
1913  {
1915  _ ("GNS lookup failed (zero records found for `%s')\n"),
1916  rh->name);
1917  fail_resolution (rh);
1918  return;
1919  }
1920 
1921  if (0 == rh->name_resolution_pos)
1922  {
1923  /* top-level match, are we done yet? */
1924  if ((rd_count > 0) &&
1927  {
1928  off = 0;
1929  cname = GNUNET_DNSPARSER_parse_name (rd[0].data,
1930  rd[0].data_size,
1931  &off);
1932  if ((NULL == cname) ||
1933  (off != rd[0].data_size))
1934  {
1935  GNUNET_break_op (0);
1936  GNUNET_free (cname);
1937  fail_resolution (rh);
1938  return;
1939  }
1941  cname);
1942  GNUNET_free (cname);
1943  return;
1944  }
1945  if ((rd_count > 0) &&
1948  {
1950  rd[0].data);
1951  return;
1952  }
1953 
1954 
1955  /* If A/AAAA was requested,
1956  * but we got a GNS2DNS record */
1957  if ((GNUNET_DNSPARSER_TYPE_A == rh->record_type) ||
1959  {
1960  for (unsigned int i = 0; i < rd_count; i++)
1961  {
1962  switch (rd[i].record_type)
1963  {
1965  {
1966  /* delegation to DNS */
1968  "Found GNS2DNS record, delegating to DNS!\n");
1969  if (GNUNET_OK ==
1971  rd_count,
1972  rd))
1973  return;
1974  else
1975  goto fail;
1976  }
1977 
1978  default:
1979  break;
1980  } /* end: switch */
1981  } /* end: for rd */
1982  } /* end: name_resolution_pos */
1983  /* convert relative names in record values to absolute names,
1984  using 'scratch' array for memory allocations */
1985  scratch_off = 0;
1986  rd_off = 0;
1987  for (unsigned int i = 0; i < rd_count; i++)
1988  {
1989  GNUNET_assert (rd_off <= i);
1990  if ((0 != rh->protocol) &&
1991  (0 != rh->service) &&
1993  continue; /* we _only_ care about boxed records */
1994 
1995  GNUNET_assert (rd_off < rd_count);
1996  rd_new[rd_off] = rd[i];
1997  /* Check if the embedded name(s) end in "+", and if so,
1998  replace the "+" with the zone at "ac_tail", changing the name
1999  to a ".ZONEKEY". The name is allocated on the 'scratch' array,
2000  so we can free it afterwards. */
2001  switch (rd[i].record_type)
2002  {
2004  {
2005  char *rname;
2006  rname = GNUNET_strndup (rd[i].data, rd[i].data_size);
2007  rname = translate_dot_plus (rh, rname);
2008  GNUNET_break (NULL != rname);
2009  scratch_start = scratch_off;
2010  memcpy (&scratch[scratch_start], rname, strlen (rname) + 1);
2011  scratch_off += strlen (rname) + 1;
2012  GNUNET_assert (rd_off < rd_count);
2013  rd_new[rd_off].data = &scratch[scratch_start];
2014  rd_new[rd_off].data_size = scratch_off - scratch_start;
2015  rd_off++;
2016  GNUNET_free (rname);
2017  }
2018  break;
2019 
2021  {
2022  char *cname;
2023 
2024  off = 0;
2025  cname = GNUNET_DNSPARSER_parse_name (rd[i].data,
2026  rd[i].data_size,
2027  &off);
2028  if ((NULL == cname) ||
2029  (off != rd[i].data_size))
2030  {
2031  GNUNET_break_op (0); /* record not well-formed */
2032  }
2033  else
2034  {
2035  cname = translate_dot_plus (rh, cname);
2036  GNUNET_break (NULL != cname);
2037  scratch_start = scratch_off;
2038  if (GNUNET_OK !=
2040  sizeof(scratch),
2041  &scratch_off,
2042  cname))
2043  {
2044  GNUNET_break (0);
2045  }
2046  else
2047  {
2048  GNUNET_assert (rd_off < rd_count);
2049  rd_new[rd_off].data = &scratch[scratch_start];
2050  rd_new[rd_off].data_size = scratch_off - scratch_start;
2051  rd_off++;
2052  }
2053  }
2054  GNUNET_free (cname);
2055  }
2056  break;
2057 
2059  {
2060  struct GNUNET_DNSPARSER_SoaRecord *soa;
2061 
2062  off = 0;
2064  rd[i].data_size,
2065  &off);
2066  if ((NULL == soa) ||
2067  (off != rd[i].data_size))
2068  {
2069  GNUNET_break_op (0); /* record not well-formed */
2070  }
2071  else
2072  {
2073  soa->mname = translate_dot_plus (rh, soa->mname);
2074  soa->rname = translate_dot_plus (rh, soa->rname);
2075  scratch_start = scratch_off;
2076  if (GNUNET_OK !=
2078  sizeof(scratch),
2079  &scratch_off,
2080  soa))
2081  {
2082  GNUNET_break (0);
2083  }
2084  else
2085  {
2086  GNUNET_assert (rd_off < rd_count);
2087  rd_new[rd_off].data = &scratch[scratch_start];
2088  rd_new[rd_off].data_size = scratch_off - scratch_start;
2089  rd_off++;
2090  }
2091  }
2092  if (NULL != soa)
2094  }
2095  break;
2096 
2098  {
2099  struct GNUNET_DNSPARSER_MxRecord *mx;
2100 
2101  off = 0;
2103  rd[i].data_size,
2104  &off);
2105  if ((NULL == mx) ||
2106  (off != rd[i].data_size))
2107  {
2108  GNUNET_break_op (0); /* record not well-formed */
2109  }
2110  else
2111  {
2112  mx->mxhost = translate_dot_plus (rh, mx->mxhost);
2113  scratch_start = scratch_off;
2114  if (GNUNET_OK !=
2116  sizeof(scratch),
2117  &scratch_off,
2118  mx))
2119  {
2120  GNUNET_break (0);
2121  }
2122  else
2123  {
2124  GNUNET_assert (rd_off < rd_count);
2125  rd_new[rd_off].data = &scratch[scratch_start];
2126  rd_new[rd_off].data_size = scratch_off - scratch_start;
2127  rd_off++;
2128  }
2129  }
2130  if (NULL != mx)
2132  }
2133  break;
2134 
2136  {
2137  struct GNUNET_DNSPARSER_SrvRecord *srv;
2138 
2139  off = 0;
2141  rd[i].data_size,
2142  &off);
2143  if ((NULL == srv) ||
2144  (off != rd[i].data_size))
2145  {
2146  GNUNET_break_op (0); /* record not well-formed */
2147  }
2148  else
2149  {
2150  srv->target = translate_dot_plus (rh, srv->target);
2151  scratch_start = scratch_off;
2152  if (GNUNET_OK !=
2154  sizeof(scratch),
2155  &scratch_off,
2156  srv))
2157  {
2158  GNUNET_break (0);
2159  }
2160  else
2161  {
2162  GNUNET_assert (rd_off < rd_count);
2163  rd_new[rd_off].data = &scratch[scratch_start];
2164  rd_new[rd_off].data_size = scratch_off - scratch_start;
2165  rd_off++;
2166  }
2167  }
2168  if (NULL != srv)
2170  }
2171  break;
2172 
2175  {
2177  if (rd[i].data_size < sizeof(uint32_t))
2178  {
2179  GNUNET_break_op (0);
2180  break;
2181  }
2182  if (GNUNET_OK !=
2184  rd[i].data_size,
2185  rd[i].record_type,
2186  &pubkey))
2187  {
2188  GNUNET_break_op (0);
2189  break;
2190  }
2191  rd_off++;
2192  if (rd[i].record_type != rh->record_type)
2193  {
2194  /* try to resolve "@" */
2195  struct AuthorityChain *ac;
2196 
2197  ac = GNUNET_new (struct AuthorityChain);
2198  ac->rh = rh;
2199  ac->gns_authority = GNUNET_YES;
2200  ac->authority_info.gns_authority = pubkey;
2203  rh->ac_tail,
2204  ac);
2206  rh);
2207  return;
2208  }
2209  }
2210  break;
2211 
2213  {
2214  /* delegation to DNS */
2216  {
2217  rd_off++;
2218  break; /* do not follow to DNS, we wanted the GNS2DNS record! */
2219  }
2221  "Found GNS2DNS record, delegating to DNS!\n");
2222  if (GNUNET_OK ==
2224  rd_count,
2225  rd))
2226  return;
2227  else
2228  goto fail;
2229  }
2230 
2232  {
2233  /* unbox SRV/TLSA records if a specific one was requested */
2234  if ((0 != rh->protocol) &&
2235  (0 != rh->service) &&
2236  (rd[i].data_size >= sizeof(struct GNUNET_GNSRECORD_BoxRecord)))
2237  {
2238  const struct GNUNET_GNSRECORD_BoxRecord *box;
2239 
2240  box = rd[i].data;
2242  "Got BOX record, checking if parameters match... %u/%u vs %u/%u\n",
2243  ntohs (box->protocol), ntohs (box->service),
2244  rh->protocol, rh->service);
2245  if ((ntohs (box->protocol) == rh->protocol) &&
2246  (ntohs (box->service) == rh->service))
2247  {
2248  /* Box matches, unbox! */
2249  GNUNET_assert (rd_off < rd_count);
2250  rd_new[rd_off].record_type = ntohl (box->record_type);
2251  rd_new[rd_off].data_size -= sizeof(struct
2253  rd_new[rd_off].data = &box[1];
2254  rd_off++;
2255  }
2256  }
2257  else
2258  {
2259  /* no specific protocol/service specified, preserve all BOX
2260  records (for modern, GNS-enabled applications) */
2261  rd_off++;
2262  }
2263  break;
2264  }
2265 
2266  default:
2267  rd_off++;
2268  break;
2269  } /* end: switch */
2270  } /* end: for rd_count */
2271 
2272  /* yes, we are done, return result */
2274  "Returning GNS response for `%s' with %u answers\n",
2275  rh->ac_tail->label,
2276  rd_off);
2277  rh->proc (rh->proc_cls,
2278  rd_off,
2279  rd_new);
2281  rh);
2282  return;
2283  }
2284 
2285  switch (rd[0].record_type)
2286  {
2288  GNUNET_break_op (1 == rd_count); /* REDIRECT should be unique */
2290  &rd[0]);
2291  return;
2292 
2294  GNUNET_break_op (1 == rd_count); /* CNAME should be unique */
2296  &rd[0]);
2297  return;
2298 
2301  GNUNET_break_op (1 == rd_count); /* PKEY should be unique */
2303  &rd[0]);
2304  return;
2305 
2307  if (GNUNET_OK ==
2309  rd_count,
2310  rd))
2311  return;
2312  break;
2313  default:
2315  return;
2317  _ ("Unable to process critical delegation record\n"));
2318  break;
2319  }
2320 fail:
2322  _ ("GNS lookup recursion failed (no delegation record found)\n"));
2323  fail_resolution (rh);
2324 }
#define GNUNET_GNSRECORD_TYPE_BOX
Box record.
#define GNUNET_GNSRECORD_TYPE_GNS2DNS
Delegation to DNS.
#define GNUNET_GNSRECORD_TYPE_REDIRECT
Redirection record.
#define GNUNET_GNSRECORD_TYPE_PKEY
WARNING: This header is generated! In order to add GNS record types, you must register them in GANA,...
#define GNUNET_GNSRECORD_TYPE_EDKEY
GNS zone delegation (EDKEY)
static struct GNUNET_IDENTITY_PublicKey pubkey
Public key of the zone to look in.
static void recursive_pkey_resolution(struct GNS_ResolverHandle *rh, const struct GNUNET_GNSRECORD_Data *rd)
We found a PKEY record, perform recursive resolution on it.
static void recursive_cname_resolution(struct GNS_ResolverHandle *rh, const struct GNUNET_GNSRECORD_Data *rd)
We found a CNAME record, perform recursive resolution on it.
static void handle_gns_redirect_result(struct GNS_ResolverHandle *rh, const char *rname)
We encountered a REDIRECT record during our resolution.
static char * translate_dot_plus(struct GNS_ResolverHandle *rh, char *name)
Expands a name ending in .
static void recursive_redirect_resolution(struct GNS_ResolverHandle *rh, const struct GNUNET_GNSRECORD_Data *rd)
We found a REDIRECT record, perform recursive resolution on it.
static void handle_gns_cname_result(struct GNS_ResolverHandle *rh, const char *cname)
We encountered a CNAME record during our resolution.
static int recursive_gns2dns_resolution(struct GNS_ResolverHandle *rh, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
We found one or more GNS2DNS records, perform recursive resolution on it.
struct GNUNET_DNSPARSER_SoaRecord * GNUNET_DNSPARSER_parse_soa(const char *udp_payload, size_t udp_payload_length, size_t *off)
Parse a DNS SOA record.
Definition: dnsparser.c:391
void GNUNET_DNSPARSER_free_srv(struct GNUNET_DNSPARSER_SrvRecord *srv)
Free SRV information record.
Definition: dnsparser.c:139
struct GNUNET_DNSPARSER_MxRecord * GNUNET_DNSPARSER_parse_mx(const char *udp_payload, size_t udp_payload_length, size_t *off)
Parse a DNS MX record.
Definition: dnsparser.c:436
void GNUNET_DNSPARSER_free_soa(struct GNUNET_DNSPARSER_SoaRecord *soa)
Free SOA information record.
Definition: dnsparser.c:108
struct GNUNET_DNSPARSER_SrvRecord * GNUNET_DNSPARSER_parse_srv(const char *udp_payload, size_t udp_payload_length, size_t *off)
Parse a DNS SRV record.
Definition: dnsparser.c:477
void GNUNET_DNSPARSER_free_mx(struct GNUNET_DNSPARSER_MxRecord *mx)
Free MX information record.
Definition: dnsparser.c:154
char * GNUNET_DNSPARSER_parse_name(const char *udp_payload, size_t udp_payload_length, size_t *off)
Parse name inside of a DNS query or record.
Definition: dnsparser.c:334
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_identity_from_data(const char *data, size_t data_size, uint32_t type, struct GNUNET_IDENTITY_PublicKey *key)
Build a #GNUNET_GNSRECORD_PublicKey from zone delegation resource record data.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_is_critical(uint32_t type)
Check if this type is a critical record.
Definition: gnsrecord.c:247
const char * GNUNET_GNSRECORD_z2s(const struct GNUNET_IDENTITY_PublicKey *z)
Convert a zone to a string (for printing debug messages).
struct GNS_ResolverHandle * rh
Resolver handle this entry in the chain belongs to.
Information from MX records (RFC 1035).
char * mxhost
Name of the mail server.
Information from SOA records (RFC 1035).
char * mname
The domainname of the name server that was the original or primary source of data for this zone.
char * rname
A domainname which specifies the mailbox of the person responsible for this zone.
Information from SRV records (RFC 2782).
char * target
Hostname offering the service.
Record type used to box up SRV and TLSA records.
uint32_t record_type
GNS record type of the boxed record.
uint16_t service
Service of the boxed record (aka port number), in NBO.
uint16_t protocol
Protocol of the boxed record (6 = TCP, 17 = UDP, etc.).

References _, ac, GNS_ResolverHandle::ac_head, GNS_ResolverHandle::ac_tail, AuthorityChain::authority_info, GNUNET_GNSRECORD_Data::data, data, data_size, GNUNET_GNSRECORD_Data::data_size, fail_resolution(), AuthorityChain::gns_authority, GNS_resolver_lookup_cancel_(), GNUNET_assert, GNUNET_break, GNUNET_break_op, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_DNSPARSER_builder_add_mx(), GNUNET_DNSPARSER_builder_add_name(), GNUNET_DNSPARSER_builder_add_soa(), GNUNET_DNSPARSER_builder_add_srv(), GNUNET_DNSPARSER_free_mx(), GNUNET_DNSPARSER_free_soa(), GNUNET_DNSPARSER_free_srv(), GNUNET_DNSPARSER_parse_mx(), GNUNET_DNSPARSER_parse_name(), GNUNET_DNSPARSER_parse_soa(), GNUNET_DNSPARSER_parse_srv(), GNUNET_DNSPARSER_TYPE_A, GNUNET_DNSPARSER_TYPE_AAAA, GNUNET_DNSPARSER_TYPE_CNAME, GNUNET_DNSPARSER_TYPE_MX, GNUNET_DNSPARSER_TYPE_SOA, GNUNET_DNSPARSER_TYPE_SRV, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_GNS_EMPTY_LABEL_AT, GNUNET_GNSRECORD_identity_from_data(), GNUNET_GNSRECORD_is_critical(), GNUNET_GNSRECORD_TYPE_BOX, GNUNET_GNSRECORD_TYPE_EDKEY, GNUNET_GNSRECORD_TYPE_GNS2DNS, GNUNET_GNSRECORD_TYPE_PKEY, GNUNET_GNSRECORD_TYPE_REDIRECT, GNUNET_GNSRECORD_z2s(), GNUNET_log, GNUNET_new, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_strndup, GNUNET_YES, handle_gns_cname_result(), handle_gns_redirect_result(), AuthorityChain::label, GNUNET_DNSPARSER_SoaRecord::mname, GNUNET_DNSPARSER_MxRecord::mxhost, GNS_ResolverHandle::name, GNS_ResolverHandle::name_resolution_pos, GNS_ResolverHandle::proc, GNS_ResolverHandle::proc_cls, GNS_ResolverHandle::protocol, GNUNET_GNSRECORD_BoxRecord::protocol, pubkey, rd, rd_count, GNS_ResolverHandle::record_type, GNUNET_GNSRECORD_Data::record_type, GNUNET_GNSRECORD_BoxRecord::record_type, recursive_cname_resolution(), recursive_gns2dns_resolution(), recursive_pkey_resolution(), recursive_redirect_resolution(), recursive_resolution(), AuthorityChain::rh, GNUNET_DNSPARSER_SoaRecord::rname, GNS_ResolverHandle::service, GNUNET_GNSRECORD_BoxRecord::service, GNUNET_DNSPARSER_SrvRecord::target, GNS_ResolverHandle::task_id, and translate_dot_plus().

Referenced by handle_dht_response(), and handle_gns_namecache_resolution_result().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ continue_with_gns2dns()

static void continue_with_gns2dns ( struct AuthorityChain ac)
static

We have resolved one or more of the nameservers for a GNS2DNS lookup.

Once we have some of them, begin using the DNSSTUB resolver.

Parameters
accontext for GNS2DNS resolution

Definition at line 1398 of file gnunet-service-gns_resolver.c.

1399 {
1400  struct GNS_ResolverHandle *rh = ac->rh;
1401 
1402  if ((NULL != ac->authority_info.dns_authority.gp_head) &&
1403  (GNUNET_NO == ac->authority_info.dns_authority.found))
1404  return; /* more pending and none found yet */
1405  if (GNUNET_NO == ac->authority_info.dns_authority.found)
1406  {
1408  "Failed to resolve DNS server for `%s' in GNS2DNS resolution\n",
1409  ac->authority_info.dns_authority.name);
1410  fail_resolution (rh);
1411  return;
1412  }
1413  if (GNUNET_NO != ac->authority_info.dns_authority.launched)
1414  return; /* already running, do not launch again! */
1415  /* recurse */
1416  ac->authority_info.dns_authority.launched = GNUNET_YES;
1418  "Will continue resolution using DNS to resolve `%s'\n",
1419  ac->label);
1420  GNUNET_assert (NULL == rh->task_id);
1422  rh);
1423 }

References ac, fail_resolution(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_add_now(), GNUNET_YES, recursive_resolution(), and GNS_ResolverHandle::task_id.

Referenced by handle_gns2dns_ip(), handle_gns2dns_result(), and recursive_gns2dns_resolution().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_gns2dns_result()

static void handle_gns2dns_result ( void *  cls,
unsigned int  rd_count,
const struct GNUNET_GNSRECORD_Data rd 
)
static

We've resolved the IP address for the DNS resolver to use after encountering a GNS2DNS record.

Parameters
clsthe struct Gns2DnsPending used for this request
rd_countnumber of records in rd
rdaddresses for the DNS resolver (presumably)

Definition at line 1435 of file gnunet-service-gns_resolver.c.

1438 {
1439  struct Gns2DnsPending *gp = cls;
1440  struct AuthorityChain *ac = gp->ac;
1441 
1442  GNUNET_CONTAINER_DLL_remove (ac->authority_info.dns_authority.gp_head,
1443  ac->authority_info.dns_authority.gp_tail,
1444  gp);
1445  /* enable cleanup of 'rh' handle that automatically comes after we return,
1446  and which expects 'rh' to be in the #rlh_head DLL. */
1447  if (NULL != gp->rh)
1448  {
1450  rlh_tail,
1451  gp->rh);
1452  gp->rh = NULL;
1453  }
1454  GNUNET_free (gp);
1456  "Received %u results for IP address of DNS server for GNS2DNS transition\n",
1457  rd_count);
1458  /* find suitable A/AAAA record */
1459  for (unsigned int j = 0; j < rd_count; j++)
1460  {
1461  switch (rd[j].record_type)
1462  {
1464  {
1465  struct sockaddr_in v4;
1466 
1467  if (sizeof(struct in_addr) != rd[j].data_size)
1468  {
1469  GNUNET_break_op (0);
1470  continue;
1471  }
1472  memset (&v4,
1473  0,
1474  sizeof(v4));
1475  v4.sin_family = AF_INET;
1476  v4.sin_port = htons (53);
1477 #if HAVE_SOCKADDR_IN_SIN_LEN
1478  v4.sin_len = (u_char) sizeof(v4);
1479 #endif
1480  GNUNET_memcpy (&v4.sin_addr,
1481  rd[j].data,
1482  sizeof(struct in_addr));
1483  if (GNUNET_OK ==
1485  ac->authority_info.dns_authority.dns_handle,
1486  (const struct sockaddr *) &v4))
1487  ac->authority_info.dns_authority.found = GNUNET_YES;
1488  break;
1489  }
1490 
1492  {
1493  struct sockaddr_in6 v6;
1494 
1495  if (sizeof(struct in6_addr) != rd[j].data_size)
1496  {
1497  GNUNET_break_op (0);
1498  continue;
1499  }
1500  /* FIXME: might want to check if we support IPv6 here,
1501  and otherwise skip this one and hope we find another */
1502  memset (&v6,
1503  0,
1504  sizeof(v6));
1505  v6.sin6_family = AF_INET6;
1506  v6.sin6_port = htons (53);
1507 #if HAVE_SOCKADDR_IN_SIN_LEN
1508  v6.sin6_len = (u_char) sizeof(v6);
1509 #endif
1510  GNUNET_memcpy (&v6.sin6_addr,
1511  rd[j].data,
1512  sizeof(struct in6_addr));
1513  if (GNUNET_OK ==
1515  ac->authority_info.dns_authority.dns_handle,
1516  (const struct sockaddr *) &v6))
1517  ac->authority_info.dns_authority.found = GNUNET_YES;
1518  break;
1519  }
1520 
1521  default:
1522  break;
1523  }
1524  }
1526 }
static struct GNS_ResolverHandle * rlh_tail
Tail of resolver lookup list.
static struct GNS_ResolverHandle * rlh_head
Head of resolver lookup list.
static void continue_with_gns2dns(struct AuthorityChain *ac)
We have resolved one or more of the nameservers for a GNS2DNS lookup.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
int GNUNET_DNSSTUB_add_dns_sa(struct GNUNET_DNSSTUB_Context *ctx, const struct sockaddr *sa)
Add nameserver for use by the DNSSTUB.
Definition: dnsstub.c:665
Element of a resolution process for looking up the responsible DNS server hostname in a GNS2DNS recur...
struct GNS_ResolverHandle * rh
Handle for the resolution of the IP part of the GNS2DNS record.
struct AuthorityChain * ac
Context this activity belongs with.

References Gns2DnsPending::ac, ac, continue_with_gns2dns(), GNUNET_GNSRECORD_Data::data, data_size, GNUNET_break_op, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_remove, GNUNET_DNSPARSER_TYPE_A, GNUNET_DNSPARSER_TYPE_AAAA, GNUNET_DNSSTUB_add_dns_sa(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_memcpy, GNUNET_OK, GNUNET_YES, rd, rd_count, Gns2DnsPending::rh, rlh_head, and rlh_tail.

Referenced by recursive_gns2dns_resolution().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_gns2dns_ip()

static void handle_gns2dns_ip ( void *  cls,
const struct sockaddr *  addr,
socklen_t  addrlen 
)
static

Function called by the resolver for each address obtained from DNS.

Parameters
clsclosure, a struct Gns2DnsPending *
addrone of the addresses of the host, NULL for the last address
addrlenlength of addr

Definition at line 1537 of file gnunet-service-gns_resolver.c.

1540 {
1541  struct Gns2DnsPending *gp = cls;
1542  struct AuthorityChain *ac = gp->ac;
1543  struct sockaddr_storage ss;
1544  struct sockaddr_in *v4;
1545  struct sockaddr_in6 *v6;
1546 
1547  if (NULL == addr)
1548  {
1549  /* DNS resolution finished */
1550  if (0 == gp->num_results)
1552  "Failed to use DNS to resolve name of DNS resolver\n");
1553  GNUNET_CONTAINER_DLL_remove (ac->authority_info.dns_authority.gp_head,
1554  ac->authority_info.dns_authority.gp_tail,
1555  gp);
1556  GNUNET_free (gp);
1558  return;
1559  }
1560  GNUNET_memcpy (&ss,
1561  addr,
1562  addrlen);
1563  switch (ss.ss_family)
1564  {
1565  case AF_INET:
1566  v4 = (struct sockaddr_in *) &ss;
1567  v4->sin_port = htons (53);
1568  gp->num_results++;
1569  break;
1570 
1571  case AF_INET6:
1572  v6 = (struct sockaddr_in6 *) &ss;
1573  v6->sin6_port = htons (53);
1574  gp->num_results++;
1575  break;
1576 
1577  default:
1579  "Unsupported AF %d\n",
1580  ss.ss_family);
1581  return;
1582  }
1583  if (GNUNET_OK ==
1584  GNUNET_DNSSTUB_add_dns_sa (ac->authority_info.dns_authority.dns_handle,
1585  (struct sockaddr *) &ss))
1586  ac->authority_info.dns_authority.found = GNUNET_YES;
1587 }
@ GNUNET_ERROR_TYPE_ERROR
unsigned int num_results
How many results did we get?

References Gns2DnsPending::ac, ac, continue_with_gns2dns(), GNUNET_CONTAINER_DLL_remove, GNUNET_DNSSTUB_add_dns_sa(), GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_memcpy, GNUNET_OK, GNUNET_YES, and Gns2DnsPending::num_results.

Referenced by recursive_gns2dns_resolution().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ recursive_redirect_resolution()

static void recursive_redirect_resolution ( struct GNS_ResolverHandle rh,
const struct GNUNET_GNSRECORD_Data rd 
)
static

We found a REDIRECT record, perform recursive resolution on it.

Parameters
rhresolution handle
rdrecord with CNAME to resolve recursively

Definition at line 1597 of file gnunet-service-gns_resolver.c.

1599 {
1601  rd->data);
1602 }

References GNUNET_GNSRECORD_Data::data, handle_gns_redirect_result(), and rd.

Referenced by handle_gns_resolution_result().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ recursive_cname_resolution()

static void recursive_cname_resolution ( struct GNS_ResolverHandle rh,
const struct GNUNET_GNSRECORD_Data rd 
)
static

We found a CNAME record, perform recursive resolution on it.

Parameters
rhresolution handle
rdrecord with CNAME to resolve recursively

Definition at line 1612 of file gnunet-service-gns_resolver.c.

1614 {
1615  char *cname;
1616  size_t off;
1617 
1618  off = 0;
1620  rd->data_size,
1621  &off);
1622  if ((NULL == cname) ||
1623  (off != rd->data_size))
1624  {
1625  GNUNET_break_op (0); /* record not well-formed */
1626  GNUNET_free (cname);
1627  fail_resolution (rh);
1628  return;
1629  }
1631  cname);
1632  GNUNET_free (cname);
1633 }

References GNUNET_GNSRECORD_Data::data, GNUNET_GNSRECORD_Data::data_size, fail_resolution(), GNUNET_break_op, GNUNET_DNSPARSER_parse_name(), GNUNET_free, handle_gns_cname_result(), and rd.

Referenced by handle_gns_resolution_result().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ recursive_pkey_resolution()

static void recursive_pkey_resolution ( struct GNS_ResolverHandle rh,
const struct GNUNET_GNSRECORD_Data rd 
)
static

We found a PKEY record, perform recursive resolution on it.

Parameters
rhresolution handle
rdrecord with PKEY to resolve recursively

Definition at line 1643 of file gnunet-service-gns_resolver.c.

1645 {
1646  struct AuthorityChain *ac;
1647  struct GNUNET_IDENTITY_PublicKey auth;
1648 
1649  /* delegation to another zone */
1651  rd->data_size,
1652  rd->record_type,
1653  &auth))
1654  {
1655  GNUNET_break_op (0);
1656  fail_resolution (rh);
1657  return;
1658  }
1659  /* expand authority chain */
1660  ac = GNUNET_new (struct AuthorityChain);
1661  ac->rh = rh;
1662  ac->gns_authority = GNUNET_YES;
1663  ac->authority_info.gns_authority = auth;
1664  ac->label = resolver_lookup_get_next_label (rh);
1665  /* add AC to tail */
1667  rh->ac_tail,
1668  ac);
1669  /* recurse */
1671  rh);
1672 }

References ac, GNS_ResolverHandle::ac_head, GNS_ResolverHandle::ac_tail, GNUNET_GNSRECORD_Data::data, GNUNET_GNSRECORD_Data::data_size, fail_resolution(), GNUNET_break_op, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_GNSRECORD_identity_from_data(), GNUNET_new, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_YES, rd, GNUNET_GNSRECORD_Data::record_type, recursive_resolution(), resolver_lookup_get_next_label(), and GNS_ResolverHandle::task_id.

Referenced by handle_gns_resolution_result().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ recursive_gns2dns_resolution()

static int recursive_gns2dns_resolution ( struct GNS_ResolverHandle rh,
unsigned int  rd_count,
const struct GNUNET_GNSRECORD_Data rd 
)
static

We found one or more GNS2DNS records, perform recursive resolution on it.

(to be precise, one or more records in rd is GNS2DNS, there may be others, so this function still needs to check which ones are GNS2DNS).

Parameters
rhresolution handle
rd_countlength of the rd array
rdrecord with PKEY to resolve recursively
Returns
GNUNET_OK if this worked, GNUNET_SYSERR if no GNS2DNS records were in rd

Records other than GNS2DNS not allowed

Definition at line 1686 of file gnunet-service-gns_resolver.c.

1689 {
1690  struct AuthorityChain *ac;
1691  const char *tld;
1692  char *ns;
1693 
1694  ns = NULL;
1695  /* expand authority chain */
1696  ac = GNUNET_new (struct AuthorityChain);
1697  ac->rh = rh;
1698  ac->authority_info.dns_authority.dns_handle = GNUNET_DNSSTUB_start (4);
1699 
1700  for (unsigned int i = 0; i < rd_count; i++)
1701  {
1702  char *ip;
1703  char *n;
1704  size_t off;
1705  struct Gns2DnsPending *gp;
1707  struct sockaddr_in v4;
1708  struct sockaddr_in6 v6;
1709 
1710  if (GNUNET_GNSRECORD_TYPE_GNS2DNS != rd[i].record_type)
1711  {
1715  GNUNET_free (ns);
1716  GNUNET_free (ac);
1717  return GNUNET_SYSERR;
1718  }
1719  off = 0;
1721  rd[i].data_size,
1722  &off);
1723  ip = GNUNET_strdup (&((const char *) rd[i].data)[off]);
1724  if ((NULL == n) ||
1725  (NULL == ip))
1726  {
1727  GNUNET_break_op (0);
1728  GNUNET_free (n);
1729  GNUNET_free (ip);
1730  continue;
1731  }
1732 
1733  off += strlen (ip) + 1;
1734 
1735  if (off != rd[i].data_size)
1736  {
1737  GNUNET_break_op (0);
1738  GNUNET_free (n);
1739  GNUNET_free (ip);
1740  continue;
1741  }
1742  /* resolve 'ip' to determine the IP(s) of the DNS
1743  resolver to use for lookup of 'ns' */
1744  if (NULL != ns)
1745  {
1746  if (0 != strcasecmp (ns,
1747  n))
1748  {
1749  /* NS values must all be the same for all GNS2DNS records,
1750  anything else leads to insanity */
1751  GNUNET_break_op (0);
1752  GNUNET_free (n);
1753  GNUNET_free (ip);
1754  continue;
1755  }
1756  GNUNET_free (n);
1757  }
1758  else
1759  {
1760  ns = n;
1761  }
1762 
1763  /* check if 'ip' is already an IPv4/IPv6 address */
1764  if ((1 == inet_pton (AF_INET,
1765  ip,
1766  &v4)) ||
1767  (1 == inet_pton (AF_INET6,
1768  ip,
1769  &v6)))
1770  {
1773  ac->authority_info.dns_authority.dns_handle,
1774  ip));
1775  ac->authority_info.dns_authority.found = GNUNET_YES;
1776  GNUNET_free (ip);
1777  continue;
1778  }
1779  tld = GNS_get_tld (ip);
1780  if ((0 != strcmp (tld, "+")) &&
1782  {
1783  /* 'ip' is a DNS name */
1784  gp = GNUNET_new (struct Gns2DnsPending);
1785  gp->ac = ac;
1786  GNUNET_CONTAINER_DLL_insert (ac->authority_info.dns_authority.gp_head,
1787  ac->authority_info.dns_authority.gp_tail,
1788  gp);
1789  gp->dns_rh = GNUNET_RESOLVER_ip_get (ip,
1790  AF_UNSPEC,
1793  gp);
1794  GNUNET_free (ip);
1795  continue;
1796  }
1797  /* 'ip' should be a GNS name */
1798  gp = GNUNET_new (struct Gns2DnsPending);
1799  gp->ac = ac;
1800  GNUNET_CONTAINER_DLL_insert (ac->authority_info.dns_authority.gp_head,
1801  ac->authority_info.dns_authority.gp_tail,
1802  gp);
1803  gp->rh = GNUNET_new (struct GNS_ResolverHandle);
1804  if (0 == strcmp (tld, "+"))
1805  {
1806  ip = translate_dot_plus (rh,
1807  ip);
1808  tld = GNS_get_tld (ip);
1809  if (GNUNET_OK !=
1811  &zone))
1812  {
1813  GNUNET_break_op (0);
1814  GNUNET_free (ip);
1815  continue;
1816  }
1817  }
1818  gp->rh->authority_zone = zone;
1820  "Resolving `%s' to determine IP address of DNS server for GNS2DNS transition for `%s'\n",
1821  ip,
1822  ns);
1823  gp->rh->name = ip;
1824  gp->rh->name_resolution_pos = strlen (ip) - strlen (tld) - 1;
1825  gp->rh->proc = &handle_gns2dns_result;
1826  gp->rh->proc_cls = gp;
1829  gp->rh->loop_limiter = rh->loop_limiter + 1;
1830  gp->rh->loop_threshold = rh->loop_threshold;
1831  gp->rh->task_id
1833  gp->rh);
1834  } /* end 'for all records' */
1835 
1836  if (NULL == ns)
1837  {
1838  /* not a single GNS2DNS record found */
1839  GNUNET_free (ac);
1840  return GNUNET_SYSERR;
1841  }
1843  strcpy (ac->authority_info.dns_authority.name,
1844  ns);
1845  /* for DNS recursion, the label is the full DNS name,
1846  created from the remainder of the GNS name and the
1847  name in the NS record */
1848  GNUNET_asprintf (&ac->label,
1849  "%.*s%s%s",
1850  (int) rh->name_resolution_pos,
1851  rh->name,
1852  (0 != rh->name_resolution_pos) ? "." : "",
1853  ns);
1854  GNUNET_free (ns);
1855 
1856  {
1857  /* the GNS name is UTF-8 and may include multibyte chars.
1858  * We have to convert the combined name to a DNS-compatible IDNA.
1859  */
1860  char *tmp = ac->label;
1861 
1862  if (IDNA_SUCCESS != idna_to_ascii_8z (tmp,
1863  &ac->label,
1864  IDNA_ALLOW_UNASSIGNED))
1865  {
1867  _ ("Name `%s' cannot be converted to IDNA."),
1868  tmp);
1869  GNUNET_free (tmp);
1870  GNUNET_free (ac);
1871  return GNUNET_SYSERR;
1872  }
1873  GNUNET_free (tmp);
1874  }
1875 
1877  rh->ac_tail,
1878  ac);
1879  if (strlen (ac->label) > GNUNET_DNSPARSER_MAX_NAME_LENGTH)
1880  {
1882  _ ("GNS lookup resulted in DNS name that is too long (`%s')\n"),
1883  ac->label);
1884  GNUNET_free (ac->label);
1885  GNUNET_free (ac);
1886  return GNUNET_SYSERR;
1887  }
1889  return GNUNET_OK;
1890 }
static struct GNUNET_NAMESTORE_Handle * ns
Handle to the namestore.
Definition: gnunet-abd.c:41
static void handle_gns2dns_ip(void *cls, const struct sockaddr *addr, socklen_t addrlen)
Function called by the resolver for each address obtained from DNS.
static void start_resolver_lookup(void *cls)
Begin the resolution process from 'name', starting with the identification of the zone specified by '...
static void handle_gns2dns_result(void *cls, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
We've resolved the IP address for the DNS resolver to use after encountering a GNS2DNS record.
#define GNUNET_DNSPARSER_MAX_NAME_LENGTH
Maximum length of a name in DNS.
int GNUNET_DNSSTUB_add_dns_ip(struct GNUNET_DNSSTUB_Context *ctx, const char *dns_ip)
Add nameserver for use by the DNSSTUB.
Definition: dnsstub.c:613
struct GNUNET_DNSSTUB_Context * GNUNET_DNSSTUB_start(unsigned int num_sockets)
Start a DNS stub resolver.
Definition: dnsstub.c:586
@ GNUNET_GNS_LO_DEFAULT
Defaults, look in cache, then in DHT.
#define GNUNET_GNSRECORD_TYPE_ANY
Record type indicating any record/'*'.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
enum GNUNET_GNS_LocalOptions options
Use only cache.
struct GNUNET_RESOLVER_RequestHandle * dns_rh
Handle for DNS resolution of the DNS nameserver.

References _, Gns2DnsPending::ac, ac, GNS_ResolverHandle::ac_head, GNS_ResolverHandle::ac_tail, GNS_ResolverHandle::authority_zone, continue_with_gns2dns(), data, data_size, Gns2DnsPending::dns_rh, GNS_get_tld(), GNUNET_asprintf(), GNUNET_assert, GNUNET_break, GNUNET_break_op, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_DNSPARSER_MAX_NAME_LENGTH, GNUNET_DNSPARSER_parse_name(), GNUNET_DNSSTUB_add_dns_ip(), GNUNET_DNSSTUB_start(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_GNS_LO_DEFAULT, GNUNET_GNSRECORD_TYPE_ANY, GNUNET_GNSRECORD_TYPE_GNS2DNS, GNUNET_GNSRECORD_zkey_to_pkey(), GNUNET_log, GNUNET_new, GNUNET_OK, GNUNET_RESOLVER_ip_get(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, handle_gns2dns_ip(), handle_gns2dns_result(), GNS_ResolverHandle::loop_limiter, GNS_ResolverHandle::loop_threshold, GNS_ResolverHandle::name, GNS_ResolverHandle::name_resolution_pos, ns, GNS_ResolverHandle::options, GNS_ResolverHandle::proc, GNS_ResolverHandle::proc_cls, rd, rd_count, GNS_ResolverHandle::record_type, Gns2DnsPending::rh, AuthorityChain::rh, start_resolver_lookup(), GNS_ResolverHandle::task_id, translate_dot_plus(), and zone.

Referenced by handle_gns_resolution_result().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ namecache_cache_continuation()

static void namecache_cache_continuation ( void *  cls,
int32_t  success,
const char *  emsg 
)
static

Function called once the namestore has completed the request for caching a block.

Parameters
clsclosure with the struct CacheOps
successGNUNET_OK on success
emsgerror message

Definition at line 2336 of file gnunet-service-gns_resolver.c.

2339 {
2340  struct CacheOps *co = cls;
2341 
2342  co->namecache_qe_cache = NULL;
2343  if (GNUNET_OK != success)
2345  _ ("Failed to cache GNS resolution: %s\n"),
2346  emsg);
2348  co_tail,
2349  co);
2350  GNUNET_free (co);
2351 }
static struct CacheOps * co_head
Organized in a DLL.
static struct CacheOps * co_tail
Organized in a DLL.
Active namestore caching operations.
struct GNUNET_NAMECACHE_QueueEntry * namecache_qe_cache
Pending Namestore caching task.

References _, co_head, co_tail, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_OK, and CacheOps::namecache_qe_cache.

Referenced by handle_dht_response().

Here is the caller graph for this function:

◆ handle_dht_response()

static void handle_dht_response ( void *  cls,
struct GNUNET_TIME_Absolute  exp,
const struct GNUNET_HashCode key,
const struct GNUNET_PeerIdentity trunc_peer,
const struct GNUNET_DHT_PathElement get_path,
unsigned int  get_path_length,
const struct GNUNET_DHT_PathElement put_path,
unsigned int  put_path_length,
enum GNUNET_BLOCK_Type  type,
size_t  size,
const void *  data 
)
static

Iterator called on each result obtained for a DHT operation that expects a reply.

Parameters
clsclosure with the struct GNS_ResolverHandle
expwhen will this value expire
keykey of the result
trunc_peertruncated peer, NULL if not truncated
get_pathpeers on reply path (or NULL if not recorded) [0] = datastore's first neighbor, [length - 1] = local peer
get_path_lengthnumber of entries in get_path
put_pathpeers on the PUT path (or NULL if not recorded) [0] = origin, [length - 1] = datastore
put_path_lengthnumber of entries in put_path
typetype of the result
sizenumber of bytes in data
datapointer to the result data

Definition at line 2373 of file gnunet-service-gns_resolver.c.

2384 {
2385  struct GNS_ResolverHandle *rh = cls;
2386  struct AuthorityChain *ac = rh->ac_tail;
2387  const struct GNUNET_GNSRECORD_Block *block;
2388  struct CacheOps *co;
2389 
2390  (void) exp;
2391  (void) key;
2392  (void) get_path;
2393  (void) get_path_length;
2394  (void) put_path;
2395  (void) put_path_length;
2396  (void) type;
2398  rh->get_handle = NULL;
2400  rh->dht_heap_node = NULL;
2402  "Handling response from the DHT\n");
2403  if (size < sizeof(struct GNUNET_GNSRECORD_Block))
2404  {
2405  /* how did this pass DHT block validation!? */
2406  GNUNET_break (0);
2407  fail_resolution (rh);
2408  return;
2409  }
2410  block = data;
2411  if (size != GNUNET_GNSRECORD_block_get_size (block))
2412  {
2413  /* how did this pass DHT block validation!? */
2414  GNUNET_break (0);
2415  fail_resolution (rh);
2416  return;
2417  }
2419  "Decrypting DHT block of size %lu for `%s', expires %s\n",
2421  rh->name,
2423  if (GNUNET_OK !=
2425  &ac->authority_info.gns_authority,
2426  ac->label,
2428  rh))
2429  {
2430  GNUNET_break_op (0); /* block was ill-formed */
2431  fail_resolution (rh);
2432  return;
2433  }
2436  rel_value_us)
2437  {
2439  "Received expired block from the DHT, will not cache it.\n");
2440  return;
2441  }
2442  if (GNUNET_YES == disable_cache)
2443  return;
2444  /* Cache well-formed blocks */
2446  "Caching response from the DHT in namecache\n");
2447  co = GNUNET_new (struct CacheOps);
2449  block,
2450  &
2452  co);
2454  co_tail,
2455  co);
2456 }
struct GNUNET_HashCode key
The key used in the DHT.
static int disable_cache
Use namecache.
static void namecache_cache_continuation(void *cls, int32_t success, const char *emsg)
Function called once the namestore has completed the request for caching a block.
static void handle_gns_resolution_result(void *cls, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process records that were decrypted from a block.
static struct GNUNET_NAMECACHE_Handle * namecache_handle
Our handle to the namecache service.
void GNUNET_DHT_get_stop(struct GNUNET_DHT_GetHandle *get_handle)
Stop async DHT-get.
Definition: dht_api.c:1237
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_block_decrypt(const struct GNUNET_GNSRECORD_Block *block, const struct GNUNET_IDENTITY_PublicKey *zone_key, const char *label, GNUNET_GNSRECORD_RecordCallback proc, void *proc_cls)
Decrypt block.
size_t GNUNET_GNSRECORD_block_get_size(const struct GNUNET_GNSRECORD_Block *block)
Returns the length of this block in bytes.
struct GNUNET_TIME_Absolute GNUNET_GNSRECORD_block_get_expiration(const struct GNUNET_GNSRECORD_Block *block)
Returns the expiration of a block.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
struct GNUNET_NAMECACHE_QueueEntry * GNUNET_NAMECACHE_block_cache(struct GNUNET_NAMECACHE_Handle *h, const struct GNUNET_GNSRECORD_Block *block, GNUNET_NAMECACHE_ContinuationWithStatus cont, void *cont_cls)
Store an item in the namecache.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:405
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:616
static unsigned int size
Size of the "table".
Definition: peer.c:68
struct GNUNET_CONTAINER_HeapNode * dht_heap_node
Heap node associated with this lookup.
struct GNUNET_DHT_GetHandle * get_handle
Handle for DHT lookups.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model

References ac, GNS_ResolverHandle::ac_tail, co_head, co_tail, data, GNS_ResolverHandle::dht_heap_node, disable_cache, fail_resolution(), GNS_ResolverHandle::get_handle, GNUNET_break, GNUNET_break_op, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_heap_remove_node(), GNUNET_DHT_get_stop(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_GNSRECORD_block_decrypt(), GNUNET_GNSRECORD_block_get_expiration(), GNUNET_GNSRECORD_block_get_size(), GNUNET_log, GNUNET_NAMECACHE_block_cache(), GNUNET_new, GNUNET_OK, GNUNET_STRINGS_absolute_time_to_string(), GNUNET_TIME_absolute_get_remaining(), GNUNET_YES, handle_gns_resolution_result(), key, GNS_ResolverHandle::name, namecache_cache_continuation(), namecache_handle, CacheOps::namecache_qe_cache, AuthorityChain::rh, size, and type.

Referenced by start_dht_request().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ start_dht_request()

static void start_dht_request ( struct GNS_ResolverHandle rh,
const struct GNUNET_HashCode query 
)
static

Initiate a DHT query for a set of GNS records.

Parameters
rhresolution handle
querykey to use in the DHT lookup

Definition at line 2466 of file gnunet-service-gns_resolver.c.

2468 {
2469  struct GNS_ResolverHandle *rx;
2470 
2471  GNUNET_assert (NULL == rh->get_handle);
2474  query,
2477  NULL, 0,
2478  &handle_dht_response, rh);
2480  rh,
2482  abs_value_us);
2485  {
2486  /* fail longest-standing DHT request */
2488  rx->dht_heap_node = NULL;
2489  GNUNET_assert (NULL != rx);
2490  fail_resolution (rx);
2491  }
2492 }
@ GNUNET_BLOCK_TYPE_GNS_NAMERECORD
Block for storing GNS record data.
static unsigned long long max_allowed_background_queries
Maximum amount of parallel queries to the DHT.
static struct GNUNET_DHT_Handle * dht_handle
Resolver handle to the dht.
static void handle_dht_response(void *cls, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const struct GNUNET_PeerIdentity *trunc_peer, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *put_path, unsigned int put_path_length, enum GNUNET_BLOCK_Type type, size_t size, const void *data)
Iterator called on each result obtained for a DHT operation that expects a reply.
#define DHT_GNS_REPLICATION_LEVEL
DHT replication level.
static struct GNUNET_CONTAINER_Heap * dht_lookup_heap
Heap for limiting parallel DHT lookups.
struct GNUNET_DHT_GetHandle * GNUNET_DHT_get_start(struct GNUNET_DHT_Handle *handle, enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode *key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, const void *xquery, size_t xquery_size, GNUNET_DHT_GetIterator iter, void *iter_cls)
Perform an asynchronous GET operation on the DHT identified.
Definition: dht_api.c:1164
@ GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE
Each peer along the way should process the request (otherwise only peers locally closest to the key w...
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
unsigned int GNUNET_CONTAINER_heap_get_size(const struct GNUNET_CONTAINER_Heap *heap)
Get the current size of the heap.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111

References DHT_GNS_REPLICATION_LEVEL, dht_handle, GNS_ResolverHandle::dht_heap_node, dht_lookup_heap, fail_resolution(), GNS_ResolverHandle::get_handle, GNUNET_assert, GNUNET_BLOCK_TYPE_GNS_NAMERECORD, GNUNET_CONTAINER_heap_get_size(), GNUNET_CONTAINER_heap_insert(), GNUNET_CONTAINER_heap_remove_root(), GNUNET_DHT_get_start(), GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, GNUNET_TIME_absolute_get(), handle_dht_response(), and max_allowed_background_queries.

Referenced by handle_namecache_block_response(), and recursive_gns_resolution_namecache().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_gns_namecache_resolution_result()

static void handle_gns_namecache_resolution_result ( void *  cls,
unsigned int  rd_count,
const struct GNUNET_GNSRECORD_Data rd 
)
static

Process a records that were decrypted from a block that we got from the namecache.

Simply calls handle_gns_resolution_result().

Parameters
clsclosure with the struct GNS_ResolverHandle
rd_countnumber of entries in rd array
rdarray of records with data to store

Definition at line 2504 of file gnunet-service-gns_resolver.c.

2507 {
2508  struct GNS_ResolverHandle *rh = cls;
2509 
2510  if (0 == rd_count)
2512  _ ("GNS namecache returned empty result for `%s'\n"),
2513  rh->name);
2515  rd_count,
2516  rd);
2517 }

References _, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, handle_gns_resolution_result(), GNS_ResolverHandle::name, rd, and rd_count.

Referenced by handle_namecache_block_response().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_namecache_block_response()

static void handle_namecache_block_response ( void *  cls,
const struct GNUNET_GNSRECORD_Block block 
)
static

Process a record that was stored in the namecache.

Parameters
clsclosure with the struct GNS_ResolverHandle
blockblock that was stored in the namecache

Definition at line 2527 of file gnunet-service-gns_resolver.c.

2529 {
2530  struct GNS_ResolverHandle *rh = cls;
2531  struct AuthorityChain *ac = rh->ac_tail;
2532  const char *label = ac->label;
2533  const struct GNUNET_IDENTITY_PublicKey *auth =
2534  &ac->authority_info.gns_authority;
2535  struct GNUNET_HashCode query;
2536 
2537  GNUNET_assert (NULL != rh->namecache_qe);
2538  rh->namecache_qe = NULL;
2539  if (NULL == block)
2541  "No block found\n");
2542  else
2544  "Got block with expiration %s\n",
2547  if (((GNUNET_GNS_LO_DEFAULT == rh->options) ||
2548  ((GNUNET_GNS_LO_LOCAL_MASTER == rh->options) &&
2549  (ac != rh->ac_head))) &&
2550  ((NULL == block) ||
2553  rel_value_us)))
2554  {
2555  /* namecache knows nothing; try DHT lookup */
2557  label,
2558  &query);
2560  "Starting DHT lookup for `%s' in zone `%s' under key `%s'\n",
2561  ac->label,
2562  GNUNET_GNSRECORD_z2s (&ac->authority_info.gns_authority),
2563  GNUNET_h2s (&query));
2564  start_dht_request (rh, &query);
2565  return;
2566  }
2567 
2568  if ((NULL == block) ||
2571  rel_value_us))
2572  {
2573  /* DHT not permitted and no local result, fail */
2575  "Resolution failed for `%s' in zone %s (DHT lookup not permitted by configuration)\n",
2576  ac->label,
2577  GNUNET_GNSRECORD_z2s (&ac->authority_info.gns_authority));
2578  fail_resolution (rh);
2579  return;
2580  }
2582  "Received result from namecache for label `%s'\n",
2583  ac->label);
2584 
2585  if (GNUNET_OK !=
2587  auth,
2588  label,
2590  rh))
2591  {
2592  GNUNET_break_op (0); /* block was ill-formed */
2593  /* try DHT instead */
2595  label,
2596  &query);
2598  "Starting DHT lookup for `%s' in zone `%s' under key `%s'\n",
2599  ac->label,
2600  GNUNET_GNSRECORD_z2s (&ac->authority_info.gns_authority),
2601  GNUNET_h2s (&query));
2602  start_dht_request (rh, &query);
2603  return;
2604  }
2605 }
static void start_dht_request(struct GNS_ResolverHandle *rh, const struct GNUNET_HashCode *query)
Initiate a DHT query for a set of GNS records.
static void handle_gns_namecache_resolution_result(void *cls, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process a records that were decrypted from a block that we got from the namecache.
@ GNUNET_GNS_LO_LOCAL_MASTER
For the rightmost label, only look in the cache (it is our local namestore), for the others,...
void GNUNET_GNSRECORD_query_from_public_key(const struct GNUNET_IDENTITY_PublicKey *pub, const char *label, struct GNUNET_HashCode *query)
Calculate the DHT query for a given label in a given zone.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
struct GNUNET_NAMECACHE_QueueEntry * namecache_qe
Pending Namecache lookup task.
A 512-bit hashcode.

References ac, GNS_ResolverHandle::ac_head, GNS_ResolverHandle::ac_tail, fail_resolution(), GNUNET_assert, GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_GNS_LO_DEFAULT, GNUNET_GNS_LO_LOCAL_MASTER, GNUNET_GNSRECORD_block_decrypt(), GNUNET_GNSRECORD_block_get_expiration(), GNUNET_GNSRECORD_query_from_public_key(), GNUNET_GNSRECORD_z2s(), GNUNET_h2s(), GNUNET_log, GNUNET_OK, GNUNET_STRINGS_absolute_time_to_string(), GNUNET_TIME_absolute_get_remaining(), handle_gns_namecache_resolution_result(), AuthorityChain::label, GNS_ResolverHandle::namecache_qe, GNS_ResolverHandle::options, AuthorityChain::rh, and start_dht_request().

Referenced by recursive_gns_resolution_namecache().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ recursive_gns_resolution_namecache()

static void recursive_gns_resolution_namecache ( struct GNS_ResolverHandle rh)
static

Lookup tail of our authority chain in the namecache.

Parameters
rhquery we are processing

Definition at line 2614 of file gnunet-service-gns_resolver.c.

2615 {
2616  struct AuthorityChain *ac = rh->ac_tail;
2617  struct GNUNET_HashCode query;
2618 
2620  "Starting GNS resolution for `%s' in zone %s\n",
2621  ac->label,
2622  GNUNET_GNSRECORD_z2s (&ac->authority_info.gns_authority));
2623  GNUNET_GNSRECORD_query_from_public_key (&ac->authority_info.gns_authority,
2624  ac->label,
2625  &query);
2626  if (GNUNET_YES != disable_cache)
2627  {
2628  rh->namecache_qe
2630  &query,
2632  rh);
2633  GNUNET_assert (NULL != rh->namecache_qe);
2634  }
2635  else
2636  {
2637  start_dht_request (rh,
2638  &query);
2639  }
2640 }
static void handle_namecache_block_response(void *cls, const struct GNUNET_GNSRECORD_Block *block)
Process a record that was stored in the namecache.
struct GNUNET_NAMECACHE_QueueEntry * GNUNET_NAMECACHE_lookup_block(struct GNUNET_NAMECACHE_Handle *h, const struct GNUNET_HashCode *derived_hash, GNUNET_NAMECACHE_BlockProcessor proc, void *proc_cls)
Get a result for a particular key from the namecache.

References ac, GNS_ResolverHandle::ac_tail, disable_cache, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_GNSRECORD_query_from_public_key(), GNUNET_GNSRECORD_z2s(), GNUNET_log, GNUNET_NAMECACHE_lookup_block(), GNUNET_YES, handle_namecache_block_response(), namecache_handle, GNS_ResolverHandle::namecache_qe, AuthorityChain::rh, and start_dht_request().

Referenced by handle_revocation_result().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_revocation_result()

static void handle_revocation_result ( void *  cls,
int  is_valid 
)
static

Function called with the result from a revocation check.

Parameters
clsthe struct GNS_ResovlerHandle
is_validGNUNET_YES if the zone was not yet revoked

Definition at line 2650 of file gnunet-service-gns_resolver.c.

2652 {
2653  struct GNS_ResolverHandle *rh = cls;
2654  struct AuthorityChain *ac = rh->ac_tail;
2655 
2656  rh->rev_check = NULL;
2657  if (GNUNET_YES != is_valid)
2658  {
2660  _ ("Zone %s was revoked, resolution fails\n"),
2661  GNUNET_GNSRECORD_z2s (&ac->authority_info.gns_authority));
2662  fail_resolution (rh);
2663  return;
2664  }
2666 }
static void recursive_gns_resolution_namecache(struct GNS_ResolverHandle *rh)
Lookup tail of our authority chain in the namecache.
struct GNUNET_REVOCATION_Query * rev_check
Pending revocation check.

References _, ac, GNS_ResolverHandle::ac_tail, fail_resolution(), GNUNET_ERROR_TYPE_WARNING, GNUNET_GNSRECORD_z2s(), GNUNET_log, GNUNET_YES, recursive_gns_resolution_namecache(), GNS_ResolverHandle::rev_check, and AuthorityChain::rh.

Referenced by recursive_gns_resolution_revocation().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ recursive_gns_resolution_revocation()

static void recursive_gns_resolution_revocation ( struct GNS_ResolverHandle rh)
static

Perform revocation check on tail of our authority chain.

Parameters
rhquery we are processing

Definition at line 2675 of file gnunet-service-gns_resolver.c.

2676 {
2677  struct AuthorityChain *ac = rh->ac_tail;
2678 
2680  "Starting revocation check for zone %s\n",
2681  GNUNET_GNSRECORD_z2s (&ac->authority_info.gns_authority));
2683  &ac->authority_info.gns_authority,
2685  rh);
2686  GNUNET_assert (NULL != rh->rev_check);
2687 }
static void handle_revocation_result(void *cls, int is_valid)
Function called with the result from a revocation check.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Global configuration.
struct GNUNET_REVOCATION_Query * GNUNET_REVOCATION_query(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_IDENTITY_PublicKey *key, GNUNET_REVOCATION_Callback func, void *func_cls)
Check if a key was revoked.

References ac, GNS_ResolverHandle::ac_tail, cfg, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_GNSRECORD_z2s(), GNUNET_log, GNUNET_REVOCATION_query(), handle_revocation_result(), GNS_ResolverHandle::rev_check, and AuthorityChain::rh.

Referenced by recursive_resolution().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNS_resolver_lookup()

struct GNS_ResolverHandle* GNS_resolver_lookup ( const struct GNUNET_IDENTITY_PublicKey zone,
uint32_t  record_type,
const char *  name,
enum GNUNET_GNS_LocalOptions  options,
uint16_t  recursion_depth_limit,
GNS_ResultProcessor  proc,
void *  proc_cls 
)

Lookup of a record in a specific zone calls lookup result processor on result.

Lookup of a record in a specific zone calls RecordLookupProcessor on result or timeout.

Parameters
zonethe zone to perform the lookup in
record_typethe record type to look up
namethe name to look up
optionslocal options to control local lookup
recursion_depth_limithow many zones to traverse at most
procthe processor to call on result
proc_clsthe closure to pass to proc
Returns
handle to cancel operation

Definition at line 2793 of file gnunet-service-gns_resolver.c.

2800 {
2801  struct GNS_ResolverHandle *rh;
2802 
2804  "Starting lookup for `%s'\n",
2805  name);
2806  rh = GNUNET_new (struct GNS_ResolverHandle);
2808  rlh_tail,
2809  rh);
2810  rh->authority_zone = *zone;
2811  rh->proc = proc;
2812  rh->proc_cls = proc_cls;
2813  rh->options = options;
2814  rh->record_type = record_type;
2815  rh->name = GNUNET_strdup (name);
2816  rh->name_resolution_pos = strlen (name);
2817  rh->loop_threshold = recursion_depth_limit;
2819  rh);
2820  return rh;
2821 }
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5

References GNS_ResolverHandle::authority_zone, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_new, GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNS_ResolverHandle::loop_threshold, name, GNS_ResolverHandle::name, GNS_ResolverHandle::name_resolution_pos, options, GNS_ResolverHandle::options, GNS_ResolverHandle::proc, GNS_ResolverHandle::proc_cls, GNS_ResolverHandle::record_type, rlh_head, rlh_tail, start_resolver_lookup(), GNS_ResolverHandle::task_id, and zone.

Referenced by handle_dns_request(), and handle_lookup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNS_resolver_lookup_cancel()

void GNS_resolver_lookup_cancel ( struct GNS_ResolverHandle rh)

Cancel active resolution (i.e.

client disconnected).

Parameters
rhresolution to abort

Definition at line 2830 of file gnunet-service-gns_resolver.c.

2831 {
2832  struct DnsResult *dr;
2833  struct AuthorityChain *ac;
2834 
2836  rlh_tail,
2837  rh);
2838  if (NULL != rh->dns_request)
2839  {
2841  rh->dns_request = NULL;
2842  }
2843  while (NULL != (ac = rh->ac_head))
2844  {
2846  rh->ac_tail,
2847  ac);
2848  if (GNUNET_NO == ac->gns_authority)
2849  {
2850  struct Gns2DnsPending *gp;
2851 
2852  while (NULL != (gp = ac->authority_info.dns_authority.gp_head))
2853  {
2854  GNUNET_CONTAINER_DLL_remove (ac->authority_info.dns_authority.gp_head,
2855  ac->authority_info.dns_authority.gp_tail,
2856  gp);
2857  if (NULL != gp->rh)
2858  {
2859  /* rh->g2dc->rh is NOT in the DLL yet, so to enable us
2860  using GNS_resolver_lookup_cancel here, we need to
2861  add it first... */
2863  rlh_tail,
2864  gp->rh);
2865  GNUNET_assert (NULL == gp->rh->task_id);
2868  gp->rh);
2869  gp->rh = NULL;
2870  }
2871  if (NULL != gp->dns_rh)
2872  {
2874  gp->dns_rh = NULL;
2875  }
2876  GNUNET_free (gp);
2877  }
2878  GNUNET_DNSSTUB_stop (ac->authority_info.dns_authority.dns_handle);
2879  }
2880  GNUNET_free (ac->label);
2881  GNUNET_free (ac);
2882  }
2883  if (NULL != rh->task_id)
2884  {
2886  rh->task_id = NULL;
2887  }
2888  if (NULL != rh->get_handle)
2889  {
2891  rh->get_handle = NULL;
2892  }
2893  if (NULL != rh->dht_heap_node)
2894  {
2896  rh->dht_heap_node = NULL;
2897  }
2898  if (NULL != rh->namecache_qe)
2899  {
2901  rh->namecache_qe = NULL;
2902  }
2903  if (NULL != rh->rev_check)
2904  {
2906  rh->rev_check = NULL;
2907  }
2908  if (NULL != rh->std_resolve)
2909  {
2911  "Canceling standard DNS resolution\n");
2913  rh->std_resolve = NULL;
2914  }
2915  while (NULL != (dr = rh->dns_result_head))
2916  {
2919  dr);
2920  GNUNET_free (dr);
2921  }
2922  GNUNET_free (rh->leho);
2923  GNUNET_free (rh->name);
2924  GNUNET_free (rh);
2925 }
void GNUNET_DNSSTUB_stop(struct GNUNET_DNSSTUB_Context *ctx)
Cleanup DNSSTUB resolver.
Definition: dnsstub.c:705
void GNUNET_NAMECACHE_cancel(struct GNUNET_NAMECACHE_QueueEntry *qe)
Cancel a namecache operation.
void GNUNET_REVOCATION_query_cancel(struct GNUNET_REVOCATION_Query *q)
Cancel key revocation check.

References ac, GNS_ResolverHandle::ac_head, GNS_ResolverHandle::ac_tail, GNS_ResolverHandle::dht_heap_node, GNS_ResolverHandle::dns_request, GNS_ResolverHandle::dns_result_head, GNS_ResolverHandle::dns_result_tail, Gns2DnsPending::dns_rh, GNS_ResolverHandle::get_handle, GNS_resolver_lookup_cancel_(), GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_heap_remove_node(), GNUNET_DHT_get_stop(), GNUNET_DNSSTUB_resolve_cancel(), GNUNET_DNSSTUB_stop(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_NAMECACHE_cancel(), GNUNET_NO, GNUNET_RESOLVER_request_cancel(), GNUNET_REVOCATION_query_cancel(), GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNS_ResolverHandle::leho, GNS_ResolverHandle::name, GNS_ResolverHandle::namecache_qe, GNS_ResolverHandle::rev_check, Gns2DnsPending::rh, AuthorityChain::rh, rlh_head, rlh_tail, GNS_ResolverHandle::std_resolve, and GNS_ResolverHandle::task_id.

Referenced by client_disconnect_cb(), GNS_interceptor_done(), GNS_resolver_done(), GNS_resolver_lookup_cancel_(), and transmit_lookup_dns_result().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNS_resolver_init()

void GNS_resolver_init ( struct GNUNET_NAMECACHE_Handle nc,
struct GNUNET_DHT_Handle dht,
const struct GNUNET_CONFIGURATION_Handle c,
unsigned long long  max_bg_queries 
)

Initialize the resolver.

Initialize the resolver subsystem.

Parameters
ncthe namecache handle
dhtthe dht handle
cconfiguration handle
max_bg_queriesmaximum number of parallel background queries in dht

Definition at line 2940 of file gnunet-service-gns_resolver.c.

2944 {
2945  cfg = c;
2946  namecache_handle = nc;
2947  dht_handle = dht;
2948  dht_lookup_heap =
2950  max_allowed_background_queries = max_bg_queries;
2952  "namecache",
2953  "DISABLE");
2954  if (GNUNET_YES == disable_cache)
2956  "Namecache disabled\n");
2957 }
static struct GNUNET_DHT_Handle * dht
Handle to the DHT.
static struct GNUNET_PEERINFO_NotifyContext * nc
Iterator context.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.

References cfg, dht, dht_handle, dht_lookup_heap, disable_cache, GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CONTAINER_heap_create(), GNUNET_CONTAINER_HEAP_ORDER_MIN, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_YES, max_allowed_background_queries, namecache_handle, and nc.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNS_resolver_done()

void GNS_resolver_done ( void  )

Shutdown resolver.

Cleanup resolver: Terminate pending lookups.

Definition at line 2964 of file gnunet-service-gns_resolver.c.

2965 {
2966  struct GNS_ResolverHandle *rh;
2967  struct CacheOps *co;
2968 
2969  /* abort active resolutions */
2970  while (NULL != (rh = rlh_head))
2971  {
2972  rh->proc (rh->proc_cls,
2973  0,
2974  NULL);
2976  }
2977  while (NULL != (co = co_head))
2978  {
2980  co_tail,
2981  co);
2983  GNUNET_free (co);
2984  }
2986  dht_lookup_heap = NULL;
2987  dht_handle = NULL;
2988  namecache_handle = NULL;
2989 }
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.

References co_head, co_tail, dht_handle, dht_lookup_heap, GNS_resolver_lookup_cancel(), GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_heap_destroy(), GNUNET_free, GNUNET_NAMECACHE_cancel(), namecache_handle, CacheOps::namecache_qe_cache, GNS_ResolverHandle::proc, GNS_ResolverHandle::proc_cls, and rlh_head.

Referenced by shutdown_task().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ namecache_handle

struct GNUNET_NAMECACHE_Handle* namecache_handle
static

Our handle to the namecache service.

Definition at line 418 of file gnunet-service-gns_resolver.c.

Referenced by GNS_resolver_done(), GNS_resolver_init(), handle_dht_response(), and recursive_gns_resolution_namecache().

◆ dht_handle

struct GNUNET_DHT_Handle* dht_handle
static

Resolver handle to the dht.

Definition at line 423 of file gnunet-service-gns_resolver.c.

Referenced by GNS_resolver_done(), GNS_resolver_init(), and start_dht_request().

◆ dht_lookup_heap

struct GNUNET_CONTAINER_Heap* dht_lookup_heap
static

Heap for limiting parallel DHT lookups.

Definition at line 428 of file gnunet-service-gns_resolver.c.

Referenced by GNS_resolver_done(), GNS_resolver_init(), and start_dht_request().

◆ max_allowed_background_queries

unsigned long long max_allowed_background_queries
static

Maximum amount of parallel queries to the DHT.

Definition at line 433 of file gnunet-service-gns_resolver.c.

Referenced by GNS_resolver_init(), and start_dht_request().

◆ rlh_head

struct GNS_ResolverHandle* rlh_head
static

Head of resolver lookup list.

Definition at line 438 of file gnunet-service-gns_resolver.c.

Referenced by GNS_resolver_done(), GNS_resolver_lookup(), GNS_resolver_lookup_cancel(), and handle_gns2dns_result().

◆ rlh_tail

struct GNS_ResolverHandle* rlh_tail
static

Tail of resolver lookup list.

Definition at line 443 of file gnunet-service-gns_resolver.c.

Referenced by GNS_resolver_lookup(), GNS_resolver_lookup_cancel(), and handle_gns2dns_result().

◆ co_head

struct CacheOps* co_head
static

Organized in a DLL.

Definition at line 448 of file gnunet-service-gns_resolver.c.

Referenced by GNS_resolver_done(), handle_dht_response(), and namecache_cache_continuation().

◆ co_tail

struct CacheOps* co_tail
static

Organized in a DLL.

Definition at line 453 of file gnunet-service-gns_resolver.c.

Referenced by GNS_resolver_done(), handle_dht_response(), and namecache_cache_continuation().

◆ disable_cache

int disable_cache
static

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Global configuration.

Definition at line 463 of file gnunet-service-gns_resolver.c.

Referenced by GNS_resolver_init(), and recursive_gns_resolution_revocation().