GNUnet  0.11.x
Data Structures | Macros | Functions | Variables
gnunet-service-gns_resolver.c File Reference

GNU Name System resolver logic. More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_dnsstub_lib.h"
#include "gnunet_dht_service.h"
#include "gnunet_gnsrecord_lib.h"
#include "gnunet_namecache_service.h"
#include "gnunet_dns_service.h"
#include "gnunet_resolver_service.h"
#include "gnunet_revocation_service.h"
#include "gnunet_dnsparser_lib.h"
#include "gnunet_tun_lib.h"
#include "gnunet_gns_service.h"
#include "gns.h"
#include "gnunet-service-gns.h"
#include "gnunet-service-gns_resolver.h"
#include "gnunet_vpn_service.h"
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  VpnContext
 Closure for vpn_allocation_cb. More...
 
struct  GNS_ResolverHandle
 Handle to a currenty 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 VPN_TIMEOUT   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30)
 Default timeout for VPN redirections. 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 cummulative 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_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 a records that were decrypted from a block. More...
 
static void vpn_allocation_cb (void *cls, int af, const void *address)
 Callback invoked from the VPN service once a redirection is available. 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_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 *get_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *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_CRYPTO_EcdsaPublicKey *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_VPN_Handlevpn_handle
 Our handle to the vpn 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:442

Default DHT timeout for lookups.

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

◆ DNS_LOOKUP_TIMEOUT

#define DNS_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:442

Default timeout for DNS lookups.

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

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

◆ VPN_TIMEOUT

Default timeout for VPN redirections.

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

Referenced by handle_gns_resolution_result(), and vpn_allocation_cb().

◆ DHT_GNS_REPLICATION_LEVEL

#define DHT_GNS_REPLICATION_LEVEL   10

DHT replication level.

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

Referenced by start_dht_request().

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 (i.e. _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 532 of file gnunet-service-gns_resolver.c.

References GNUNET_NO, and GNUNET_YES.

533 {
534  const char *pos;
535  const char *dot;
536 
537  if (NULL == strchr (name,
538  (unsigned char) '.'))
539  return GNUNET_YES;
540  if ('_' != name[0])
541  return GNUNET_NO;
542  pos = &name[1];
543  while (NULL != (dot = strchr (pos,
544  (unsigned char) '.')))
545  if ('_' != dot[1])
546  return GNUNET_NO;
547  else
548  pos = dot + 1;
549  return GNUNET_YES;
550 }
#define GNUNET_NO
Definition: gnunet_common.h:86
const char * name
#define GNUNET_YES
Definition: gnunet_common.h:85

◆ 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 563 of file gnunet-service-gns_resolver.c.

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().

565 {
566  char *ret;
567  size_t s_len = strlen (name);
568 
569  if (0 != strcmp (&name[s_len - 2],
570  ".+"))
571  return name; /* did not end in ".+" */
573  GNUNET_asprintf (&ret,
574  "%.*s.%s",
575  (int) (s_len - 2),
576  name,
579  GNUNET_free (name);
580  return ret;
581 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
int gns_authority
GNUNET_YES if the authority was a GNS authority, GNUNET_NO if the authority was a DNS authority...
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
struct AuthorityChain * ac_tail
DLL to store the authority chain.
const char * GNUNET_GNSRECORD_pkey_to_zkey(const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey)
Convert public key to the respective absolute domain name in the ".zkey" pTLD.
const char * name
#define GNUNET_YES
Definition: gnunet_common.h:85
union AuthorityChain::@19 authority_info
Information about the resolver authority for this label.
#define GNUNET_free(ptr)
Wrapper around free.
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 591 of file gnunet-service-gns_resolver.c.

References GNS_resolver_lookup_cancel(), Gns2DnsPending::rh, 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().

592 {
593  struct GNS_ResolverHandle *rh = cls;
594 
595  rh->task_id = NULL;
597 }
void GNS_resolver_lookup_cancel(struct GNS_ResolverHandle *rh)
Cancel active resolution (i.e.
Handle to a currenty pending resolution.
struct GNUNET_SCHEDULER_Task * task_id
ID of a task associated with the resolution process.
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 606 of file gnunet-service-gns_resolver.c.

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().

607 {
608  rh->proc (rh->proc_cls,
609  0,
610  NULL);
611  GNUNET_assert (NULL == rh->task_id);
613  rh);
614 }
static void GNS_resolver_lookup_cancel_(void *cls)
Wrapper around GNS_resolver_lookup_cancel() as a task.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
GNS_ResultProcessor proc
called when resolution phase finishes
void * proc_cls
closure passed to proc
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:1280
struct GNUNET_SCHEDULER_Task * task_id
ID of a task associated with the resolution process.
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 623 of file gnunet-service-gns_resolver.c.

References fail_resolution(), Gns2DnsPending::rh, and GNS_ResolverHandle::task_id.

Referenced by recursive_dns_resolution().

624 {
625  struct GNS_ResolverHandle *rh = cls;
626 
627  rh->task_id = NULL;
628  fail_resolution (rh);
629 }
Handle to a currenty pending resolution.
struct GNUNET_SCHEDULER_Task * task_id
ID of a task associated with the resolution process.
static void fail_resolution(struct GNS_ResolverHandle *rh)
Function called to asynchronously fail a 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

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

References _, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, 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_cname_result(), recursive_pkey_resolution(), and start_resolver_lookup().

651 {
652  const char *rp;
653  const char *dot;
654  size_t len;
655  char *ret;
656  char *srv_name;
657  char *proto_name;
658  struct protoent *pe;
659  struct servent *se;
660 
661  if (0 == rh->name_resolution_pos)
662  return NULL;
663  dot = memrchr (rh->name,
664  (int) '.',
665  rh->name_resolution_pos);
666  if (NULL == dot)
667  {
668  /* done, this was the last one */
669  len = rh->name_resolution_pos;
670  rp = rh->name;
671  rh->name_resolution_pos = 0;
672  }
673  else
674  {
675  /* advance by one label */
676  len = rh->name_resolution_pos - (dot - rh->name) - 1;
677  rp = dot + 1;
678  rh->name_resolution_pos = dot - rh->name;
679  }
680  rh->protocol = 0;
681  rh->service = 0;
682  ret = GNUNET_strndup (rp, len);
683  /* If we have labels starting with underscore with label on
684  * the right (SRV/DANE/BOX case), determine port/protocol;
685  * The format of `rh->name` must be "_PORT._PROTOCOL".
686  */
687  if (('_' == rh->name[0]) &&
688  (NULL != (dot = memrchr (rh->name,
689  (int) '.',
690  rh->name_resolution_pos))) &&
691  ('_' == dot[1]) &&
692  (NULL == memrchr (rh->name,
693  (int) '.',
694  dot - rh->name)))
695  {
696  srv_name = GNUNET_strndup (&rh->name[1],
697  (dot - rh->name) - 1);
698  proto_name = GNUNET_strndup (&dot[2],
699  rh->name_resolution_pos - (dot - rh->name)
700  - 2);
701  rh->name_resolution_pos = 0;
702  pe = getprotobyname (proto_name);
703  if (NULL == pe)
704  {
706  _ ("Protocol `%s' unknown, skipping labels.\n"),
707  proto_name);
708  GNUNET_free (proto_name);
709  GNUNET_free (srv_name);
710  return ret;
711  }
712  se = getservbyname (srv_name,
713  proto_name);
714  if (NULL == se)
715  {
717  _ (
718  "Service `%s' unknown for protocol `%s', trying as number.\n"),
719  srv_name,
720  proto_name);
721  if (1 != sscanf (srv_name, "%u", &rh->service))
722  {
724  _ ("Service `%s' not a port, skipping service labels.\n"),
725  srv_name);
726  GNUNET_free (proto_name);
727  GNUNET_free (srv_name);
728  return ret;
729  }
730  }
731  else
732  {
733  rh->service = se->s_port;
734  }
735  rh->protocol = pe->p_proto;
736  GNUNET_free (proto_name);
737  GNUNET_free (srv_name);
738  }
739  return ret;
740 }
#define memrchr(s, c, n)
Definition: compat.h:49
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
char * name
The name to resolve.
#define _(String)
GNU gettext support macro.
Definition: platform.h:180
int service
For SRV and TLSA records, the number of the service specified in the name.
int protocol
For SRV and TLSA records, the number of the protocol specified in the name.
size_t name_resolution_pos
Current offset in name where we are resolving.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
#define GNUNET_log(kind,...)
static char * rp
Relying party.
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
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 cummulative result obtained to the callback and clean up the request.

Parameters
rhresolution process that has culminated in a result

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

References GNUNET_GNSRECORD_Data::data, DnsResult::data, GNUNET_GNSRECORD_Data::data_size, DnsResult::data_size, GNS_ResolverHandle::dns_result_head, GNUNET_GNSRECORD_Data::expiration_time, DnsResult::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_log, DnsResult::next, GNS_ResolverHandle::proc, GNS_ResolverHandle::proc_cls, GNUNET_GNSRECORD_Data::record_type, and DnsResult::record_type.

Referenced by handle_dns_result().

750 {
751  struct DnsResult *pos;
752  unsigned int n;
753  unsigned int i;
754 
755  n = 0;
756  for (pos = rh->dns_result_head; NULL != pos; pos = pos->next)
757  n++;
758  {
759  struct GNUNET_GNSRECORD_Data rd[n];
760 
761  i = 0;
762  for (pos = rh->dns_result_head; NULL != pos; pos = pos->next)
763  {
764  rd[i].data = pos->data;
765  rd[i].data_size = pos->data_size;
766  rd[i].record_type = pos->record_type;
767  if (0 == pos->expiration_time)
768  {
770  rd[i].expiration_time = 0;
771  }
772  else
773  {
774  rd[i].flags = GNUNET_GNSRECORD_RF_NONE;
775  rd[i].expiration_time = pos->expiration_time;
776  }
777  i++;
778  }
779  GNUNET_assert (i == n);
781  "Transmitting standard DNS result with %u records\n",
782  n);
783  rh->proc (rh->proc_cls,
784  n,
785  rd);
786  }
788 }
void GNS_resolver_lookup_cancel(struct GNS_ResolverHandle *rh)
Cancel active resolution (i.e.
size_t data_size
Number of bytes in data.
uint64_t expiration_time
Expiration time for the DNS record, 0 if we didn't get anything useful (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
GNS_ResultProcessor proc
called when resolution phase finishes
void * proc_cls
closure passed to proc
uint32_t record_type
Type of the GNS/DNS record.
const void * data
Binary value stored in the DNS record (appended to this struct)
const void * data
Binary value stored in the DNS record.
A result we got from DNS.
struct DnsResult * next
Kept in DLL.
#define GNUNET_log(kind,...)
This flag is currently unused; former RF_PENDING flag.
struct DnsResult * dns_result_head
DLL of results we got from DNS.
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 801 of file gnunet-service-gns_resolver.c.

References DnsResult::data, data_size, DnsResult::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().

806 {
807  struct DnsResult *res;
808 
809  res = GNUNET_malloc (sizeof(struct DnsResult) + data_size);
811  res->data_size = data_size;
812  res->record_type = record_type;
813  res->data = &res[1];
814  GNUNET_memcpy (&res[1],
815  data,
816  data_size);
818  rh->dns_result_tail,
819  res);
820 }
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
size_t data_size
Number of bytes in data.
uint64_t expiration_time
Expiration time for the DNS record, 0 if we didn't get anything useful (i.e.
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint32_t record_type
Type of the GNS/DNS record.
const void * data
Binary value stored in the DNS record (appended to this struct)
static int res
A result we got from DNS.
struct DnsResult * dns_result_tail
DLL of results we got from DNS.
uint32_t data
The data value.
#define GNUNET_malloc(size)
Wrapper around malloc.
struct DnsResult * dns_result_head
DLL of results we got from DNS.
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 832 of file gnunet-service-gns_resolver.c.

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

Referenced by dns_result_parser(), and handle_gns_cname_result().

835 {
836  struct GNS_ResolverHandle *rh = cls;
837  const struct sockaddr_in *sa4;
838  const struct sockaddr_in6 *sa6;
839 
840  if (NULL == addr)
841  {
842  rh->std_resolve = NULL;
844  return;
845  }
847  "Received %u bytes of DNS IP data\n",
848  addrlen);
849  switch (addr->sa_family)
850  {
851  case AF_INET:
852  sa4 = (const struct sockaddr_in *) addr;
853  add_dns_result (rh,
854  0 /* expiration time is unknown */,
856  sizeof(struct in_addr),
857  &sa4->sin_addr);
858  break;
859 
860  case AF_INET6:
861  sa6 = (const struct sockaddr_in6 *) addr;
862  add_dns_result (rh,
863  0 /* expiration time is unknown */,
865  sizeof(struct in6_addr),
866  &sa6->sin6_addr);
867  break;
868 
869  default:
870  GNUNET_break (0);
871  break;
872  }
873 }
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Handle to a currenty pending resolution.
struct GNUNET_RESOLVER_RequestHandle * std_resolve
Handle for standard DNS resolution, NULL if none is active.
static void transmit_lookup_dns_result(struct GNS_ResolverHandle *rh)
Gives the cummulative result obtained to the callback and clean up the request.
#define GNUNET_DNSPARSER_TYPE_AAAA
#define GNUNET_log(kind,...)
#define GNUNET_DNSPARSER_TYPE_A
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.
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
tctask context
clsthe struct GNS_ResolverHandle of the resolution

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

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(), Gns2DnsPending::rh, and GNS_ResolverHandle::task_id.

Referenced by continue_with_gns2dns(), handle_dns_result(), handle_gns_cname_result(), handle_gns_resolution_result(), recursive_pkey_resolution(), and start_resolver_lookup().

2744 {
2745  struct GNS_ResolverHandle *rh = cls;
2746 
2747  rh->task_id = NULL;
2748  if (rh->loop_threshold < rh->loop_limiter++)
2749  {
2751  "Encountered unbounded recursion resolving `%s'\n",
2752  rh->name);
2753  fail_resolution (rh);
2754  return;
2755  }
2756  if (GNUNET_YES == rh->ac_tail->gns_authority)
2758  else
2760 }
static void recursive_gns_resolution_revocation(struct GNS_ResolverHandle *rh)
Perform revocation check on tail of our authority chain.
unsigned int loop_threshold
Maximum value of loop_limiter allowed by client.
char * name
The name to resolve.
int gns_authority
GNUNET_YES if the authority was a GNS authority, GNUNET_NO if the authority was a DNS authority...
Handle to a currenty pending resolution.
struct AuthorityChain * ac_tail
DLL to store the authority chain.
struct GNUNET_SCHEDULER_Task * task_id
ID of a task associated with the resolution process.
static void fail_resolution(struct GNS_ResolverHandle *rh)
Function called to asynchronously fail a resolution.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:85
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.
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
clsthe struct GNS_ResolverHandle

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

References Gns2DnsPending::ac, GNS_ResolverHandle::ac_head, GNS_ResolverHandle::ac_tail, AuthorityChain::authority_info, GNS_ResolverHandle::authority_zone, GNUNET_GNSRECORD_Data::data, GNUNET_GNSRECORD_Data::data_size, GNUNET_GNSRECORD_Data::expiration_time, GNUNET_GNSRECORD_Data::flags, AuthorityChain::gns_authority, 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, AuthorityChain::label, GNS_ResolverHandle::name, GNS_ResolverHandle::proc, GNS_ResolverHandle::proc_cls, GNUNET_GNSRECORD_Data::record_type, recursive_resolution(), resolver_lookup_get_next_label(), Gns2DnsPending::rh, AuthorityChain::rh, and GNS_ResolverHandle::task_id.

Referenced by GNS_resolver_lookup(), handle_dns_result(), and recursive_gns2dns_resolution().

2771 {
2772  struct GNS_ResolverHandle *rh = cls;
2773  struct AuthorityChain *ac;
2774  struct in_addr v4;
2775  struct in6_addr v6;
2776 
2777  rh->task_id = NULL;
2778  if (1 == inet_pton (AF_INET,
2779  rh->name,
2780  &v4))
2781  {
2782  /* name is IPv4 address, pretend it's an A record */
2783  struct GNUNET_GNSRECORD_Data rd;
2784 
2785  rd.data = &v4;
2786  rd.data_size = sizeof(v4);
2787  rd.expiration_time = UINT64_MAX;
2788  rd.record_type = GNUNET_DNSPARSER_TYPE_A;
2789  rd.flags = 0;
2790  rh->proc (rh->proc_cls,
2791  1,
2792  &rd);
2793  GNUNET_assert (NULL == rh->task_id);
2795  rh);
2796  return;
2797  }
2798  if (1 == inet_pton (AF_INET6,
2799  rh->name,
2800  &v6))
2801  {
2802  /* name is IPv6 address, pretend it's an AAAA record */
2803  struct GNUNET_GNSRECORD_Data rd;
2804 
2805  rd.data = &v6;
2806  rd.data_size = sizeof(v6);
2807  rd.expiration_time = UINT64_MAX;
2808  rd.record_type = GNUNET_DNSPARSER_TYPE_AAAA;
2809  rd.flags = 0;
2810  rh->proc (rh->proc_cls,
2811  1,
2812  &rd);
2813  GNUNET_assert (NULL == rh->task_id);
2815  rh);
2816  return;
2817  }
2818 
2819  ac = GNUNET_new (struct AuthorityChain);
2820  ac->rh = rh;
2822  if (NULL == ac->label)
2823  /* name was just the "TLD", so we default to label
2824  #GNUNET_GNS_EMPTY_LABEL_AT */
2826  ac->gns_authority = GNUNET_YES;
2829  rh->ac_tail,
2830  ac);
2832  rh);
2833 }
static void recursive_resolution(void *cls)
Task scheduled to continue with the resolution process.
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
static void GNS_resolver_lookup_cancel_(void *cls)
Wrapper around GNS_resolver_lookup_cancel() as a task.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
char * label
label/name corresponding to the authority
GNS_ResultProcessor proc
called when resolution phase finishes
#define GNUNET_new(type)
Allocate a struct or union of the given type.
char * name
The name to resolve.
int gns_authority
GNUNET_YES if the authority was a GNS authority, GNUNET_NO if the authority was a DNS authority...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct AuthorityChain * ac_head
DLL to store the authority chain.
Handle to a currenty pending resolution.
void * proc_cls
closure passed to proc
const void * data
Binary value stored in the DNS record.
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 ...
struct AuthorityChain * ac_tail
DLL to store the authority chain.
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:1280
struct GNS_ResolverHandle * rh
Resolver handle this entry in the chain belongs to.
DLL to hold the authority chain we had to pass in the resolution process.
struct GNUNET_SCHEDULER_Task * task_id
ID of a task associated with the resolution process.
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
struct GNUNET_CRYPTO_EcdsaPublicKey authority_zone
The top-level GNS authoritative zone to query.
#define GNUNET_DNSPARSER_TYPE_AAAA
#define GNUNET_YES
Definition: gnunet_common.h:85
union AuthorityChain::@19 authority_info
Information about the resolver authority for this label.
#define GNUNET_DNSPARSER_TYPE_A
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 905 of file gnunet-service-gns_resolver.c.

References _, GNUNET_TIME_Absolute::abs_value_us, GNS_ResolverHandle::ac_tail, add_dns_result(), GNUNET_DNSPARSER_Packet::additional_records, GNUNET_DNSPARSER_Packet::answers, GNUNET_DNSPARSER_Packet::authority_records, buf, GNUNET_GNSRECORD_Data::data, GNUNET_DNSPARSER_RawRecord::data, GNUNET_DNSPARSER_Record::data, GNUNET_DNSPARSER_RawRecord::data_len, GNUNET_GNSRECORD_Data::data_size, DNS_LOOKUP_TIMEOUT, GNS_ResolverHandle::dns_request, GNUNET_GNSRECORD_Data::expiration_time, GNUNET_DNSPARSER_Record::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_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, GNUNET_DNSPARSER_Packet::num_additional_records, GNUNET_DNSPARSER_Packet::num_answers, GNUNET_DNSPARSER_Packet::num_authority_records, GNS_ResolverHandle::original_dns_id, p, GNS_ResolverHandle::proc, GNS_ResolverHandle::proc_cls, GNUNET_DNSPARSER_Record::raw, GNUNET_GNSRECORD_Data::record_type, GNS_ResolverHandle::record_type, Gns2DnsPending::rh, 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().

908 {
909  struct GNS_ResolverHandle *rh = cls;
910  struct GNUNET_DNSPARSER_Packet *p;
911  const struct GNUNET_DNSPARSER_Record *rec;
912  unsigned int rd_count;
913 
914  if (NULL == dns)
915  {
916  rh->dns_request = NULL;
918  rh->task_id = NULL;
919  fail_resolution (rh);
920  return;
921  }
922  if (rh->original_dns_id != dns->id)
923  {
924  /* DNS answer, but for another query */
925  return;
926  }
927  p = GNUNET_DNSPARSER_parse ((const char *) dns,
928  dns_len);
929  if (NULL == p)
930  {
932  _ ("Failed to parse DNS response\n"));
933  return;
934  }
935 
936  /* We got a result from DNS */
938  "Received DNS response for `%s' with %u answers\n",
939  rh->ac_tail->label,
940  (unsigned int) p->num_answers);
941  if ((p->num_answers > 0) &&
944  {
945  int af;
946 
948  "Got CNAME `%s' from DNS for `%s'\n",
949  p->answers[0].data.hostname,
950  rh->name);
951  if (NULL != rh->std_resolve)
952  {
954  "Multiple CNAME results from DNS resolving `%s'! Not really allowed...\n",
955  rh->name);
957  }
958  GNUNET_free (rh->name);
959  rh->name = GNUNET_strdup (p->answers[0].data.hostname);
960  rh->name_resolution_pos = strlen (rh->name);
961  switch (rh->record_type)
962  {
964  af = AF_INET;
965  break;
966 
968  af = AF_INET6;
969  break;
970 
971  default:
972  af = AF_UNSPEC;
973  break;
974  }
975  if (NULL != rh->leho)
976  add_dns_result (rh,
977  GNUNET_TIME_UNIT_HOURS.rel_value_us,
979  strlen (rh->leho),
980  rh->leho);
982  af,
985  rh);
988  rh->dns_request = NULL;
989  return;
990  }
991 
992  /* convert from (parsed) DNS to (binary) GNS format! */
993  rd_count = p->num_answers + p->num_authority_records
995  {
996  struct GNUNET_GNSRECORD_Data rd[rd_count + 1]; /* +1 for LEHO */
997  int skip;
998  char buf[UINT16_MAX];
999  size_t buf_off;
1000  size_t buf_start;
1001 
1002  buf_off = 0;
1003  skip = 0;
1004  memset (rd,
1005  0,
1006  sizeof(rd));
1007  for (unsigned int i = 0; i < rd_count; i++)
1008  {
1009  if (i < p->num_answers)
1010  rec = &p->answers[i];
1011  else if (i < p->num_answers + p->num_authority_records)
1012  rec = &p->authority_records[i - p->num_answers];
1013  else
1014  rec = &p->additional_records[i - p->num_answers
1015  - p->num_authority_records];
1016  /* As we copied the full DNS name to 'rh->ac_tail->label', this
1017  should be the correct check to see if this record is actually
1018  a record for our label... */
1019  if (0 != strcmp (rec->name,
1020  rh->ac_tail->label))
1021  {
1023  "Dropping record `%s', does not match desired name `%s'\n",
1024  rec->name,
1025  rh->ac_tail->label);
1026  skip++;
1027  continue;
1028  }
1029  rd[i - skip].record_type = rec->type;
1030  rd[i - skip].expiration_time = rec->expiration_time.abs_value_us;
1031  switch (rec->type)
1032  {
1034  if (rec->data.raw.data_len != sizeof(struct in_addr))
1035  {
1036  GNUNET_break_op (0);
1037  skip++;
1038  continue;
1039  }
1040  rd[i - skip].data_size = rec->data.raw.data_len;
1041  rd[i - skip].data = rec->data.raw.data;
1042  break;
1043 
1045  if (rec->data.raw.data_len != sizeof(struct in6_addr))
1046  {
1047  GNUNET_break_op (0);
1048  skip++;
1049  continue;
1050  }
1051  rd[i - skip].data_size = rec->data.raw.data_len;
1052  rd[i - skip].data = rec->data.raw.data;
1053  break;
1054 
1058  buf_start = buf_off;
1059  if (GNUNET_OK !=
1061  sizeof(buf),
1062  &buf_off,
1063  rec->data.hostname))
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.soa))
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 
1090  buf_start = buf_off;
1091  if (GNUNET_OK !=
1093  sizeof(buf),
1094  &buf_off,
1095  rec->data.mx))
1096  {
1097  GNUNET_break (0);
1098  skip++;
1099  continue;
1100  }
1101  rd[i - skip].data_size = buf_off - buf_start;
1102  rd[i - skip].data = &buf[buf_start];
1103  break;
1104 
1106  buf_start = buf_off;
1107  if (GNUNET_OK !=
1109  sizeof(buf),
1110  &buf_off,
1111  rec->data.srv))
1112  {
1113  GNUNET_break (0);
1114  skip++;
1115  continue;
1116  }
1117  rd[i - skip].data_size = buf_off - buf_start;
1118  rd[i - skip].data = &buf[buf_start];
1119  break;
1120 
1121  default:
1123  _ ("Skipping record of unsupported type %d\n"),
1124  rec->type);
1125  skip++;
1126  continue;
1127  }
1128  } /* end of for all records in answer */
1129  if (NULL != rh->leho)
1130  {
1131  rd[rd_count - skip].record_type = GNUNET_GNSRECORD_TYPE_LEHO;
1132  rd[rd_count - skip].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1133  rd[rd_count - skip].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us;
1134  rd[rd_count - skip].data = rh->leho;
1135  rd[rd_count - skip].data_size = strlen (rh->leho);
1136  skip--; /* skip one LESS */
1138  "Adding LEHO %s\n",
1139  rh->leho);
1140  }
1142  "Returning DNS response for `%s' with %u answers\n",
1143  rh->ac_tail->label,
1144  (unsigned int) (rd_count - skip));
1145  rh->proc (rh->proc_cls,
1146  rd_count - skip,
1147  rd);
1149  rh->dns_request = NULL;
1150  }
1152  if (NULL != rh->task_id)
1153  GNUNET_SCHEDULER_cancel (rh->task_id); /* should be timeout task */
1155  rh);
1156 }
struct GNUNET_DNSPARSER_Record * answers
Array of all answers in the packet, must contain "num_answers" entries.
uint16_t type
See GNUNET_DNSPARSER_TYPE_*.
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
#define GNUNET_TIME_UNIT_HOURS
One hour.
#define GNUNET_DNSPARSER_TYPE_CNAME
struct GNUNET_DNSPARSER_SrvRecord * srv
SRV data for SRV records.
static void handle_dns_result(void *cls, const struct sockaddr *addr, socklen_t addrlen)
We had to do a DNS lookup.
static void GNS_resolver_lookup_cancel_(void *cls)
Wrapper around GNS_resolver_lookup_cancel() as a task.
char * label
label/name corresponding to the authority
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:1118
GNS_ResultProcessor proc
called when resolution phase finishes
void GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p)
Free memory taken by a packet.
Definition: dnsparser.c:854
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:939
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
char * name
The name to resolve.
struct GNUNET_DNSPARSER_Record * additional_records
Array of all additional answers in the packet, must contain "num_additional_records" entries...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_DNSPARSER_TYPE_MX
unsigned int num_answers
Number of answers in the packet, should be 0 for queries.
uint64_t abs_value_us
The actual value.
uint16_t id
Unique identifier for the request/response.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Handle to a currenty pending resolution.
void * proc_cls
closure passed to proc
#define _(String)
GNU gettext support macro.
Definition: platform.h:180
#define GNUNET_DNSPARSER_TYPE_PTR
#define GNUNET_DNSPARSER_TYPE_SOA
char * name
Name of the record that the query is for (0-terminated).
char * hostname
For NS, CNAME and PTR records, this is the uncompressed 0-terminated hostname.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
struct GNUNET_DNSPARSER_SoaRecord * soa
SOA data for SOA records.
unsigned int num_additional_records
Number of additional records in the packet, should be 0 for queries.
struct GNUNET_RESOLVER_RequestHandle * std_resolve
Handle for standard DNS resolution, NULL if none is active.
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
struct AuthorityChain * ac_tail
DLL to store the authority chain.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
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:1280
int record_type
Desired type for the resolution.
static char buf[2048]
union GNUNET_DNSPARSER_Record::@24 data
Payload of the record (which one of these is valid depends on the &#39;type&#39;).
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:1077
struct GNUNET_SCHEDULER_Task * task_id
ID of a task associated with the resolution process.
A DNS response record.
struct GNUNET_DNSPARSER_Record * authority_records
Array of all authority records in the packet, must contain "num_authority_records" entries...
size_t name_resolution_pos
Current offset in name where we are resolving.
#define DNS_LOOKUP_TIMEOUT
Default timeout for DNS lookups.
size_t data_len
Number of bytes in data.
void * data
Binary record data.
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:1001
unsigned int num_authority_records
Number of authoritative answers in the packet, should be 0 for queries.
struct GNUNET_DNSSTUB_RequestSocket * dns_request
Socket for a DNS request, NULL if none is active.
struct GNUNET_TIME_Absolute expiration_time
When does the record expire?
#define GNUNET_GNSRECORD_TYPE_LEHO
Record type for GNS legacy hostnames ("LEHO").
static void fail_resolution(struct GNS_ResolverHandle *rh)
Function called to asynchronously fail a resolution.
uint16_t original_dns_id
16 bit random ID we used in the dns_request.
struct GNUNET_DNSPARSER_MxRecord * mx
MX data for MX records.
#define GNUNET_DNSPARSER_TYPE_AAAA
void GNUNET_DNSSTUB_resolve_cancel(struct GNUNET_DNSSTUB_RequestSocket *rs)
Cancel DNS resolution.
Definition: dnsstub.c:540
#define GNUNET_DNSPARSER_TYPE_NS
Easy-to-process, parsed version of a DNS packet.
#define GNUNET_log(kind,...)
This flag is currently unused; former RF_PENDING flag.
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
char * leho
Legacy Hostname to use if we encountered GNS2DNS record and thus can deduct the LEHO from that transi...
#define GNUNET_DNSPARSER_TYPE_SRV
struct GNUNET_DNSPARSER_RawRecord raw
Raw data for all other types.
#define GNUNET_DNSPARSER_TYPE_A
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_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
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 1168 of file gnunet-service-gns_resolver.c.

References Gns2DnsPending::ac, GNS_ResolverHandle::ac_tail, AuthorityChain::authority_info, AuthorityChain::dns_authority, DNS_LOOKUP_TIMEOUT, GNS_ResolverHandle::dns_request, dns_result_parser(), GNUNET_DNSPARSER_Query::dns_traffic_class, GNUNET_DNSPARSER_Packet::flags, AuthorityChain::gns_authority, 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, GNUNET_DNSPARSER_Packet::id, AuthorityChain::label, GNS_ResolverHandle::leho, GNUNET_DNSPARSER_Query::name, GNUNET_DNSPARSER_Packet::num_queries, GNUNET_TUN_DnsFlags::opcode, GNS_ResolverHandle::original_dns_id, p, GNS_ResolverHandle::proc, GNS_ResolverHandle::proc_cls, GNUNET_DNSPARSER_Packet::queries, GNS_ResolverHandle::record_type, GNUNET_TUN_DnsFlags::recursion_desired, ret, GNS_ResolverHandle::task_id, timeout_resolution(), and GNUNET_DNSPARSER_Query::type.

Referenced by recursive_resolution().

1169 {
1170  struct AuthorityChain *ac;
1171  struct GNUNET_DNSPARSER_Query *query;
1172  struct GNUNET_DNSPARSER_Packet *p;
1173  char *dns_request;
1174  size_t dns_request_length;
1175  int ret;
1176 
1177  ac = rh->ac_tail;
1178  GNUNET_assert (NULL != ac);
1180  "Starting DNS lookup for `%s'\n",
1181  ac->label);
1183  query = GNUNET_new (struct GNUNET_DNSPARSER_Query);
1184  query->name = GNUNET_strdup (ac->label);
1185  query->type = rh->record_type;
1187  p = GNUNET_new (struct GNUNET_DNSPARSER_Packet);
1188  p->queries = query;
1189  p->num_queries = 1;
1191  UINT16_MAX);
1193  p->flags.recursion_desired = 1;
1194  ret = GNUNET_DNSPARSER_pack (p,
1195  1024,
1196  &dns_request,
1197  &dns_request_length);
1198  if (GNUNET_OK != ret)
1199  {
1200  GNUNET_break (0);
1201  rh->proc (rh->proc_cls,
1202  0,
1203  NULL);
1204  GNUNET_assert (NULL == rh->task_id);
1206  rh);
1207  }
1208  else
1209  {
1210  rh->original_dns_id = p->id;
1211  GNUNET_assert (NULL != ac->authority_info.dns_authority.dns_handle);
1212  GNUNET_assert (NULL == rh->dns_request);
1213  rh->leho = GNUNET_strdup (ac->label);
1215  ac->authority_info.dns_authority.dns_handle,
1216  dns_request,
1217  dns_request_length,
1219  rh);
1222  rh);
1223  }
1224  if (GNUNET_SYSERR != ret)
1225  GNUNET_free (dns_request);
1227 }
uint16_t type
See GNUNET_DNSPARSER_TYPE_*.
static void GNS_resolver_lookup_cancel_(void *cls)
Wrapper around GNS_resolver_lookup_cancel() as a task.
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.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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:1257
char * label
label/name corresponding to the authority
uint16_t id
DNS ID (to match replies to requests).
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
GNS_ResultProcessor proc
called when resolution phase finishes
void GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p)
Free memory taken by a packet.
Definition: dnsparser.c:854
#define GNUNET_NO
Definition: gnunet_common.h:86
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
#define GNUNET_new(type)
Allocate a struct or union of the given type.
int gns_authority
GNUNET_YES if the authority was a GNS authority, GNUNET_NO if the authority was a DNS authority...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void * proc_cls
closure passed to proc
uint16_t dns_traffic_class
See GNUNET_TUN_DNS_CLASS_*.
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:1253
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
struct AuthorityChain * ac_tail
DLL to store the authority chain.
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:1280
int record_type
Desired type for the resolution.
Randomness for IVs etc.
unsigned int recursion_desired
Set to 1 if recursion is desired (client -> server)
DLL to hold the authority chain we had to pass in the resolution process.
unsigned int opcode
See GNUNET_TUN_DNS_OPCODE_ defines.
struct GNUNET_SCHEDULER_Task * task_id
ID of a task associated with the resolution process.
struct GNUNET_DNSPARSER_Query * queries
Array of all queries in the packet, must contain "num_queries" entries.
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:504
#define DNS_LOOKUP_TIMEOUT
Default timeout for DNS lookups.
#define GNUNET_SYSERR
Definition: gnunet_common.h:84
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
#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&#39;r...
struct GNUNET_DNSSTUB_RequestSocket * dns_request
Socket for a DNS request, NULL if none is active.
uint16_t original_dns_id
16 bit random ID we used in the dns_request.
Easy-to-process, parsed version of a DNS packet.
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.
#define GNUNET_log(kind,...)
char * name
Name of the record that the query is for (0-terminated).
#define GNUNET_TUN_DNS_OPCODE_QUERY
unsigned int num_queries
Number of queries in the packet.
union AuthorityChain::@19 authority_info
Information about the resolver authority for this label.
struct GNUNET_TUN_DnsFlags flags
Bitfield of DNS flags.
char * leho
Legacy Hostname to use if we encountered GNS2DNS record and thus can deduct the LEHO from that transi...
struct AuthorityChain::@19::@20 dns_authority
#define GNUNET_free(ptr)
Wrapper around free.
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 1239 of file gnunet-service-gns_resolver.c.

References Gns2DnsPending::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(), handle_gns_resolution_result(), AuthorityChain::label, GNS_ResolverHandle::name, GNS_ResolverHandle::name_resolution_pos, GNS_ResolverHandle::record_type, recursive_resolution(), res, resolver_lookup_get_next_label(), Gns2DnsPending::rh, AuthorityChain::rh, GNS_ResolverHandle::std_resolve, GNS_ResolverHandle::task_id, and zone.

Referenced by handle_gns_resolution_result(), and recursive_cname_resolution().

1241 {
1242  size_t nlen;
1243  char *res;
1244  const char *tld;
1245  struct AuthorityChain *ac;
1246  int af;
1248 
1249  nlen = strlen (cname);
1250  tld = GNS_get_tld (cname);
1251  if (0 == strcmp ("+", tld))
1252  {
1253  /* CNAME resolution continues relative to current domain */
1254  if (0 == rh->name_resolution_pos)
1255  {
1256  res = GNUNET_strndup (cname, nlen - 2);
1257  rh->name_resolution_pos = nlen - 2;
1258  }
1259  else
1260  {
1261  GNUNET_asprintf (&res,
1262  "%.*s.%.*s",
1263  (int) rh->name_resolution_pos,
1264  rh->name,
1265  (int) (nlen - 2),
1266  cname);
1267  rh->name_resolution_pos = strlen (res);
1268  }
1269  GNUNET_free (rh->name);
1270  rh->name = res;
1271  ac = GNUNET_new (struct AuthorityChain);
1272  ac->rh = rh;
1273  ac->gns_authority = GNUNET_YES;
1277  /* add AC to tail */
1279  rh->ac_tail,
1280  ac);
1282  rh);
1283  return;
1284  }
1286  {
1287  /* CNAME resolution continues relative to current domain */
1288  if (0 == rh->name_resolution_pos)
1289  {
1290  GNUNET_asprintf (&res,
1291  "%.*s",
1292  strlen (cname) - (strlen (tld) + 1),
1293  cname);
1294  }
1295  else
1296  {
1297  GNUNET_asprintf (&res,
1298  "%.*s.%.*s",
1299  (int) rh->name_resolution_pos,
1300  rh->name,
1301  (int) strlen (cname) - (strlen (tld) + 1),
1302  cname);
1303  }
1304  rh->name_resolution_pos = strlen (res);
1305  GNUNET_free (rh->name);
1306  rh->name = res;
1307  ac = GNUNET_new (struct AuthorityChain);
1308  ac->rh = rh;
1309  ac->gns_authority = GNUNET_YES;
1312  /* add AC to tail */
1314  rh->ac_tail,
1315  ac);
1317  rh);
1318  return;
1319  }
1320 
1322  "Got CNAME `%s' from GNS for `%s'\n",
1323  cname,
1324  rh->name);
1325  if (NULL != rh->std_resolve)
1326  {
1328  "Multiple CNAME results from GNS resolving `%s'! Not really allowed...\n",
1329  rh->name);
1331  }
1332  /* name is absolute, go to DNS */
1333  GNUNET_free (rh->name);
1334  rh->name = GNUNET_strdup (cname);
1335  rh->name_resolution_pos = strlen (rh->name);
1336  switch (rh->record_type)
1337  {
1339  af = AF_INET;
1340  break;
1341 
1343  af = AF_INET6;
1344  break;
1345 
1346  default:
1347  af = AF_UNSPEC;
1348  break;
1349  }
1351  "Doing standard DNS lookup for `%s'\n",
1352  rh->name);
1354  af,
1357  rh);
1358 }
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
static void recursive_resolution(void *cls)
Task scheduled to continue with the resolution process.
static void handle_dns_result(void *cls, const struct sockaddr *addr, socklen_t addrlen)
We had to do a DNS lookup.
const char * GNS_get_tld(const char *name)
Obtain the TLD of the given name.
char * label
label/name corresponding to the authority
int GNUNET_GNSRECORD_zkey_to_pkey(const char *zkey, struct GNUNET_CRYPTO_EcdsaPublicKey *pkey)
Convert an absolute domain name to the respective public key.
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:939
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
#define GNUNET_new(type)
Allocate a struct or union of the given type.
char * name
The name to resolve.
int gns_authority
GNUNET_YES if the authority was a GNS authority, GNUNET_NO if the authority was a DNS authority...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct AuthorityChain * ac_head
DLL to store the authority chain.
static char * zone
Name of the zone we manage.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
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 ...
struct GNUNET_RESOLVER_RequestHandle * std_resolve
Handle for standard DNS resolution, NULL if none is active.
struct AuthorityChain * ac_tail
DLL to store the authority chain.
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:1280
int record_type
Desired type for the resolution.
struct GNS_ResolverHandle * rh
Resolver handle this entry in the chain belongs to.
DLL to hold the authority chain we had to pass in the resolution process.
struct GNUNET_SCHEDULER_Task * task_id
ID of a task associated with the resolution process.
static int res
size_t name_resolution_pos
Current offset in name where we are resolving.
#define DNS_LOOKUP_TIMEOUT
Default timeout for DNS lookups.
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
#define GNUNET_DNSPARSER_TYPE_AAAA
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:85
union AuthorityChain::@19 authority_info
Information about the resolver authority for this label.
#define GNUNET_DNSPARSER_TYPE_A
#define GNUNET_free(ptr)
Wrapper around free.
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 a 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
clsclosure with the struct GNS_ResolverHandle
rd_countnumber of entries in rd array
rdarray of records with data to store

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

References _, Gns2DnsPending::ac, GNS_ResolverHandle::ac_head, GNS_ResolverHandle::ac_tail, AuthorityChain::authority_info, data, GNUNET_GNSRECORD_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_free_non_null, GNUNET_GNS_EMPTY_LABEL_AT, GNUNET_GNSRECORD_records_get_size(), GNUNET_GNSRECORD_records_serialize(), GNUNET_GNSRECORD_TYPE_BOX, GNUNET_GNSRECORD_TYPE_GNS2DNS, GNUNET_GNSRECORD_TYPE_NICK, GNUNET_GNSRECORD_TYPE_PKEY, GNUNET_GNSRECORD_TYPE_VPN, GNUNET_GNSRECORD_z2s(), GNUNET_i2s(), GNUNET_log, GNUNET_malloc, GNUNET_memcpy, GNUNET_new, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_TIME_relative_to_absolute(), GNUNET_TUN_service_name_to_hash(), GNUNET_VPN_redirect_to_peer(), GNUNET_YES, handle_gns_cname_result(), AuthorityChain::label, GNUNET_DNSPARSER_SoaRecord::mname, GNUNET_DNSPARSER_MxRecord::mxhost, GNS_ResolverHandle::name, GNS_ResolverHandle::name_resolution_pos, GNUNET_TUN_GnsVpnRecord::peer, GNS_ResolverHandle::proc, GNS_ResolverHandle::proc_cls, GNUNET_TUN_GnsVpnRecord::proto, GNUNET_GNSRECORD_BoxRecord::protocol, GNS_ResolverHandle::protocol, pub, VpnContext::rd_count, VpnContext::rd_data, VpnContext::rd_data_size, GNUNET_GNSRECORD_Data::record_type, GNUNET_GNSRECORD_BoxRecord::record_type, GNS_ResolverHandle::record_type, recursive_cname_resolution(), recursive_gns2dns_resolution(), recursive_pkey_resolution(), recursive_resolution(), Gns2DnsPending::rh, AuthorityChain::rh, VpnContext::rh, GNUNET_DNSPARSER_SoaRecord::rname, GNUNET_GNSRECORD_BoxRecord::service, GNS_ResolverHandle::service, GNUNET_DNSPARSER_SrvRecord::target, GNS_ResolverHandle::task_id, translate_dot_plus(), vpn_allocation_cb(), GNS_ResolverHandle::vpn_ctx, VpnContext::vpn_request, and VPN_TIMEOUT.

Referenced by handle_dht_response(), handle_gns_cname_result(), handle_gns_namecache_resolution_result(), and vpn_allocation_cb().

1929 {
1930  struct GNS_ResolverHandle *rh = cls;
1931  char *cname;
1932  struct VpnContext *vpn_ctx;
1933  const struct GNUNET_TUN_GnsVpnRecord *vpn;
1934  const char *vname;
1935  struct GNUNET_HashCode vhash;
1936  int af;
1937  char scratch[UINT16_MAX];
1938  size_t scratch_off;
1939  size_t scratch_start;
1940  size_t off;
1941  struct GNUNET_GNSRECORD_Data rd_new[rd_count];
1942  unsigned int rd_off;
1943 
1945  "Resolution succeeded for `%s' in zone %s, got %u records\n",
1946  rh->ac_tail->label,
1948  rd_count);
1949  if (0 == rd_count)
1950  {
1952  _ ("GNS lookup failed (zero records found for `%s')\n"),
1953  rh->name);
1954  fail_resolution (rh);
1955  return;
1956  }
1957 
1958  if (0 == rh->name_resolution_pos)
1959  {
1960  /* top-level match, are we done yet? */
1961  if ((rd_count > 0) &&
1964  {
1965  off = 0;
1966  cname = GNUNET_DNSPARSER_parse_name (rd[0].data,
1967  rd[0].data_size,
1968  &off);
1969  if ((NULL == cname) ||
1970  (off != rd[0].data_size))
1971  {
1972  GNUNET_break_op (0);
1973  GNUNET_free_non_null (cname);
1974  fail_resolution (rh);
1975  return;
1976  }
1978  cname);
1979  GNUNET_free (cname);
1980  return;
1981  }
1982  /* If A/AAAA was requested, but we got a VPN
1983  record, we convert it to A/AAAA using GNUnet VPN */
1984  if ((GNUNET_DNSPARSER_TYPE_A == rh->record_type) ||
1986  {
1987  for (unsigned int i = 0; i < rd_count; i++)
1988  {
1989  switch (rd[i].record_type)
1990  {
1992  {
1993  af = (GNUNET_DNSPARSER_TYPE_A == rh->record_type) ? AF_INET :
1994  AF_INET6;
1995  if (sizeof(struct GNUNET_TUN_GnsVpnRecord) >
1996  rd[i].data_size)
1997  {
1998  GNUNET_break_op (0);
1999  fail_resolution (rh);
2000  return;
2001  }
2002  vpn = (const struct GNUNET_TUN_GnsVpnRecord *) rd[i].data;
2003  vname = (const char *) &vpn[1];
2004  if ('\0' != vname[rd[i].data_size - 1 - sizeof(struct
2006  ])
2007  {
2008  GNUNET_break_op (0);
2009  fail_resolution (rh);
2010  return;
2011  }
2013  &vhash);
2015  "Attempting VPN allocation for %s-%s (AF: %d, proto %d)\n",
2016  GNUNET_i2s (&vpn->peer),
2017  vname,
2018  (int) af,
2019  (int) ntohs (vpn->proto));
2020  vpn_ctx = GNUNET_new (struct VpnContext);
2021  rh->vpn_ctx = vpn_ctx;
2022  vpn_ctx->rh = rh;
2023  vpn_ctx->rd_data_size = GNUNET_GNSRECORD_records_get_size (rd_count,
2024  rd);
2025  if (vpn_ctx->rd_data_size < 0)
2026  {
2027  GNUNET_break_op (0);
2028  GNUNET_free (vpn_ctx);
2029  fail_resolution (rh);
2030  return;
2031  }
2032  vpn_ctx->rd_data = GNUNET_malloc ((size_t) vpn_ctx->rd_data_size);
2033  vpn_ctx->rd_count = rd_count;
2034  GNUNET_assert (vpn_ctx->rd_data_size ==
2036  rd,
2037  (size_t) vpn_ctx
2038  ->rd_data_size,
2039  vpn_ctx->rd_data));
2041  af,
2042  ntohs (
2043  vpn->proto),
2044  &vpn->peer,
2045  &vhash,
2047  VPN_TIMEOUT),
2048  &
2050  vpn_ctx);
2051  return;
2052  }
2053 
2055  {
2056  /* delegation to DNS */
2058  "Found GNS2DNS record, delegating to DNS!\n");
2059  if (GNUNET_OK ==
2061  rd_count,
2062  rd))
2063  return;
2064  else
2065  goto fail;
2066  }
2067 
2068  default:
2069  break;
2070  } /* end: switch */
2071  } /* end: for rd */
2072  } /* end: name_resolution_pos */
2073  /* convert relative names in record values to absolute names,
2074  using 'scratch' array for memory allocations */
2075  scratch_off = 0;
2076  rd_off = 0;
2077  for (unsigned int i = 0; i < rd_count; i++)
2078  {
2079  GNUNET_assert (rd_off <= i);
2080  if ((0 != rh->protocol) &&
2081  (0 != rh->service) &&
2083  continue; /* we _only_ care about boxed records */
2084 
2085  GNUNET_assert (rd_off < rd_count);
2086  rd_new[rd_off] = rd[i];
2087  /* Check if the embedded name(s) end in "+", and if so,
2088  replace the "+" with the zone at "ac_tail", changing the name
2089  to a ".ZONEKEY". The name is allocated on the 'scratch' array,
2090  so we can free it afterwards. */
2091  switch (rd[i].record_type)
2092  {
2094  {
2095  char *cname;
2096 
2097  off = 0;
2098  cname = GNUNET_DNSPARSER_parse_name (rd[i].data,
2099  rd[i].data_size,
2100  &off);
2101  if ((NULL == cname) ||
2102  (off != rd[i].data_size))
2103  {
2104  GNUNET_break_op (0); /* record not well-formed */
2105  }
2106  else
2107  {
2108  cname = translate_dot_plus (rh, cname);
2109  GNUNET_break (NULL != cname);
2110  scratch_start = scratch_off;
2111  if (GNUNET_OK !=
2113  sizeof(scratch),
2114  &scratch_off,
2115  cname))
2116  {
2117  GNUNET_break (0);
2118  }
2119  else
2120  {
2121  GNUNET_assert (rd_off < rd_count);
2122  rd_new[rd_off].data = &scratch[scratch_start];
2123  rd_new[rd_off].data_size = scratch_off - scratch_start;
2124  rd_off++;
2125  }
2126  }
2127  GNUNET_free_non_null (cname);
2128  }
2129  break;
2130 
2132  {
2133  struct GNUNET_DNSPARSER_SoaRecord *soa;
2134 
2135  off = 0;
2136  soa = GNUNET_DNSPARSER_parse_soa (rd[i].data,
2137  rd[i].data_size,
2138  &off);
2139  if ((NULL == soa) ||
2140  (off != rd[i].data_size))
2141  {
2142  GNUNET_break_op (0); /* record not well-formed */
2143  }
2144  else
2145  {
2146  soa->mname = translate_dot_plus (rh, soa->mname);
2147  soa->rname = translate_dot_plus (rh, soa->rname);
2148  scratch_start = scratch_off;
2149  if (GNUNET_OK !=
2151  sizeof(scratch),
2152  &scratch_off,
2153  soa))
2154  {
2155  GNUNET_break (0);
2156  }
2157  else
2158  {
2159  GNUNET_assert (rd_off < rd_count);
2160  rd_new[rd_off].data = &scratch[scratch_start];
2161  rd_new[rd_off].data_size = scratch_off - scratch_start;
2162  rd_off++;
2163  }
2164  }
2165  if (NULL != soa)
2167  }
2168  break;
2169 
2171  {
2172  struct GNUNET_DNSPARSER_MxRecord *mx;
2173 
2174  off = 0;
2175  mx = GNUNET_DNSPARSER_parse_mx (rd[i].data,
2176  rd[i].data_size,
2177  &off);
2178  if ((NULL == mx) ||
2179  (off != rd[i].data_size))
2180  {
2181  GNUNET_break_op (0); /* record not well-formed */
2182  }
2183  else
2184  {
2185  mx->mxhost = translate_dot_plus (rh, mx->mxhost);
2186  scratch_start = scratch_off;
2187  if (GNUNET_OK !=
2189  sizeof(scratch),
2190  &scratch_off,
2191  mx))
2192  {
2193  GNUNET_break (0);
2194  }
2195  else
2196  {
2197  GNUNET_assert (rd_off < rd_count);
2198  rd_new[rd_off].data = &scratch[scratch_start];
2199  rd_new[rd_off].data_size = scratch_off - scratch_start;
2200  rd_off++;
2201  }
2202  }
2203  if (NULL != mx)
2205  }
2206  break;
2207 
2209  {
2210  struct GNUNET_DNSPARSER_SrvRecord *srv;
2211 
2212  off = 0;
2213  srv = GNUNET_DNSPARSER_parse_srv (rd[i].data,
2214  rd[i].data_size,
2215  &off);
2216  if ((NULL == srv) ||
2217  (off != rd[i].data_size))
2218  {
2219  GNUNET_break_op (0); /* record not well-formed */
2220  }
2221  else
2222  {
2223  srv->target = translate_dot_plus (rh, srv->target);
2224  scratch_start = scratch_off;
2225  if (GNUNET_OK !=
2227  sizeof(scratch),
2228  &scratch_off,
2229  srv))
2230  {
2231  GNUNET_break (0);
2232  }
2233  else
2234  {
2235  GNUNET_assert (rd_off < rd_count);
2236  rd_new[rd_off].data = &scratch[scratch_start];
2237  rd_new[rd_off].data_size = scratch_off - scratch_start;
2238  rd_off++;
2239  }
2240  }
2241  if (NULL != srv)
2243  }
2244  break;
2245 
2247  /* ignore */
2248  break;
2249 
2251  {
2253 
2254  if (rd[i].data_size != sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey))
2255  {
2256  GNUNET_break_op (0);
2257  break;
2258  }
2259  GNUNET_memcpy (&pub,
2260  rd[i].data,
2261  rd[i].data_size);
2262  rd_off++;
2264  {
2265  /* try to resolve "@" */
2266  struct AuthorityChain *ac;
2267 
2268  ac = GNUNET_new (struct AuthorityChain);
2269  ac->rh = rh;
2270  ac->gns_authority = GNUNET_YES;
2274  rh->ac_tail,
2275  ac);
2277  rh);
2278  return;
2279  }
2280  }
2281  break;
2282 
2284  {
2285  /* delegation to DNS */
2287  {
2288  rd_off++;
2289  break; /* do not follow to DNS, we wanted the GNS2DNS record! */
2290  }
2292  "Found GNS2DNS record, delegating to DNS!\n");
2293  if (GNUNET_OK ==
2295  rd_count,
2296  rd))
2297  return;
2298  else
2299  goto fail;
2300  }
2301 
2303  {
2304  /* unbox SRV/TLSA records if a specific one was requested */
2305  if ((0 != rh->protocol) &&
2306  (0 != rh->service) &&
2307  (rd[i].data_size >= sizeof(struct GNUNET_GNSRECORD_BoxRecord)))
2308  {
2309  const struct GNUNET_GNSRECORD_BoxRecord *box;
2310 
2311  box = rd[i].data;
2312  if ((ntohs (box->protocol) == rh->protocol) &&
2313  (ntohs (box->service) == rh->service))
2314  {
2315  /* Box matches, unbox! */
2316  GNUNET_assert (rd_off < rd_count);
2317  rd_new[rd_off].record_type = ntohl (box->record_type);
2318  rd_new[rd_off].data_size -= sizeof(struct
2320  rd_new[rd_off].data = &box[1];
2321  rd_off++;
2322  }
2323  }
2324  else
2325  {
2326  /* no specific protocol/service specified, preserve all BOX
2327  records (for modern, GNS-enabled applications) */
2328  rd_off++;
2329  }
2330  break;
2331  }
2332 
2333  default:
2334  rd_off++;
2335  break;
2336  } /* end: switch */
2337  } /* end: for rd_count */
2338 
2339  /* yes, we are done, return result */
2341  "Returning GNS response for `%s' with %u answers\n",
2342  rh->ac_tail->label,
2343  rd_off);
2344  rh->proc (rh->proc_cls,
2345  rd_off,
2346  rd_new);
2348  rh);
2349  return;
2350  }
2351 
2352  switch (rd[0].record_type)
2353  {
2355  GNUNET_break_op (1 == rd_count); /* CNAME should be unique */
2357  &rd[0]);
2358  return;
2359 
2361  GNUNET_break_op (1 == rd_count); /* PKEY should be unique */
2363  &rd[0]);
2364  return;
2365 
2366  default:
2367  if (GNUNET_OK ==
2369  rd_count,
2370  rd))
2371  return;
2372  break;
2373  }
2374 fail:
2376  _ ("GNS lookup recursion failed (no delegation record found)\n"));
2377  fail_resolution (rh);
2378 }
void GNUNET_DNSPARSER_free_soa(struct GNUNET_DNSPARSER_SoaRecord *soa)
Free SOA information record.
Definition: dnsparser.c:108
static struct GNUNET_VPN_Handle * vpn_handle
Our handle to the vpn service.
Information from SOA records (RFC 1035).
Payload of GNS VPN record.
GNUNET_NETWORK_STRUCT_END ssize_t GNUNET_GNSRECORD_records_get_size(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Calculate how many bytes we will need to serialize the given records.
uint16_t service
Service of the boxed record (aka port number), in NBO.
static void vpn_allocation_cb(void *cls, int af, const void *address)
Callback invoked from the VPN service once a redirection is available.
Record type used to box up SRV and TLSA records.
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
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.
char * mname
The domainname of the name server that was the original or primary source of data for this zone...
static void recursive_resolution(void *cls)
Task scheduled to continue with the resolution process.
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
void GNUNET_DNSPARSER_free_srv(struct GNUNET_DNSPARSER_SrvRecord *srv)
Free SRV information record.
Definition: dnsparser.c:139
#define GNUNET_DNSPARSER_TYPE_CNAME
char * mxhost
Name of the mail server.
ssize_t GNUNET_GNSRECORD_records_serialize(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, size_t dest_size, char *dest)
Serialize the given records to the given destination buffer.
static void GNS_resolver_lookup_cancel_(void *cls)
Wrapper around GNS_resolver_lookup_cancel() as a task.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
char * label
label/name corresponding to the authority
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:1118
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNS_ResultProcessor proc
called when resolution phase finishes
struct GNUNET_VPN_RedirectionRequest * vpn_request
Handle to the VPN request that we were performing.
#define VPN_TIMEOUT
Default timeout for VPN redirections.
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
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
size_t data_size
Number of bytes in data.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
char * name
The name to resolve.
int gns_authority
GNUNET_YES if the authority was a GNS authority, GNUNET_NO if the authority was a DNS authority...
#define GNUNET_GNSRECORD_TYPE_BOX
Record type for a boxed record (see TLSA/SRV handling in GNS).
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_DNSPARSER_TYPE_MX
Information from MX records (RFC 1035).
#define GNUNET_GNSRECORD_TYPE_NICK
Record type for GNS nick names ("NICK").
struct AuthorityChain * ac_head
DLL to store the authority chain.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Handle to a currenty pending resolution.
void * proc_cls
closure passed to proc
#define GNUNET_GNSRECORD_TYPE_VPN
Record type for VPN resolution.
#define _(String)
GNU gettext support macro.
Definition: platform.h:180
#define GNUNET_DNSPARSER_TYPE_SOA
int service
For SRV and TLSA records, the number of the service specified in the name.
const void * data
Binary value stored in the DNS record.
#define GNUNET_GNSRECORD_TYPE_PKEY
Record type for GNS zone transfer ("PKEY").
struct AuthorityChain * ac_tail
DLL to store the authority chain.
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.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
char * target
Hostname offering the service.
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:1280
#define GNUNET_GNSRECORD_TYPE_GNS2DNS
Record type for delegation to DNS.
char * rname
A domainname which specifies the mailbox of the person responsible for this zone. ...
int record_type
Desired type for the resolution.
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
int protocol
For SRV and TLSA records, the number of the protocol specified in the name.
struct GNS_ResolverHandle * rh
Resolver handle this entry in the chain belongs to.
void GNUNET_TUN_service_name_to_hash(const char *service_name, struct GNUNET_HashCode *hc)
Hash the service name of a hosted service to the hash code that is used to identify the service on th...
Definition: regex.c:814
DLL to hold the authority chain we had to pass in the resolution process.
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:1077
uint16_t protocol
Protocol of the boxed record (6 = TCP, 17 = UDP, etc.).
struct GNUNET_SCHEDULER_Task * task_id
ID of a task associated with the resolution process.
A 512-bit hashcode.
const char * GNUNET_GNSRECORD_z2s(const struct GNUNET_CRYPTO_EcdsaPublicKey *z)
Convert a zone key to a string (for printing debug messages).
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
size_t name_resolution_pos
Current offset in name where we are resolving.
struct GNUNET_VPN_RedirectionRequest * GNUNET_VPN_redirect_to_peer(struct GNUNET_VPN_Handle *vh, int result_af, uint8_t protocol, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HashCode *serv, struct GNUNET_TIME_Absolute expiration_time, GNUNET_VPN_AllocationCallback cb, void *cb_cls)
Tell the VPN that a forwarding to a particular peer offering a particular service is requested...
Definition: vpn_api.c:410
struct GNUNET_PeerIdentity peer
The peer to contact.
uint16_t proto
The protocol to use.
struct GNS_ResolverHandle * rh
Which resolution process are we processing.
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:1001
struct VpnContext * vpn_ctx
Handle to a VPN request, NULL if none is active.
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
uint32_t record_type
GNS record type of the boxed record.
char * rd_data
Serialized records.
static char * translate_dot_plus(struct GNS_ResolverHandle *rh, char *name)
Expands a name ending in .
static void fail_resolution(struct GNS_ResolverHandle *rh)
Function called to asynchronously fail a resolution.
static void handle_gns_cname_result(struct GNS_ResolverHandle *rh, const char *cname)
We encountered a CNAME record during our resolution.
uint32_t record_type
Type of the GNS/DNS record.
#define GNUNET_DNSPARSER_TYPE_AAAA
Closure for vpn_allocation_cb.
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 struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:39
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:85
union AuthorityChain::@19 authority_info
Information about the resolver authority for this label.
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
ssize_t rd_data_size
Number of bytes in rd_data.
#define GNUNET_DNSPARSER_TYPE_SRV
uint32_t data
The data value.
void GNUNET_DNSPARSER_free_mx(struct GNUNET_DNSPARSER_MxRecord *mx)
Free MX information record.
Definition: dnsparser.c:154
#define GNUNET_DNSPARSER_TYPE_A
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_malloc(size)
Wrapper around malloc.
Information from SRV records (RFC 2782).
#define GNUNET_free(ptr)
Wrapper around free.
unsigned int rd_count
Number of records serialized in rd_data.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ vpn_allocation_cb()

static void vpn_allocation_cb ( void *  cls,
int  af,
const void *  address 
)
static

Callback invoked from the VPN service once a redirection is available.

Provides the IP address that can now be used to reach the requested destination. Replaces the "VPN" record with the respective A/AAAA record and continues processing.

Parameters
clsclosure
afaddress family, AF_INET or AF_INET6; AF_UNSPEC on error; will match 'result_af' from the request
addressIP address (struct in_addr or struct in_addr6, depending on 'af') that the VPN allocated for the redirection; traffic to this IP will now be redirected to the specified target peer; NULL on error

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

References _, GNUNET_TIME_Absolute::abs_value_us, address, GNUNET_GNSRECORD_Data::data, GNUNET_GNSRECORD_Data::data_size, GNUNET_GNSRECORD_Data::expiration_time, GNUNET_GNSRECORD_Data::flags, GNUNET_assert, GNUNET_DNSPARSER_TYPE_A, GNUNET_DNSPARSER_TYPE_AAAA, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_GNSRECORD_records_deserialize(), GNUNET_GNSRECORD_TYPE_VPN, GNUNET_log, GNUNET_OK, GNUNET_TIME_relative_to_absolute(), handle_gns_resolution_result(), GNS_ResolverHandle::name, GNUNET_GNSRECORD_Data::record_type, Gns2DnsPending::rh, VpnContext::rh, GNS_ResolverHandle::vpn_ctx, and VPN_TIMEOUT.

Referenced by handle_gns_resolution_result().

1392 {
1393  struct VpnContext *vpn_ctx = cls;
1394  struct GNS_ResolverHandle *rh = vpn_ctx->rh;
1395  struct GNUNET_GNSRECORD_Data rd[vpn_ctx->rd_count];
1396  unsigned int i;
1397 
1398  vpn_ctx->vpn_request = NULL;
1399  rh->vpn_ctx = NULL;
1402  (size_t) vpn_ctx->rd_data_size,
1403  vpn_ctx->rd_data,
1404  vpn_ctx->rd_count,
1405  rd));
1406  for (i = 0; i < vpn_ctx->rd_count; i++)
1407  {
1409  {
1410  switch (af)
1411  {
1412  case AF_INET:
1413  rd[i].record_type = GNUNET_DNSPARSER_TYPE_A;
1414  rd[i].data_size = sizeof(struct in_addr);
1415  rd[i].expiration_time = GNUNET_TIME_relative_to_absolute (
1417  rd[i].flags = 0;
1418  rd[i].data = address;
1419  break;
1420 
1421  case AF_INET6:
1422  rd[i].record_type = GNUNET_DNSPARSER_TYPE_AAAA;
1423  rd[i].expiration_time = GNUNET_TIME_relative_to_absolute (
1425  rd[i].flags = 0;
1426  rd[i].data = address;
1427  rd[i].data_size = sizeof(struct in6_addr);
1428  break;
1429 
1430  default:
1431  GNUNET_assert (0);
1432  }
1433  break;
1434  }
1435  }
1436  GNUNET_assert (i < vpn_ctx->rd_count);
1437  if (0 == vpn_ctx->rd_count)
1439  _ ("VPN returned empty result for `%s'\n"),
1440  rh->name);
1442  vpn_ctx->rd_count,
1443  rd);
1444  GNUNET_free (vpn_ctx->rd_data);
1445  GNUNET_free (vpn_ctx);
1446 }
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_VPN_RedirectionRequest * vpn_request
Handle to the VPN request that we were performing.
#define VPN_TIMEOUT
Default timeout for VPN redirections.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
char * name
The name to resolve.
int GNUNET_GNSRECORD_records_deserialize(size_t len, const char *src, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *dest)
Deserialize the given records to the given destination.
uint64_t abs_value_us
The actual value.
Handle to a currenty pending resolution.
#define GNUNET_GNSRECORD_TYPE_VPN
Record type for VPN resolution.
#define _(String)
GNU gettext support macro.
Definition: platform.h:180
struct GNS_ResolverHandle * rh
Which resolution process are we processing.
struct VpnContext * vpn_ctx
Handle to a VPN request, NULL if none is active.
char * rd_data
Serialized records.
uint32_t record_type
Type of the GNS/DNS record.
#define GNUNET_DNSPARSER_TYPE_AAAA
Closure for vpn_allocation_cb.
static void handle_gns_resolution_result(void *cls, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process a records that were decrypted from a block.
#define GNUNET_log(kind,...)
ssize_t rd_data_size
Number of bytes in rd_data.
static char * address
GNS address for this phone.
#define GNUNET_DNSPARSER_TYPE_A
#define GNUNET_free(ptr)
Wrapper around free.
unsigned int rd_count
Number of records serialized in rd_data.
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 1457 of file gnunet-service-gns_resolver.c.

References AuthorityChain::authority_info, AuthorityChain::dns_authority, fail_resolution(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_add_now(), GNUNET_YES, AuthorityChain::label, recursive_resolution(), Gns2DnsPending::rh, AuthorityChain::rh, and GNS_ResolverHandle::task_id.

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

1458 {
1459  struct GNS_ResolverHandle *rh = ac->rh;
1460 
1461  if ((NULL != ac->authority_info.dns_authority.gp_head) &&
1462  (GNUNET_NO == ac->authority_info.dns_authority.found))
1463  return; /* more pending and none found yet */
1464  if (GNUNET_NO == ac->authority_info.dns_authority.found)
1465  {
1467  "Failed to resolve DNS server for `%s' in GNS2DNS resolution\n",
1468  ac->authority_info.dns_authority.name);
1469  fail_resolution (rh);
1470  return;
1471  }
1472  if (GNUNET_NO != ac->authority_info.dns_authority.launched)
1473  return; /* already running, do not launch again! */
1474  /* recurse */
1475  ac->authority_info.dns_authority.launched = GNUNET_YES;
1477  "Will continue resolution using DNS to resolve `%s'\n",
1478  ac->label);
1479  GNUNET_assert (NULL == rh->task_id);
1481  rh);
1482 }
static void recursive_resolution(void *cls)
Task scheduled to continue with the resolution process.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
char * label
label/name corresponding to the authority
#define GNUNET_NO
Definition: gnunet_common.h:86
Handle to a currenty pending resolution.
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:1280
struct GNS_ResolverHandle * rh
Resolver handle this entry in the chain belongs to.
struct GNUNET_SCHEDULER_Task * task_id
ID of a task associated with the resolution process.
static void fail_resolution(struct GNS_ResolverHandle *rh)
Function called to asynchronously fail a resolution.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:85
union AuthorityChain::@19 authority_info
Information about the resolver authority for this label.
struct AuthorityChain::@19::@20 dns_authority
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 1494 of file gnunet-service-gns_resolver.c.

References Gns2DnsPending::ac, AuthorityChain::authority_info, continue_with_gns2dns(), GNUNET_GNSRECORD_Data::data, data_size, AuthorityChain::dns_authority, 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, and Gns2DnsPending::rh.

Referenced by recursive_gns2dns_resolution().

1497 {
1498  struct Gns2DnsPending *gp = cls;
1499  struct AuthorityChain *ac = gp->ac;
1500 
1502  ac->authority_info.dns_authority.gp_tail,
1503  gp);
1504  /* enable cleanup of 'rh' handle that automatically comes after we return,
1505  and which expects 'rh' to be in the #rlh_head DLL. */
1506  if (NULL != gp->rh)
1507  {
1509  rlh_tail,
1510  gp->rh);
1511  gp->rh = NULL;
1512  }
1513  GNUNET_free (gp);
1515  "Received %u results for IP address of DNS server for GNS2DNS transition\n",
1516  rd_count);
1517  /* find suitable A/AAAA record */
1518  for (unsigned int j = 0; j < rd_count; j++)
1519  {
1520  switch (rd[j].record_type)
1521  {
1523  {
1524  struct sockaddr_in v4;
1525 
1526  if (sizeof(struct in_addr) != rd[j].data_size)
1527  {
1528  GNUNET_break_op (0);
1529  continue;
1530  }
1531  memset (&v4,
1532  0,
1533  sizeof(v4));
1534  v4.sin_family = AF_INET;
1535  v4.sin_port = htons (53);
1536 #if HAVE_SOCKADDR_IN_SIN_LEN
1537  v4.sin_len = (u_char) sizeof(v4);
1538 #endif
1539  GNUNET_memcpy (&v4.sin_addr,
1540  rd[j].data,
1541  sizeof(struct in_addr));
1542  if (GNUNET_OK ==
1544  ac->authority_info.dns_authority.dns_handle,
1545  (const struct sockaddr *) &v4))
1547  break;
1548  }
1549 
1551  {
1552  struct sockaddr_in6 v6;
1553 
1554  if (sizeof(struct in6_addr) != rd[j].data_size)
1555  {
1556  GNUNET_break_op (0);
1557  continue;
1558  }
1559  /* FIXME: might want to check if we support IPv6 here,
1560  and otherwise skip this one and hope we find another */
1561  memset (&v6,
1562  0,
1563  sizeof(v6));
1564  v6.sin6_family = AF_INET6;
1565  v6.sin6_port = htons (53);
1566 #if HAVE_SOCKADDR_IN_SIN_LEN
1567  v6.sin6_len = (u_char) sizeof(v6);
1568 #endif
1569  GNUNET_memcpy (&v6.sin6_addr,
1570  rd[j].data,
1571  sizeof(struct in6_addr));
1572  if (GNUNET_OK ==
1574  ac->authority_info.dns_authority.dns_handle,
1575  (const struct sockaddr *) &v6))
1577  break;
1578  }
1579 
1580  default:
1581  break;
1582  }
1583  }
1584  continue_with_gns2dns (ac);
1585 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct GNS_ResolverHandle * rh
Handle for the resolution of the IP part of the GNS2DNS record.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
const void * data
Binary value stored in the DNS record.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
DLL to hold the authority chain we had to pass in the resolution process.
struct AuthorityChain * ac
Context this activity belongs with.
Element of a resolution process for looking up the responsible DNS server hostname in a GNS2DNS recur...
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
static void continue_with_gns2dns(struct AuthorityChain *ac)
We have resolved one or more of the nameservers for a GNS2DNS lookup.
#define GNUNET_DNSPARSER_TYPE_AAAA
#define GNUNET_log(kind,...)
static struct GNS_ResolverHandle * rlh_head
Head of resolver lookup list.
static struct GNS_ResolverHandle * rlh_tail
Tail of resolver lookup list.
#define GNUNET_YES
Definition: gnunet_common.h:85
union AuthorityChain::@19 authority_info
Information about the resolver authority for this label.
#define GNUNET_DNSPARSER_TYPE_A
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:643
struct AuthorityChain::@19::@20 dns_authority
#define GNUNET_free(ptr)
Wrapper around free.
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 1596 of file gnunet-service-gns_resolver.c.

References Gns2DnsPending::ac, AuthorityChain::authority_info, continue_with_gns2dns(), AuthorityChain::dns_authority, 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().

1599 {
1600  struct Gns2DnsPending *gp = cls;
1601  struct AuthorityChain *ac = gp->ac;
1602  struct sockaddr_storage ss;
1603  struct sockaddr_in *v4;
1604  struct sockaddr_in6 *v6;
1605 
1606  if (NULL == addr)
1607  {
1608  /* DNS resolution finished */
1609  if (0 == gp->num_results)
1611  "Failed to use DNS to resolve name of DNS resolver\n");
1613  ac->authority_info.dns_authority.gp_tail,
1614  gp);
1615  GNUNET_free (gp);
1616  continue_with_gns2dns (ac);
1617  return;
1618  }
1619  GNUNET_memcpy (&ss,
1620  addr,
1621  addrlen);
1622  switch (ss.ss_family)
1623  {
1624  case AF_INET:
1625  v4 = (struct sockaddr_in *) &ss;
1626  v4->sin_port = htons (53);
1627  gp->num_results++;
1628  break;
1629 
1630  case AF_INET6:
1631  v6 = (struct sockaddr_in6 *) &ss;
1632  v6->sin6_port = htons (53);
1633  gp->num_results++;
1634  break;
1635 
1636  default:
1638  "Unsupported AF %d\n",
1639  ss.ss_family);
1640  return;
1641  }
1642  if (GNUNET_OK ==
1644  (struct sockaddr *) &ss))
1646 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
unsigned int num_results
How many results did we get?
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
DLL to hold the authority chain we had to pass in the resolution process.
struct AuthorityChain * ac
Context this activity belongs with.
Element of a resolution process for looking up the responsible DNS server hostname in a GNS2DNS recur...
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
static void continue_with_gns2dns(struct AuthorityChain *ac)
We have resolved one or more of the nameservers for a GNS2DNS lookup.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:85
union AuthorityChain::@19 authority_info
Information about the resolver authority for this label.
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:643
struct AuthorityChain::@19::@20 dns_authority
#define GNUNET_free(ptr)
Wrapper around free.
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 1656 of file gnunet-service-gns_resolver.c.

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

Referenced by handle_gns_resolution_result().

1658 {
1659  char *cname;
1660  size_t off;
1661 
1662  off = 0;
1663  cname = GNUNET_DNSPARSER_parse_name (rd->data,
1664  rd->data_size,
1665  &off);
1666  if ((NULL == cname) ||
1667  (off != rd->data_size))
1668  {
1669  GNUNET_break_op (0); /* record not well-formed */
1670  GNUNET_free_non_null (cname);
1671  fail_resolution (rh);
1672  return;
1673  }
1675  cname);
1676  GNUNET_free (cname);
1677 }
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
size_t data_size
Number of bytes in data.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
const void * data
Binary value stored in the DNS record.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
static void fail_resolution(struct GNS_ResolverHandle *rh)
Function called to asynchronously fail a resolution.
static void handle_gns_cname_result(struct GNS_ResolverHandle *rh, const char *cname)
We encountered a CNAME record during our resolution.
#define GNUNET_free(ptr)
Wrapper around free.
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 1687 of file gnunet-service-gns_resolver.c.

References Gns2DnsPending::ac, GNS_ResolverHandle::ac_head, GNS_ResolverHandle::ac_tail, AuthorityChain::authority_info, GNUNET_GNSRECORD_Data::data, GNUNET_GNSRECORD_Data::data_size, fail_resolution(), AuthorityChain::gns_authority, GNUNET_break_op, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_memcpy, GNUNET_new, GNUNET_SCHEDULER_add_now(), GNUNET_YES, AuthorityChain::label, recursive_resolution(), resolver_lookup_get_next_label(), Gns2DnsPending::rh, AuthorityChain::rh, and GNS_ResolverHandle::task_id.

Referenced by handle_gns_resolution_result().

1689 {
1690  struct AuthorityChain *ac;
1691 
1692  /* delegation to another zone */
1693  if (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) !=
1694  rd->data_size)
1695  {
1696  GNUNET_break_op (0);
1697  fail_resolution (rh);
1698  return;
1699  }
1700  /* expand authority chain */
1701  ac = GNUNET_new (struct AuthorityChain);
1702  ac->rh = rh;
1703  ac->gns_authority = GNUNET_YES;
1705  rd->data,
1706  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
1708  /* add AC to tail */
1710  rh->ac_tail,
1711  ac);
1712  /* recurse */
1714  rh);
1715 }
static void recursive_resolution(void *cls)
Task scheduled to continue with the resolution process.
char * label
label/name corresponding to the authority
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
size_t data_size
Number of bytes in data.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
int gns_authority
GNUNET_YES if the authority was a GNS authority, GNUNET_NO if the authority was a DNS authority...
struct AuthorityChain * ac_head
DLL to store the authority chain.
const void * data
Binary value stored in the DNS record.
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 ...
struct AuthorityChain * ac_tail
DLL to store the authority chain.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
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:1280
struct GNS_ResolverHandle * rh
Resolver handle this entry in the chain belongs to.
DLL to hold the authority chain we had to pass in the resolution process.
struct GNUNET_SCHEDULER_Task * task_id
ID of a task associated with the resolution process.
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
static void fail_resolution(struct GNS_ResolverHandle *rh)
Function called to asynchronously fail a resolution.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define GNUNET_YES
Definition: gnunet_common.h:85
union AuthorityChain::@19 authority_info
Information about the resolver authority for this label.
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

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

References _, Gns2DnsPending::ac, GNS_ResolverHandle::ac_head, GNS_ResolverHandle::ac_tail, AuthorityChain::authority_info, GNS_ResolverHandle::authority_zone, continue_with_gns2dns(), data, data_size, AuthorityChain::dns_authority, 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_free_non_null, 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(), AuthorityChain::label, 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, 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().

1732 {
1733  struct AuthorityChain *ac;
1734  const char *tld;
1735  char *ns;
1736 
1737  ns = NULL;
1738  /* expand authority chain */
1739  ac = GNUNET_new (struct AuthorityChain);
1740  ac->rh = rh;
1741  ac->authority_info.dns_authority.dns_handle = GNUNET_DNSSTUB_start (4);
1742 
1743  for (unsigned int i = 0; i < rd_count; i++)
1744  {
1745  char *ip;
1746  char *n;
1747  size_t off;
1748  struct Gns2DnsPending *gp;
1750  struct sockaddr_in v4;
1751  struct sockaddr_in6 v6;
1752 
1753  if (GNUNET_GNSRECORD_TYPE_GNS2DNS != rd[i].record_type)
1754  continue;
1755  off = 0;
1756  n = GNUNET_DNSPARSER_parse_name (rd[i].data,
1757  rd[i].data_size,
1758  &off);
1759  ip = GNUNET_strdup (&((const char *) rd[i].data)[off]);
1760  off += strlen (ip) + 1;
1761 
1762  if ((NULL == n) ||
1763  (NULL == ip) ||
1764  (off != rd[i].data_size))
1765  {
1766  GNUNET_break_op (0);
1768  GNUNET_free_non_null (ip);
1769  continue;
1770  }
1771  /* resolve 'ip' to determine the IP(s) of the DNS
1772  resolver to use for lookup of 'ns' */
1773  if (NULL != ns)
1774  {
1775  if (0 != strcasecmp (ns,
1776  n))
1777  {
1778  /* NS values must all be the same for all GNS2DNS records,
1779  anything else leads to insanity */
1780  GNUNET_break_op (0);
1781  GNUNET_free (n);
1782  GNUNET_free (ip);
1783  continue;
1784  }
1785  GNUNET_free (n);
1786  }
1787  else
1788  {
1789  ns = n;
1790  }
1791 
1792  /* check if 'ip' is already an IPv4/IPv6 address */
1793  if ((1 == inet_pton (AF_INET,
1794  ip,
1795  &v4)) ||
1796  (1 == inet_pton (AF_INET6,
1797  ip,
1798  &v6)))
1799  {
1802  ac->authority_info.dns_authority.dns_handle,
1803  ip));
1805  GNUNET_free (ip);
1806  continue;
1807  }
1808  tld = GNS_get_tld (ip);
1809  if ((0 != strcmp (tld, "+")) &&
1811  {
1812  /* 'ip' is a DNS name */
1813  gp = GNUNET_new (struct Gns2DnsPending);
1814  gp->ac = ac;
1816  ac->authority_info.dns_authority.gp_tail,
1817  gp);
1818  gp->dns_rh = GNUNET_RESOLVER_ip_get (ip,
1819  AF_UNSPEC,
1822  gp);
1823  GNUNET_free (ip);
1824  continue;
1825  }
1826  /* 'ip' should be a GNS name */
1827  gp = GNUNET_new (struct Gns2DnsPending);
1828  gp->ac = ac;
1830  ac->authority_info.dns_authority.gp_tail,
1831  gp);
1832  gp->rh = GNUNET_new (struct GNS_ResolverHandle);
1833  if (0 == strcmp (tld, "+"))
1834  {
1835  ip = translate_dot_plus (rh,
1836  ip);
1837  tld = GNS_get_tld (ip);
1838  if (GNUNET_OK !=
1840  &zone))
1841  {
1842  GNUNET_break_op (0);
1843  GNUNET_free (ip);
1844  continue;
1845  }
1846  }
1847  gp->rh->authority_zone = zone;
1849  "Resolving `%s' to determine IP address of DNS server for GNS2DNS transition for `%s'\n",
1850  ip,
1851  ns);
1852  gp->rh->name = ip;
1853  gp->rh->name_resolution_pos = strlen (ip) - strlen (tld) - 1;
1854  gp->rh->proc = &handle_gns2dns_result;
1855  gp->rh->proc_cls = gp;
1858  gp->rh->loop_limiter = rh->loop_limiter + 1;
1859  gp->rh->loop_threshold = rh->loop_threshold;
1860  gp->rh->task_id
1862  gp->rh);
1863  } /* end 'for all records' */
1864 
1865  if (NULL == ns)
1866  {
1867  /* not a single GNS2DNS record found */
1868  GNUNET_free (ac);
1869  return GNUNET_SYSERR;
1870  }
1872  strcpy (ac->authority_info.dns_authority.name,
1873  ns);
1874  /* for DNS recursion, the label is the full DNS name,
1875  created from the remainder of the GNS name and the
1876  name in the NS record */
1877  GNUNET_asprintf (&ac->label,
1878  "%.*s%s%s",
1879  (int) rh->name_resolution_pos,
1880  rh->name,
1881  (0 != rh->name_resolution_pos) ? "." : "",
1882  ns);
1883  GNUNET_free (ns);
1884 
1885  {
1886  /* the GNS name is UTF-8 and may include multibyte chars.
1887  * We have to convert the combined name to a DNS-compatible IDNA.
1888  */
1889  char *tmp = ac->label;
1890 
1891  if (IDNA_SUCCESS != idna_to_ascii_8z (tmp,
1892  &ac->label,
1893  IDNA_ALLOW_UNASSIGNED))
1894  {
1896  _ ("Name `%s' cannot be converted to IDNA."),
1897  tmp);
1898  return GNUNET_SYSERR;
1899  }
1900  GNUNET_free (tmp);
1901  }
1902 
1904  rh->ac_tail,
1905  ac);
1906  if (strlen (ac->label) > GNUNET_DNSPARSER_MAX_NAME_LENGTH)
1907  {
1909  _ ("GNS lookup resulted in DNS name that is too long (`%s')\n"),
1910  ac->label);
1911  return GNUNET_SYSERR;
1912  }
1913  continue_with_gns2dns (ac);
1914  return GNUNET_OK;
1915 }
struct GNS_ResolverHandle * rh
Handle for the resolution of the IP part of the GNS2DNS record.
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
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
const char * GNS_get_tld(const char *name)
Obtain the TLD of the given name.
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
char * label
label/name corresponding to the authority
#define GNUNET_GNSRECORD_TYPE_ANY
Record type indicating any record/&#39;*&#39;.
int GNUNET_GNSRECORD_zkey_to_pkey(const char *zkey, struct GNUNET_CRYPTO_EcdsaPublicKey *pkey)
Convert an absolute domain name to the respective public key.
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:591
unsigned int loop_threshold
Maximum value of loop_limiter allowed by client.
GNS_ResultProcessor proc
called when resolution phase finishes
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:939
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
char * name
The name to resolve.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct AuthorityChain * ac_head
DLL to store the authority chain.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Handle to a currenty pending resolution.
void * proc_cls
closure passed to proc
static void start_resolver_lookup(void *cls)
Begin the resolution process from &#39;name&#39;, starting with the identification of the zone specified by &#39;...
#define _(String)
GNU gettext support macro.
Definition: platform.h:180
static char * zone
Name of the zone we manage.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
#define GNUNET_DNSPARSER_MAX_NAME_LENGTH
Maximum length of a name in DNS.
struct AuthorityChain * ac_tail
DLL to store the authority chain.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
struct GNUNET_DNSSTUB_Context * GNUNET_DNSSTUB_start(unsigned int num_sockets)
Start a DNS stub resolver.
Definition: dnsstub.c:564
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:1280
#define GNUNET_GNSRECORD_TYPE_GNS2DNS
Record type for delegation to DNS.
static struct GNUNET_NAMESTORE_Handle * ns
Handle to the namestore.
Definition: gnunet-abd.c:41
int record_type
Desired type for the resolution.
struct GNS_ResolverHandle * rh
Resolver handle this entry in the chain belongs to.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
DLL to hold the authority chain we had to pass in the resolution process.
struct AuthorityChain * ac
Context this activity belongs with.
struct GNUNET_SCHEDULER_Task * task_id
ID of a task associated with the resolution process.
size_t name_resolution_pos
Current offset in name where we are resolving.
static void handle_gns2dns_result(void *cls, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
We&#39;ve resolved the IP address for the DNS resolver to use after encountering a GNS2DNS record...
#define GNUNET_SYSERR
Definition: gnunet_common.h:84
Element of a resolution process for looking up the responsible DNS server hostname in a GNS2DNS recur...
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
static void continue_with_gns2dns(struct AuthorityChain *ac)
We have resolved one or more of the nameservers for a GNS2DNS lookup.
struct GNUNET_CRYPTO_EcdsaPublicKey authority_zone
The top-level GNS authoritative zone to query.
static char * translate_dot_plus(struct GNS_ResolverHandle *rh, char *name)
Expands a name ending in .
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.
struct GNUNET_RESOLVER_RequestHandle * dns_rh
Handle for DNS resolution of the DNS nameserver.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:85
Defaults, look in cache, then in DHT.
union AuthorityChain::@19 authority_info
Information about the resolver authority for this label.
uint32_t data
The data value.
unsigned int loop_limiter
We increment the loop limiter for each step in a recursive resolution.
struct AuthorityChain::@19::@20 dns_authority
#define GNUNET_free(ptr)
Wrapper around free.
enum GNUNET_GNS_LocalOptions options
Use only cache.
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 2390 of file gnunet-service-gns_resolver.c.

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

Referenced by handle_dht_response().

2393 {
2394  struct CacheOps *co = cls;
2395 
2396  co->namecache_qe_cache = NULL;
2397  if (GNUNET_OK != success)
2399  _ ("Failed to cache GNS resolution: %s\n"),
2400  emsg);
2402  co_tail,
2403  co);
2404  GNUNET_free (co);
2405 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct GNUNET_NAMECACHE_QueueEntry * namecache_qe_cache
Pending Namestore caching task.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
#define _(String)
GNU gettext support macro.
Definition: platform.h:180
Active namestore caching operations.
#define GNUNET_log(kind,...)
static struct CacheOps * co_tail
Organized in a DLL.
#define GNUNET_free(ptr)
Wrapper around free.
static struct CacheOps * co_head
Organized in a DLL.
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 get_path,
unsigned int  get_path_length,
const struct GNUNET_PeerIdentity 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
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 2426 of file gnunet-service-gns_resolver.c.

References Gns2DnsPending::ac, GNS_ResolverHandle::ac_tail, AuthorityChain::authority_info, data, GNS_ResolverHandle::dht_heap_node, disable_cache, GNUNET_GNSRECORD_Block::expiration_time, fail_resolution(), GNS_ResolverHandle::get_handle, AuthorityChain::gns_authority, 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_log, GNUNET_NAMECACHE_block_cache(), GNUNET_new, GNUNET_OK, GNUNET_STRINGS_absolute_time_to_string(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_absolute_ntoh(), GNUNET_YES, handle_gns_resolution_result(), AuthorityChain::label, GNS_ResolverHandle::name, namecache_cache_continuation(), CacheOps::namecache_qe_cache, GNUNET_GNSRECORD_Block::purpose, Gns2DnsPending::rh, and GNUNET_CRYPTO_EccSignaturePurpose::size.

Referenced by start_dht_request().

2436 {
2437  struct GNS_ResolverHandle *rh = cls;
2438  struct AuthorityChain *ac = rh->ac_tail;
2439  const struct GNUNET_GNSRECORD_Block *block;
2440  struct CacheOps *co;
2441 
2442  (void) exp;
2443  (void) key;
2444  (void) get_path;
2445  (void) get_path_length;
2446  (void) put_path;
2447  (void) put_path_length;
2448  (void) type;
2450  rh->get_handle = NULL;
2452  rh->dht_heap_node = NULL;
2454  "Handling response from the DHT\n");
2455  if (size < sizeof(struct GNUNET_GNSRECORD_Block))
2456  {
2457  /* how did this pass DHT block validation!? */
2458  GNUNET_break (0);
2459  fail_resolution (rh);
2460  return;
2461  }
2462  block = data;
2463  if (size !=
2464  ntohl (block->purpose.size)
2465  + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)
2466  + sizeof(struct GNUNET_CRYPTO_EcdsaSignature))
2467  {
2468  /* how did this pass DHT block validation!? */
2469  GNUNET_break (0);
2470  fail_resolution (rh);
2471  return;
2472  }
2474  "Decrypting DHT block of size %u for `%s', expires %s\n",
2475  ntohl (block->purpose.size),
2476  rh->name,
2478  if (GNUNET_OK !=
2481  ac->label,
2483  rh))
2484  {
2485  GNUNET_break_op (0); /* block was ill-formed */
2486  fail_resolution (rh);
2487  return;
2488  }
2490  block->expiration_time)).
2491  rel_value_us)
2492  {
2494  "Received expired block from the DHT, will not cache it.\n");
2495  return;
2496  }
2497  if (GNUNET_YES == disable_cache)
2498  return;
2499  /* Cache well-formed blocks */
2501  "Caching response from the DHT in namecache\n");
2502  co = GNUNET_new (struct CacheOps);
2504  block,
2505  &
2507  co);
2509  co_tail,
2510  co);
2511 }
static struct GNUNET_NAMECACHE_Handle * namecache_handle
Our handle to the namecache service.
struct GNUNET_TIME_AbsoluteNBO expiration_time
Expiration time of the block.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:673
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct GNUNET_NAMECACHE_QueueEntry * namecache_qe_cache
Pending Namestore caching task.
struct GNUNET_DHT_GetHandle * get_handle
Handle for DHT lookups.
char * label
label/name corresponding to the authority
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
#define GNUNET_new(type)
Allocate a struct or union of the given type.
char * name
The name to resolve.
int gns_authority
GNUNET_YES if the authority was a GNS authority, GNUNET_NO if the authority was a DNS authority...
Information we have in an encrypted block with record data (i.e.
static int disable_cache
Use namecache.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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. ...
Handle to a currenty pending resolution.
Active namestore caching operations.
struct AuthorityChain * ac_tail
DLL to store the authority chain.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
an ECC signature using ECDSA
DLL to hold the authority chain we had to pass in the resolution process.
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!)...
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.
void GNUNET_DHT_get_stop(struct GNUNET_DHT_GetHandle *get_handle)
Stop async DHT-get.
Definition: dht_api.c:1155
struct GNUNET_CONTAINER_HeapNode * dht_heap_node
Heap node associated with this lookup.
static unsigned int size
Size of the "table".
Definition: peer.c:67
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
static void fail_resolution(struct GNS_ResolverHandle *rh)
Function called to asynchronously fail a resolution.
int GNUNET_GNSRECORD_block_decrypt(const struct GNUNET_GNSRECORD_Block *block, const struct GNUNET_CRYPTO_EcdsaPublicKey *zone_key, const char *label, GNUNET_GNSRECORD_RecordCallback proc, void *proc_cls)
Decrypt block.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
static void handle_gns_resolution_result(void *cls, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process a records that were decrypted from a block.
#define GNUNET_log(kind,...)
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:331
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
#define GNUNET_YES
Definition: gnunet_common.h:85
static struct CacheOps * co_tail
Organized in a DLL.
union AuthorityChain::@19 authority_info
Information about the resolver authority for this label.
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:742
uint32_t data
The data value.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Number of bytes signed; also specifies the number of bytes of encrypted data that follow...
static struct CacheOps * co_head
Organized in a DLL.
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 2521 of file gnunet-service-gns_resolver.c.

References DHT_GNS_REPLICATION_LEVEL, GNS_ResolverHandle::dht_heap_node, 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().

2523 {
2524  struct GNS_ResolverHandle *rx;
2525 
2526  GNUNET_assert (NULL == rh->get_handle);
2529  query,
2532  NULL, 0,
2533  &handle_dht_response, rh);
2535  rh,
2537  abs_value_us);
2540  {
2541  /* fail longest-standing DHT request */
2543  rx->dht_heap_node = NULL;
2544  GNUNET_assert (NULL != rx);
2545  fail_resolution (rx);
2546  }
2547 }
static struct GNUNET_CONTAINER_Heap * dht_lookup_heap
Heap for limiting parallel DHT lookups.
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.
#define DHT_GNS_REPLICATION_LEVEL
DHT replication level.
struct GNUNET_DHT_GetHandle * get_handle
Handle for DHT lookups.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static unsigned long long max_allowed_background_queries
Maximum amount of parallel queries to the DHT.
Handle to a currenty pending resolution.
static struct GNUNET_DHT_Handle * dht_handle
Resolver handle to the dht.
Block for storing record data.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
unsigned int GNUNET_CONTAINER_heap_get_size(const struct GNUNET_CONTAINER_Heap *heap)
Get the current size of the heap.
struct GNUNET_CONTAINER_HeapNode * dht_heap_node
Heap node associated with this lookup.
static void fail_resolution(struct GNS_ResolverHandle *rh)
Function called to asynchronously fail a resolution.
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:1067
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
Each peer along the way should look at &#39;enc&#39; (otherwise only the k-peers closest to the key should lo...
static void handle_dht_response(void *cls, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const struct GNUNET_PeerIdentity *get_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *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. ...
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 2559 of file gnunet-service-gns_resolver.c.

References _, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, handle_gns_resolution_result(), GNS_ResolverHandle::name, and Gns2DnsPending::rh.

Referenced by handle_namecache_block_response().

2562 {
2563  struct GNS_ResolverHandle *rh = cls;
2564 
2565  if (0 == rd_count)
2567  _ ("GNS namecache returned empty result for `%s'\n"),
2568  rh->name);
2570  rd_count,
2571  rd);
2572 }
char * name
The name to resolve.
Handle to a currenty pending resolution.
#define _(String)
GNU gettext support macro.
Definition: platform.h:180
static void handle_gns_resolution_result(void *cls, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process a records that were decrypted from a block.
#define GNUNET_log(kind,...)
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 2582 of file gnunet-service-gns_resolver.c.

References Gns2DnsPending::ac, GNS_ResolverHandle::ac_head, GNS_ResolverHandle::ac_tail, AuthorityChain::authority_info, GNUNET_GNSRECORD_Block::expiration_time, fail_resolution(), AuthorityChain::gns_authority, GNUNET_assert, GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_GNS_LO_DEFAULT, GNUNET_GNS_LO_LOCAL_MASTER, GNUNET_GNSRECORD_block_decrypt(), GNUNET_GNSRECORD_query_from_public_key(), GNUNET_GNSRECORD_z2s(), GNUNET_h2s(), GNUNET_log, GNUNET_OK, GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_absolute_ntoh(), handle_gns_namecache_resolution_result(), AuthorityChain::label, GNS_ResolverHandle::namecache_qe, GNS_ResolverHandle::options, Gns2DnsPending::rh, and start_dht_request().

Referenced by recursive_gns_resolution_namecache().

2584 {
2585  struct GNS_ResolverHandle *rh = cls;
2586  struct AuthorityChain *ac = rh->ac_tail;
2587  const char *label = ac->label;
2588  const struct GNUNET_CRYPTO_EcdsaPublicKey *auth =
2590  struct GNUNET_HashCode query;
2591 
2592  GNUNET_assert (NULL != rh->namecache_qe);
2593  rh->namecache_qe = NULL;
2594  if (((GNUNET_GNS_LO_DEFAULT == rh->options) ||
2595  ((GNUNET_GNS_LO_LOCAL_MASTER == rh->options) &&
2596  (ac != rh->ac_head))) &&
2597  ((NULL == block) ||
2599  block->expiration_time)).
2600  rel_value_us)))
2601  {
2602  /* namecache knows nothing; try DHT lookup */
2604  label,
2605  &query);
2607  "Starting DHT lookup for `%s' in zone `%s' under key `%s'\n",
2608  ac->label,
2610  GNUNET_h2s (&query));
2611  start_dht_request (rh, &query);
2612  return;
2613  }
2614 
2615  if ((NULL == block) ||
2617  block->expiration_time)).
2618  rel_value_us))
2619  {
2620  /* DHT not permitted and no local result, fail */
2622  "Resolution failed for `%s' in zone %s (DHT lookup not permitted by configuration)\n",
2623  ac->label,
2625  fail_resolution (rh);
2626  return;
2627  }
2629  "Received result from namecache for label `%s'\n",
2630  ac->label);
2631 
2632  if (GNUNET_OK !=
2634  auth,
2635  label,
2637  rh))
2638  {
2639  GNUNET_break_op (0); /* block was ill-formed */
2640  /* try DHT instead */
2642  label,
2643  &query);
2645  "Starting DHT lookup for `%s' in zone `%s' under key `%s'\n",
2646  ac->label,
2648  GNUNET_h2s (&query));
2649  start_dht_request (rh, &query);
2650  return;
2651  }
2652 }
For the rightmost label, only look in the cache (it is our local namestore), for the others...
struct GNUNET_TIME_AbsoluteNBO expiration_time
Expiration time of the block.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:673
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
char * label
label/name corresponding to the authority
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
int gns_authority
GNUNET_YES if the authority was a GNS authority, GNUNET_NO if the authority was a DNS authority...
struct AuthorityChain * ac_head
DLL to store the authority chain.
Handle to a currenty pending resolution.
struct AuthorityChain * ac_tail
DLL to store the authority chain.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
struct GNUNET_NAMECACHE_QueueEntry * namecache_qe
Pending Namecache lookup task.
DLL to hold the authority chain we had to pass in the resolution process.
A 512-bit hashcode.
const char * GNUNET_GNSRECORD_z2s(const struct GNUNET_CRYPTO_EcdsaPublicKey *z)
Convert a zone key to a string (for printing debug messages).
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.
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
static void fail_resolution(struct GNS_ResolverHandle *rh)
Function called to asynchronously fail a resolution.
static void start_dht_request(struct GNS_ResolverHandle *rh, const struct GNUNET_HashCode *query)
Initiate a DHT query for a set of GNS records.
int GNUNET_GNSRECORD_block_decrypt(const struct GNUNET_GNSRECORD_Block *block, const struct GNUNET_CRYPTO_EcdsaPublicKey *zone_key, const char *label, GNUNET_GNSRECORD_RecordCallback proc, void *proc_cls)
Decrypt block.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define GNUNET_log(kind,...)
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:331
Defaults, look in cache, then in DHT.
void GNUNET_GNSRECORD_query_from_public_key(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, const char *label, struct GNUNET_HashCode *query)
Calculate the DHT query for a given label in a given zone.
union AuthorityChain::@19 authority_info
Information about the resolver authority for this label.
enum GNUNET_GNS_LocalOptions options
Use only cache.
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 2661 of file gnunet-service-gns_resolver.c.

References Gns2DnsPending::ac, GNS_ResolverHandle::ac_tail, AuthorityChain::authority_info, disable_cache, AuthorityChain::gns_authority, 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(), AuthorityChain::label, GNS_ResolverHandle::namecache_qe, and start_dht_request().

Referenced by handle_revocation_result().

2662 {
2663  struct AuthorityChain *ac = rh->ac_tail;
2664  struct GNUNET_HashCode query;
2665 
2667  "Starting GNS resolution for `%s' in zone %s\n",
2668  ac->label,
2671  ac->label,
2672  &query);
2673  if (GNUNET_YES != disable_cache)
2674  {
2675  rh->namecache_qe
2677  &query,
2679  rh);
2680  GNUNET_assert (NULL != rh->namecache_qe);
2681  }
2682  else
2683  {
2684  start_dht_request (rh,
2685  &query);
2686  }
2687 }
static struct GNUNET_NAMECACHE_Handle * namecache_handle
Our handle to the namecache service.
static void handle_namecache_block_response(void *cls, const struct GNUNET_GNSRECORD_Block *block)
Process a record that was stored in the namecache.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
char * label
label/name corresponding to the authority
int gns_authority
GNUNET_YES if the authority was a GNS authority, GNUNET_NO if the authority was a DNS authority...
static int disable_cache
Use namecache.
struct AuthorityChain * ac_tail
DLL to store the authority chain.
struct GNUNET_NAMECACHE_QueueEntry * namecache_qe
Pending Namecache lookup task.
DLL to hold the authority chain we had to pass in the resolution process.
A 512-bit hashcode.
const char * GNUNET_GNSRECORD_z2s(const struct GNUNET_CRYPTO_EcdsaPublicKey *z)
Convert a zone key to a string (for printing debug messages).
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
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.
static void start_dht_request(struct GNS_ResolverHandle *rh, const struct GNUNET_HashCode *query)
Initiate a DHT query for a set of GNS records.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:85
void GNUNET_GNSRECORD_query_from_public_key(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, const char *label, struct GNUNET_HashCode *query)
Calculate the DHT query for a given label in a given zone.
union AuthorityChain::@19 authority_info
Information about the resolver authority for this label.
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 2697 of file gnunet-service-gns_resolver.c.

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

Referenced by recursive_gns_resolution_revocation().

2699 {
2700  struct GNS_ResolverHandle *rh = cls;
2701  struct AuthorityChain *ac = rh->ac_tail;
2702 
2703  rh->rev_check = NULL;
2704  if (GNUNET_YES != is_valid)
2705  {
2707  _ ("Zone %s was revoked, resolution fails\n"),
2709  fail_resolution (rh);
2710  return;
2711  }
2713 }
int gns_authority
GNUNET_YES if the authority was a GNS authority, GNUNET_NO if the authority was a DNS authority...
Handle to a currenty pending resolution.
#define _(String)
GNU gettext support macro.
Definition: platform.h:180
struct AuthorityChain * ac_tail
DLL to store the authority chain.
static void recursive_gns_resolution_namecache(struct GNS_ResolverHandle *rh)
Lookup tail of our authority chain in the namecache.
DLL to hold the authority chain we had to pass in the resolution process.
const char * GNUNET_GNSRECORD_z2s(const struct GNUNET_CRYPTO_EcdsaPublicKey *z)
Convert a zone key to a string (for printing debug messages).
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
static void fail_resolution(struct GNS_ResolverHandle *rh)
Function called to asynchronously fail a resolution.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:85
struct GNUNET_REVOCATION_Query * rev_check
Pending revocation check.
union AuthorityChain::@19 authority_info
Information about the resolver authority for this label.
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 2722 of file gnunet-service-gns_resolver.c.

References Gns2DnsPending::ac, GNS_ResolverHandle::ac_tail, AuthorityChain::authority_info, AuthorityChain::gns_authority, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_GNSRECORD_z2s(), GNUNET_log, GNUNET_REVOCATION_query(), handle_revocation_result(), and GNS_ResolverHandle::rev_check.

Referenced by recursive_resolution().

2723 {
2724  struct AuthorityChain *ac = rh->ac_tail;
2725 
2727  "Starting revocation check for zone %s\n",
2732  rh);
2733  GNUNET_assert (NULL != rh->rev_check);
2734 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int gns_authority
GNUNET_YES if the authority was a GNS authority, GNUNET_NO if the authority was a DNS authority...
static const struct GNUNET_CONFIGURATION_Handle * cfg
Global configuration.
struct AuthorityChain * ac_tail
DLL to store the authority chain.
DLL to hold the authority chain we had to pass in the resolution process.
const char * GNUNET_GNSRECORD_z2s(const struct GNUNET_CRYPTO_EcdsaPublicKey *z)
Convert a zone key to a string (for printing debug messages).
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
static void handle_revocation_result(void *cls, int is_valid)
Function called with the result from a revocation check.
#define GNUNET_log(kind,...)
struct GNUNET_REVOCATION_Query * GNUNET_REVOCATION_query(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_CRYPTO_EcdsaPublicKey *key, GNUNET_REVOCATION_Callback func, void *func_cls)
Check if a key was revoked.
struct GNUNET_REVOCATION_Query * rev_check
Pending revocation check.
union AuthorityChain::@19 authority_info
Information about the resolver authority for this label.
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_CRYPTO_EcdsaPublicKey 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 2851 of file gnunet-service-gns_resolver.c.

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, GNS_ResolverHandle::name, GNS_ResolverHandle::name_resolution_pos, options, GNS_ResolverHandle::options, GNS_ResolverHandle::proc, GNS_ResolverHandle::proc_cls, GNS_ResolverHandle::record_type, Gns2DnsPending::rh, start_resolver_lookup(), GNS_ResolverHandle::task_id, and zone.

Referenced by handle_dns_request(), and handle_lookup().

2858 {
2859  struct GNS_ResolverHandle *rh;
2860 
2862  "Starting lookup for `%s'\n",
2863  name);
2864  rh = GNUNET_new (struct GNS_ResolverHandle);
2866  rlh_tail,
2867  rh);
2868  rh->authority_zone = *zone;
2869  rh->proc = proc;
2870  rh->proc_cls = proc_cls;
2871  rh->options = options;
2872  rh->record_type = record_type;
2873  rh->name = GNUNET_strdup (name);
2874  rh->name_resolution_pos = strlen (name);
2875  rh->loop_threshold = recursion_depth_limit;
2877  rh);
2878  return rh;
2879 }
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
unsigned int loop_threshold
Maximum value of loop_limiter allowed by client.
GNS_ResultProcessor proc
called when resolution phase finishes
#define GNUNET_new(type)
Allocate a struct or union of the given type.
char * name
The name to resolve.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
Handle to a currenty pending resolution.
void * proc_cls
closure passed to proc
static void start_resolver_lookup(void *cls)
Begin the resolution process from &#39;name&#39;, starting with the identification of the zone specified by &#39;...
static char * zone
Name of the zone we manage.
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:1280
int record_type
Desired type for the resolution.
struct GNUNET_SCHEDULER_Task * task_id
ID of a task associated with the resolution process.
size_t name_resolution_pos
Current offset in name where we are resolving.
struct GNUNET_CRYPTO_EcdsaPublicKey authority_zone
The top-level GNS authoritative zone to query.
const char * name
#define GNUNET_log(kind,...)
static struct GNS_ResolverHandle * rlh_head
Head of resolver lookup list.
static struct GNS_ResolverHandle * rlh_tail
Tail of resolver lookup list.
enum GNUNET_GNS_LocalOptions options
Use only cache.
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 2888 of file gnunet-service-gns_resolver.c.

References Gns2DnsPending::ac, GNS_ResolverHandle::ac_head, GNS_ResolverHandle::ac_tail, AuthorityChain::authority_info, GNS_ResolverHandle::dht_heap_node, AuthorityChain::dns_authority, GNS_ResolverHandle::dns_request, GNS_ResolverHandle::dns_result_head, GNS_ResolverHandle::dns_result_tail, Gns2DnsPending::dns_rh, GNS_ResolverHandle::get_handle, AuthorityChain::gns_authority, 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_free_non_null, GNUNET_log, GNUNET_NAMECACHE_cancel(), GNUNET_NO, GNUNET_RESOLVER_request_cancel(), GNUNET_REVOCATION_query_cancel(), GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_VPN_cancel_request(), AuthorityChain::label, GNS_ResolverHandle::leho, GNS_ResolverHandle::name, GNS_ResolverHandle::namecache_qe, VpnContext::rd_data, GNS_ResolverHandle::rev_check, Gns2DnsPending::rh, GNS_ResolverHandle::std_resolve, GNS_ResolverHandle::task_id, GNS_ResolverHandle::vpn_ctx, and VpnContext::vpn_request.

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

2889 {
2890  struct DnsResult *dr;
2891  struct AuthorityChain *ac;
2892  struct VpnContext *vpn_ctx;
2893 
2895  rlh_tail,
2896  rh);
2897  if (NULL != rh->dns_request)
2898  {
2900  rh->dns_request = NULL;
2901  }
2902  while (NULL != (ac = rh->ac_head))
2903  {
2905  rh->ac_tail,
2906  ac);
2907  if (GNUNET_NO == ac->gns_authority)
2908  {
2909  struct Gns2DnsPending *gp;
2910 
2911  while (NULL != (gp = ac->authority_info.dns_authority.gp_head))
2912  {
2914  ac->authority_info.dns_authority.gp_tail,
2915  gp);
2916  if (NULL != gp->rh)
2917  {
2918  /* rh->g2dc->rh is NOT in the DLL yet, so to enable us
2919  using GNS_resolver_lookup_cancel here, we need to
2920  add it first... */
2922  rlh_tail,
2923  gp->rh);
2924  GNUNET_assert (NULL == gp->rh->task_id);
2927  gp->rh);
2928  gp->rh = NULL;
2929  }
2930  if (NULL != gp->dns_rh)
2931  {
2933  gp->dns_rh = NULL;
2934  }
2935  GNUNET_free (gp);
2936  }
2938  }
2939  GNUNET_free (ac->label);
2940  GNUNET_free (ac);
2941  }
2942  if (NULL != rh->task_id)
2943  {
2945  rh->task_id = NULL;
2946  }
2947  if (NULL != rh->get_handle)
2948  {
2950  rh->get_handle = NULL;
2951  }
2952  if (NULL != rh->dht_heap_node)
2953  {
2955  rh->dht_heap_node = NULL;
2956  }
2957  if (NULL != (vpn_ctx = rh->vpn_ctx))
2958  {
2960  GNUNET_free (vpn_ctx->rd_data);
2961  GNUNET_free (vpn_ctx);
2962  }
2963  if (NULL != rh->namecache_qe)
2964  {
2966  rh->namecache_qe = NULL;
2967  }
2968  if (NULL != rh->rev_check)
2969  {
2971  rh->rev_check = NULL;
2972  }
2973  if (NULL != rh->std_resolve)
2974  {
2976  "Canceling standard DNS resolution\n");
2978  rh->std_resolve = NULL;
2979  }
2980  while (NULL != (dr = rh->dns_result_head))
2981  {
2983  rh->dns_result_tail,
2984  dr);
2985  GNUNET_free (dr);
2986  }
2987  GNUNET_free_non_null (rh->leho);
2988  GNUNET_free (rh->name);
2989  GNUNET_free (rh);
2990 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct GNS_ResolverHandle * rh
Handle for the resolution of the IP part of the GNS2DNS record.
void GNUNET_REVOCATION_query_cancel(struct GNUNET_REVOCATION_Query *q)
Cancel key revocation check.
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct GNUNET_DHT_GetHandle * get_handle
Handle for DHT lookups.
static void GNS_resolver_lookup_cancel_(void *cls)
Wrapper around GNS_resolver_lookup_cancel() as a task.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void GNUNET_DNSSTUB_stop(struct GNUNET_DNSSTUB_Context *ctx)
Cleanup DNSSTUB resolver.
Definition: dnsstub.c:690
char * label
label/name corresponding to the authority
struct GNUNET_VPN_RedirectionRequest * vpn_request
Handle to the VPN request that we were performing.
#define GNUNET_NO
Definition: gnunet_common.h:86
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
char * name
The name to resolve.
int gns_authority
GNUNET_YES if the authority was a GNS authority, GNUNET_NO if the authority was a DNS authority...
struct AuthorityChain * ac_head
DLL to store the authority chain.
struct GNUNET_RESOLVER_RequestHandle * std_resolve
Handle for standard DNS resolution, NULL if none is active.
struct AuthorityChain * ac_tail
DLL to store the authority chain.
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:1280
struct GNUNET_NAMECACHE_QueueEntry * namecache_qe
Pending Namecache lookup task.
void GNUNET_NAMECACHE_cancel(struct GNUNET_NAMECACHE_QueueEntry *qe)
Cancel a namecache operation.
DLL to hold the authority chain we had to pass in the resolution process.
struct GNUNET_SCHEDULER_Task * task_id
ID of a task associated with the resolution process.
void GNUNET_DHT_get_stop(struct GNUNET_DHT_GetHandle *get_handle)
Stop async DHT-get.
Definition: dht_api.c:1155
void GNUNET_VPN_cancel_request(struct GNUNET_VPN_RedirectionRequest *rr)
Cancel redirection request with the service.
Definition: vpn_api.c:375
A result we got from DNS.
struct GNUNET_CONTAINER_HeapNode * dht_heap_node
Heap node associated with this lookup.
Element of a resolution process for looking up the responsible DNS server hostname in a GNS2DNS recur...
struct VpnContext * vpn_ctx
Handle to a VPN request, NULL if none is active.
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
char * rd_data
Serialized records.
struct GNUNET_DNSSTUB_RequestSocket * dns_request
Socket for a DNS request, NULL if none is active.
struct GNUNET_RESOLVER_RequestHandle * dns_rh
Handle for DNS resolution of the DNS nameserver.
Closure for vpn_allocation_cb.
void GNUNET_DNSSTUB_resolve_cancel(struct GNUNET_DNSSTUB_RequestSocket *rs)
Cancel DNS resolution.
Definition: dnsstub.c:540
#define GNUNET_log(kind,...)
static struct GNS_ResolverHandle * rlh_head
Head of resolver lookup list.
static struct GNS_ResolverHandle * rlh_tail
Tail of resolver lookup list.
struct GNUNET_REVOCATION_Query * rev_check
Pending revocation check.
struct DnsResult * dns_result_tail
DLL of results we got from DNS.
union AuthorityChain::@19 authority_info
Information about the resolver authority for this label.
char * leho
Legacy Hostname to use if we encountered GNS2DNS record and thus can deduct the LEHO from that transi...
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
struct AuthorityChain::@19::@20 dns_authority
struct DnsResult * dns_result_head
DLL of results we got from DNS.
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
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 3005 of file gnunet-service-gns_resolver.c.

References dht, disable_cache, GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CONTAINER_heap_create(), GNUNET_CONTAINER_HEAP_ORDER_MIN, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_VPN_connect(), GNUNET_YES, max_allowed_background_queries, and nc.

Referenced by run().

3009 {
3010  cfg = c;
3011  namecache_handle = nc;
3012  dht_handle = dht;
3013  dht_lookup_heap =
3015  max_allowed_background_queries = max_bg_queries;
3017  "namecache",
3018  "DISABLE");
3019  if (GNUNET_YES == disable_cache)
3021  "Namecache disabled\n");
3023 }
static struct GNUNET_VPN_Handle * vpn_handle
Our handle to the vpn service.
static struct GNUNET_NAMECACHE_Handle * namecache_handle
Our handle to the namecache service.
static struct GNUNET_CONTAINER_Heap * dht_lookup_heap
Heap for limiting parallel DHT lookups.
static unsigned long long max_allowed_background_queries
Maximum amount of parallel queries to the DHT.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Global configuration.
static int disable_cache
Use namecache.
static struct GNUNET_DHT_Handle * dht_handle
Resolver handle to the dht.
Heap with the minimum cost at the root.
static struct GNUNET_PEERINFO_NotifyContext * nc
Iterator context.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
struct GNUNET_VPN_Handle * GNUNET_VPN_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the VPN service.
Definition: vpn_api.c:512
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:85
int 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".
static struct GNUNET_DHT_Handle * dht
Handle to the DHT.
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 3030 of file gnunet-service-gns_resolver.c.

References GNS_resolver_lookup_cancel(), GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_heap_destroy(), GNUNET_free, GNUNET_NAMECACHE_cancel(), GNUNET_VPN_disconnect(), CacheOps::namecache_qe_cache, GNS_ResolverHandle::proc, GNS_ResolverHandle::proc_cls, and Gns2DnsPending::rh.

Referenced by shutdown_task().

3031 {
3032  struct GNS_ResolverHandle *rh;
3033  struct CacheOps *co;
3034 
3035  /* abort active resolutions */
3036  while (NULL != (rh = rlh_head))
3037  {
3038  rh->proc (rh->proc_cls,
3039  0,
3040  NULL);
3042  }
3043  while (NULL != (co = co_head))
3044  {
3046  co_tail,
3047  co);
3049  GNUNET_free (co);
3050  }
3052  dht_lookup_heap = NULL;
3054  vpn_handle = NULL;
3055  dht_handle = NULL;
3056  namecache_handle = NULL;
3057 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static struct GNUNET_VPN_Handle * vpn_handle
Our handle to the vpn service.
static struct GNUNET_NAMECACHE_Handle * namecache_handle
Our handle to the namecache service.
static struct GNUNET_CONTAINER_Heap * dht_lookup_heap
Heap for limiting parallel DHT lookups.
void GNS_resolver_lookup_cancel(struct GNS_ResolverHandle *rh)
Cancel active resolution (i.e.
struct GNUNET_NAMECACHE_QueueEntry * namecache_qe_cache
Pending Namestore caching task.
GNS_ResultProcessor proc
called when resolution phase finishes
Handle to a currenty pending resolution.
void * proc_cls
closure passed to proc
Active namestore caching operations.
void GNUNET_VPN_disconnect(struct GNUNET_VPN_Handle *vh)
Disconnect from the VPN service.
Definition: vpn_api.c:534
static struct GNUNET_DHT_Handle * dht_handle
Resolver handle to the dht.
void GNUNET_NAMECACHE_cancel(struct GNUNET_NAMECACHE_QueueEntry *qe)
Cancel a namecache operation.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
static struct GNS_ResolverHandle * rlh_head
Head of resolver lookup list.
static struct CacheOps * co_tail
Organized in a DLL.
#define GNUNET_free(ptr)
Wrapper around free.
static struct CacheOps * co_head
Organized in a DLL.
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 463 of file gnunet-service-gns_resolver.c.

◆ vpn_handle

struct GNUNET_VPN_Handle* vpn_handle
static

Our handle to the vpn service.

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

◆ dht_handle

struct GNUNET_DHT_Handle* dht_handle
static

Resolver handle to the dht.

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

◆ dht_lookup_heap

struct GNUNET_CONTAINER_Heap* dht_lookup_heap
static

Heap for limiting parallel DHT lookups.

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

◆ max_allowed_background_queries

unsigned long long max_allowed_background_queries
static

Maximum amount of parallel queries to the DHT.

Definition at line 483 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 488 of file gnunet-service-gns_resolver.c.

◆ rlh_tail

struct GNS_ResolverHandle* rlh_tail
static

Tail of resolver lookup list.

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

◆ co_head

struct CacheOps* co_head
static

Organized in a DLL.

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

◆ co_tail

struct CacheOps* co_tail
static

Organized in a DLL.

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

◆ disable_cache

int disable_cache
static

◆ cfg

<