33#define LOG(kind, ...) GNUNET_log_from (kind, "util-resolver-api", __VA_ARGS__)
35#define LOG_STRERROR(kind, syscall) GNUNET_log_from_strerror (kind, \
36 "util-resolver-api", \
42#define MAX_HOSTNAME 1024
194 struct sockaddr_in v4;
195 struct sockaddr_in6 v6;
202 memset (&v4, 0,
sizeof(v4));
203 v4.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
204 v4.sin_family = AF_INET;
205#if HAVE_SOCKADDR_IN_SIN_LEN
206 v4.sin_len =
sizeof(v4);
208 memset (&v6, 0,
sizeof(v6));
209 v6.sin6_family = AF_INET6;
210#if HAVE_SOCKADDR_IN_SIN_LEN
211 v6.sin6_len =
sizeof(v6);
221 "Missing `%s' for `%s' in configuration, DNS resolution will be unavailable.\n"),
226 if ((1 == inet_pton (AF_INET, hostname, &v4)) ||
227 (1 == inet_pton (AF_INET6, hostname, &v6)))
232 for (
unsigned int i = 0;
243 "Missing `%s' or numeric IP address for `%s' of `%s' in configuration, DNS resolution will be unavailable.\n"),
285 "Disconnecting from DNS service\n");
352 char buf[INET6_ADDRSTRLEN];
357 if (ip_len !=
sizeof(
struct in_addr))
372 if (ip_len !=
sizeof(
struct in6_addr))
417 "MQ error %d, reconnecting\n",
455 msg->af = htonl (rh->
af);
456 msg->client_id = rh->
id;
461 "Transmitting DNS resolution request (ID %u) to DNS service\n",
502 uint32_t client_request_id =
msg->client_id;
504 for (; rh != NULL; rh = rh->
next)
506 if (rh->
id == client_request_id)
524 "Received empty response from DNS service\n");
559 const char *hostname;
561 hostname = (
const char *) &
msg[1];
577 "Resolver returns `%s' for IP `%s'.\n",
582 rh->name_callback (rh->cls,
589 struct sockaddr_in v4;
590 struct sockaddr_in6 v6;
591 const struct sockaddr *sa;
598 if (ip_len ==
sizeof(
struct in_addr))
600 memset (&v4, 0,
sizeof(v4));
601 v4.sin_family = AF_INET;
602 v4.sin_addr = *(
struct in_addr*) ip;
603#if HAVE_SOCKADDR_IN_SIN_LEN
604 v4.sin_len =
sizeof(v4);
607 sa = (
const struct sockaddr *) &v4;
609 else if (ip_len ==
sizeof(
struct in6_addr))
611 memset (&v6, 0,
sizeof(v6));
612 v6.sin6_family = AF_INET6;
613 v6.sin6_addr = *(
struct in6_addr*) ip;
614#if HAVE_SOCKADDR_IN_SIN_LEN
615 v6.sin6_len =
sizeof(v6);
618 sa = (
const struct sockaddr *) &v6;
635 "Received IP from DNS service\n");
655 struct sockaddr_in v4;
656 struct sockaddr_in6 v6;
657 const char *hostname;
660 memset (&v4, 0,
sizeof(v4));
661 v4.sin_family = AF_INET;
662#if HAVE_SOCKADDR_IN_SIN_LEN
663 v4.sin_len =
sizeof(v4);
665 memset (&v6, 0,
sizeof(v6));
666 v6.sin6_family = AF_INET6;
667#if HAVE_SOCKADDR_IN_SIN_LEN
668 v6.sin6_len =
sizeof(v6);
670 hostname = (
const char *) &rh[1];
671 if (((rh->
af == AF_UNSPEC) ||
672 (rh->
af == AF_INET)) &&
673 (1 == inet_pton (AF_INET,
678 (
const struct sockaddr *) &v4,
680 if ((rh->
af == AF_UNSPEC) &&
682 (1 == inet_pton (AF_INET6,
688 (
const struct sockaddr *) &v6,
698 if (((rh->
af == AF_UNSPEC) ||
699 (rh->
af == AF_INET6)) &&
700 (1 == inet_pton (AF_INET6,
705 (
const struct sockaddr *) &v6,
731 struct sockaddr_in v4;
732 struct sockaddr_in6 v6;
735 memset (&v4, 0,
sizeof(v4));
736 v4.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
737 v4.sin_family = AF_INET;
738#if HAVE_SOCKADDR_IN_SIN_LEN
739 v4.sin_len =
sizeof(v4);
741 memset (&v6, 0,
sizeof(v6));
742 v6.sin6_family = AF_INET6;
743#if HAVE_SOCKADDR_IN_SIN_LEN
744 v6.sin6_len =
sizeof(v6);
746 v6.sin6_addr = in6addr_loopback;
751 (
const struct sockaddr *) &v4,
757 (
const struct sockaddr *) &v6,
763 (
const struct sockaddr *) &v6,
766 (
const struct sockaddr *) &v4,
780 "Finished resolving hostname `%s'.\n",
781 (
const char *) &rh[1]);
807 "Trying to connect to DNS service\n");
816 "Failed to connect, will try again later\n");
863 "Will try to connect to DNS service in %s\n",
888 _ (
"Timeout trying to resolve hostname `%s'.\n"),
889 (
const char *) &rh[1]);
890 if (NULL != rh->addr_callback)
891 rh->addr_callback (rh->cls,
897#if ! defined(GNUNET_CULL_LOGGING)
898 char buf[INET6_ADDRSTRLEN];
901 _ (
"Timeout trying to resolve IP address `%s'.\n"),
903 (
const void *) &rh[1],
914 if (NULL != rh->name_callback)
915 rh->name_callback (rh->cls, nret);
919 if (NULL != rh->name_callback)
920 rh->name_callback (rh->cls,
951 slen = strlen (hostname) + 1;
959 "Trying to resolve hostname `%s'.\n",
965 rh->
cls = callback_cls;
973 if (((1 == inet_pton (AF_INET,
977 (af == AF_UNSPEC))) ||
978 ((1 == inet_pton (AF_INET6,
989 for (
unsigned int i = 0;
1040 "Resolver returns `%s'.\n",
1050 if (NULL != rh->
task)
1086 _ (
"Resolver not configured correctly.\n"));
1090 switch (sa->sa_family)
1094 ip_len =
sizeof(
struct in_addr);
1095 ip = &((
const struct sockaddr_in*) sa)->sin_addr;
1100 ip_len =
sizeof(
struct in6_addr);
1101 ip = &((
const struct sockaddr_in6*) sa)->sin6_addr;
1111 rh->
af = sa->sa_family;
1153 if (0 != gethostname (hostname,
1154 sizeof(hostname) - 1))
1161 "Resolving our FQDN `%s'\n",
1165 struct addrinfo *
ai;
1169 if (0 != (
ret = getaddrinfo (hostname,
1175 _ (
"Could not resolve our FQDN: %s\n"),
1176 gai_strerror (
ret));
1179 if (NULL !=
ai->ai_canonname)
1186#elif HAVE_GETHOSTBYNAME2
1188 struct hostent *host;
1190 host = gethostbyname2 (hostname,
1193 host = gethostbyname2 (hostname,
1198 _ (
"Could not resolve our FQDN: %s\n"),
1199 hstrerror (h_errno));
1204#elif HAVE_GETHOSTBYNAME
1206 struct hostent *host;
1208 host = gethostbyname (hostname);
1212 _ (
"Could not resolve our FQDN: %s\n"),
1213 hstrerror (h_errno));
1242 if (0 != gethostname (hostname,
sizeof(hostname) - 1))
1249 "Resolving our hostname `%s'\n",
1272 "Asked to cancel request to resolve hostname `%s'.\n",
1273 (
const char *) &rh[1]);
1274 if (NULL != rh->
task)
struct GNUNET_MQ_MessageHandlers handlers[]
struct GNUNET_MessageHeader * msg
struct GNUNET_MQ_Envelope * env
static int ret
Final status code.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
static struct MHD_Response * response
Our canonical response.
static int result
Global testing status.
Constants for network protocols.
Functions related to doing DNS lookups.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_have_value(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Test if we have a value for a particular option.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
void * cls
Closure for mv and cb.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
#define GNUNET_OS_get_hostname_max_length()
Get maximum string length returned by gethostname()
#define GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST
Request DNS resolution.
#define GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE
Response to a DNS resolution request.
char * GNUNET_RESOLVER_local_fqdn_get()
Get local fully qualified af name.
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.
void GNUNET_RESOLVER_disconnect()
Destroy the connection to the resolver service.
void GNUNET_RESOLVER_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create the connection to the resolver service.
struct GNUNET_RESOLVER_RequestHandle * GNUNET_RESOLVER_hostname_resolve(int af, struct GNUNET_TIME_Relative timeout, GNUNET_RESOLVER_AddressCallback callback, void *cls)
Looking our own hostname.
void(* GNUNET_RESOLVER_AddressCallback)(void *cls, const struct sockaddr *addr, socklen_t addrlen)
Function called by the resolver for each address obtained from DNS.
struct GNUNET_RESOLVER_RequestHandle * GNUNET_RESOLVER_hostname_get(const struct sockaddr *sa, socklen_t salen, int do_resolve, struct GNUNET_TIME_Relative timeout, GNUNET_RESOLVER_HostnameCallback callback, void *cls)
Get an IP address as a string.
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
void(* GNUNET_RESOLVER_HostnameCallback)(void *cls, const char *hostname)
Function called by the resolver for each hostname obtained from DNS.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
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.
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.
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
static unsigned int size
Size of the "table".
static void reconnect(void)
Adjust exponential back-off and reconnect to the service.
static void numeric_resolution(void *cls)
We've been asked to lookup the address for a hostname and were given a valid numeric string.
static struct GNUNET_RESOLVER_RequestHandle * req_tail
Tail of DLL of requests.
static char * no_resolve(int af, const void *ip, socklen_t ip_len)
Convert IP address to string without DNS resolution.
static void check_disconnect()
Consider disconnecting if we have no further requests pending.
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
static int check_config()
Check that the resolver service runs on localhost (or equivalent).
static const char * loopback[]
Possible hostnames for "loopback".
static void loopback_resolution(void *cls)
We've been asked to lookup the address for a hostname and were given a variant of "loopback".
static void shutdown_task(void *cls)
Task executed on system shutdown.
static void mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
static struct GNUNET_SCHEDULER_Task * s_task
Task ID of shutdown task; only present while we have a connection to the resolver service.
static uint32_t last_request_id
ID of the last request we sent to the service.
static struct GNUNET_TIME_Relative backoff
How long should we wait to reconnect?
static void handle_response(void *cls, const struct GNUNET_RESOLVER_ResponseMessage *msg)
Check validity of response with a hostname for a DNS lookup.
static void numeric_reverse(void *cls)
We've been asked to convert an address to a string without a reverse lookup, either because the clien...
static void process_requests()
Process pending requests to the resolver.
static const struct GNUNET_CONFIGURATION_Handle * resolver_cfg
Configuration.
static struct GNUNET_RESOLVER_RequestHandle * req_head
Head of DLL of requests.
static struct GNUNET_SCHEDULER_Task * r_task
Task for reconnecting.
static void handle_lookup_timeout(void *cls)
A DNS resolution timed out.
static int check_response(void *cls, const struct GNUNET_RESOLVER_ResponseMessage *msg)
Check validity of response with a hostname for a DNS lookup.
#define LOG_STRERROR(kind, syscall)
static void reconnect_task(void *cls)
Now try to reconnect to the resolver service.
Handle to a message queue.
Message handler for a specific message type.
Request for the resolver.
Handle to a request given to the resolver.
struct GNUNET_SCHEDULER_Task * task
Task handle for making reply callbacks in numeric lookups asynchronous, and for timeout handling.
GNUNET_RESOLVER_HostnameCallback name_callback
Callback if this is a reverse lookup request, otherwise NULL.
int was_queued
Did we add this request to the queue?
struct GNUNET_RESOLVER_RequestHandle * next
Next entry in DLL of requests.
void * cls
Closure for the callbacks.
int was_transmitted
Has this request been transmitted to the service? GNUNET_YES if transmitted GNUNET_NO if not transmit...
size_t data_len
Length of the data that follows this struct.
GNUNET_RESOLVER_AddressCallback addr_callback
Callback if this is an name resolution request, otherwise NULL.
int af
Desired address family.
uint32_t id
Identifies the request.
struct GNUNET_TIME_Absolute timeout
When should this request time out?
struct GNUNET_RESOLVER_RequestHandle * prev
Previous entry in DLL of requests.
int received_response
GNUNET_YES if a response was received
int direction
Desired direction (IP to name or name to IP)
Entry in list of pending tasks.
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.