#include "gnunet_resolver_service.h"
#include "resolver.h"
-#define LOG(kind,...) GNUNET_log_from (kind, "resolver-api", __VA_ARGS__)
+#define LOG(kind,...) GNUNET_log_from (kind, "util-resolver-api", __VA_ARGS__)
-#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "resolver-api", syscall)
+#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-resolver-api", syscall)
/**
* Maximum supported length for a hostname
void
GNUNET_RESOLVER_disconnect ()
{
- GNUNET_assert (NULL == req_head);
- GNUNET_assert (NULL == req_tail);
+ struct GNUNET_RESOLVER_RequestHandle *rh;
+
+ while (NULL != (rh = req_head))
+ {
+ GNUNET_assert (GNUNET_SYSERR == rh->was_transmitted);
+ GNUNET_CONTAINER_DLL_remove (req_head,
+ req_tail,
+ rh);
+ GNUNET_free (rh);
+ }
if (NULL != mq)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
}
+/**
+ * Task executed on system shutdown.
+ */
+static void
+shutdown_task (void *cls)
+{
+ s_task = NULL;
+ GNUNET_RESOLVER_disconnect ();
+ backoff = GNUNET_TIME_UNIT_MILLISECONDS;
+}
+
+
+/**
+ * Consider disconnecting if we have no further requests pending.
+ */
+static void
+check_disconnect ()
+{
+ struct GNUNET_RESOLVER_RequestHandle *rh;
+
+ for (rh = req_head; NULL != rh; rh = rh->next)
+ if (GNUNET_SYSERR != rh->was_transmitted)
+ return;
+ if (NULL != r_task)
+ {
+ GNUNET_SCHEDULER_cancel (r_task);
+ r_task = NULL;
+ }
+ if (NULL != s_task)
+ return;
+ s_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
+ &shutdown_task,
+ NULL);
+}
+
+
/**
* Convert IP address to string without DNS resolution.
*
{
GNUNET_MQ_destroy (mq);
mq = NULL;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "MQ error, reconnecting\n");
reconnect ();
}
-/**
- * Task executed on system shutdown.
- */
-static void
-shutdown_task (void *cls)
-{
- s_task = NULL;
- GNUNET_RESOLVER_disconnect ();
- backoff = GNUNET_TIME_UNIT_MILLISECONDS;
-}
-
-
/**
* Process pending requests to the resolver.
*/
GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST);
msg->direction = htonl (rh->direction);
msg->af = htonl (rh->af);
- memcpy (&msg[1],
+ GNUNET_memcpy (&msg[1],
&rh[1],
rh->data_len);
LOG (GNUNET_ERROR_TYPE_DEBUG,
}
if ( ( (rh->af == AF_UNSPEC) ||
(rh->af == AF_INET6) ) &&
- (1 == inet_pton (AF_INET6, hostname, &v6.sin6_addr) ) )
+ (1 == inet_pton (AF_INET6,
+ hostname,
+ &v6.sin6_addr) ) )
{
rh->addr_callback (rh->cls,
(const struct sockaddr *) &v6,
rh->addr_callback (rh->cls,
NULL,
0);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Finished resolving hostname `%s'.\n",
+ (const char *) &rh[1]);
GNUNET_free (rh);
}
static void
reconnect_task (void *cls)
{
- GNUNET_MQ_hd_var_size (response,
- GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE,
- struct GNUNET_MessageHeader);
struct GNUNET_MQ_MessageHandler handlers[] = {
- make_response_handler (NULL),
- GNUNET_MQ_handler_end ()
+ GNUNET_MQ_hd_var_size (response,
+ GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE,
+ struct GNUNET_MessageHeader,
+ NULL),
+ GNUNET_MQ_handler_end ()
};
r_task = NULL;
return; /* no work pending */
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Trying to connect to DNS service\n");
- mq = GNUNET_CLIENT_connecT (resolver_cfg,
+ mq = GNUNET_CLIENT_connect (resolver_cfg,
"resolver",
handlers,
&mq_error_handler,
req_tail,
rh);
GNUNET_free (rh);
+ check_disconnect ();
break;
default:
GNUNET_assert (0);
GNUNET_break (0);
return NULL;
}
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Trying to resolve hostname `%s'.\n",
+ hostname);
rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + slen);
rh->af = af;
rh->addr_callback = callback;
rh->cls = callback_cls;
- memcpy (&rh[1],
- hostname,
- slen);
+ GNUNET_memcpy (&rh[1],
+ hostname,
+ slen);
rh->data_len = slen;
rh->timeout = GNUNET_TIME_relative_to_absolute (timeout);
rh->direction = GNUNET_NO;
rh->cls = cls;
rh->af = sa->sa_family;
rh->timeout = GNUNET_TIME_relative_to_absolute (timeout);
- memcpy (&rh[1],
+ GNUNET_memcpy (&rh[1],
ip,
ip_len);
rh->data_len = ip_len;
void
GNUNET_RESOLVER_request_cancel (struct GNUNET_RESOLVER_RequestHandle *rh)
{
+ if (GNUNET_NO == rh->direction)
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Asked to cancel request to resolve hostname `%s'.\n",
+ (const char *) &rh[1]);
if (NULL != rh->task)
{
GNUNET_SCHEDULER_cancel (rh->task);
req_tail,
rh);
GNUNET_free (rh);
+ check_disconnect ();
return;
}
GNUNET_assert (GNUNET_YES == rh->was_transmitted);
rh->was_transmitted = GNUNET_SYSERR; /* mark as cancelled */
+ check_disconnect ();
}