+++ /dev/null
-INCLUDES = -I$(top_srcdir)/src/include
-
-if MINGW
- WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
-endif
-
-if USE_COVERAGE
- AM_CFLAGS = --coverage -O0
- XLIB = -lgcov
-endif
-
-
-lib_LTLIBRARIES = libgnunetresolver.la
-
-libgnunetresolver_la_SOURCES = \
- resolver_api.c resolver.h
-libgnunetresolver_la_LIBADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(GN_LIBINTL) $(XLIB)
-libgnunetresolver_la_LDFLAGS = \
- $(GN_LIB_LDFLAGS) $(WINFLAGS) \
- -version-info 0:0:0
-
-
-bin_PROGRAMS = \
- gnunet-service-resolver
-
-gnunet_service_resolver_SOURCES = \
- gnunet-service-resolver.c
-gnunet_service_resolver_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(GN_LIBINTL)
-
-
-check_PROGRAMS = \
- test_resolver_api
-
-TESTS = $(check_PROGRAMS)
-
-test_resolver_api_SOURCES = \
- test_resolver_api.c
-test_resolver_api_LDADD = \
- $(top_builddir)/src/resolver/libgnunetresolver.la \
- $(top_builddir)/src/util/libgnunetutil.la
-
-EXTRA_DIST = \
- test_resolver_api_data.conf
+++ /dev/null
-/*
- This file is part of GNUnet.
- (C) 2007, 2008, 2009 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 2, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file resolver/gnunet-service-resolver.c
- * @brief code to do DNS resolution
- * @author Christian Grothoff
- */
-
-#include <stdlib.h>
-#include "platform.h"
-#include "gnunet_disk_lib.h"
-#include "gnunet_getopt_lib.h"
-#include "gnunet_protocols.h"
-#include "gnunet_service_lib.h"
-#include "gnunet_statistics_service.h"
-#include "gnunet_strings_lib.h"
-#include "gnunet_time_lib.h"
-#include "resolver.h"
-
-
-struct IPCache
-{
- struct IPCache *next;
- char *addr;
- struct sockaddr *sa;
- struct GNUNET_TIME_Absolute last_refresh;
- struct GNUNET_TIME_Absolute last_request;
- unsigned int salen;
-};
-
-
-static struct IPCache *head;
-
-
-
-
-#if HAVE_GETNAMEINFO
-static void
-getnameinfo_resolve (struct IPCache *cache)
-{
- char hostname[256];
-
- if (0 == getnameinfo (cache->sa,
- cache->salen,
- hostname,
- sizeof(hostname),
- NULL, 0, 0))
- cache->addr = GNUNET_strdup (hostname);
-}
-#endif
-
-
-#if HAVE_GETHOSTBYADDR
-static void
-gethostbyaddr_resolve (struct IPCache *cache)
-{
- struct hostent *ent;
-
- switch (cache->sa->sa_family)
- {
- case AF_INET:
- ent = gethostbyaddr (&((struct sockaddr_in *) cache->sa)->sin_addr,
- sizeof (struct in_addr), AF_INET);
- break;
- case AF_INET6:
- ent = gethostbyaddr (&((struct sockaddr_in6 *) cache->sa)->sin6_addr,
- sizeof (struct in6_addr), AF_INET6);
- break;
- default:
- ent = NULL;
- }
- if (ent != NULL)
- cache->addr = GNUNET_strdup (ent->h_name);
-}
-#endif
-
-
-static void
-cache_resolve (struct IPCache *cache)
-{
-#if HAVE_GETNAMEINFO
- if (cache->addr == NULL)
- getnameinfo_resolve (cache);
-#endif
-#if HAVE_GETHOSTBYADDR
- if (cache->addr == NULL)
- gethostbyaddr_resolve (cache);
-#endif
-}
-
-
-
-/**
- * Get an IP address as a string (works for both IPv4 and IPv6). Note
- * that the resolution happens asynchronously and that the first call
- * may not immediately result in the FQN (but instead in a
- * human-readable IP address).
- *
- * @param sa should be of type "struct sockaddr*"
- */
-static void
-get_ip_as_string (struct GNUNET_SERVER_Client *client,
- const struct sockaddr *sav, socklen_t salen)
-{
- struct IPCache *cache;
- struct IPCache *prev;
- struct GNUNET_TIME_Absolute now;
- struct GNUNET_SERVER_TransmitContext *tc;
-
- if (salen < sizeof (struct sockaddr))
- {
- GNUNET_break (0);
- return;
- }
- now = GNUNET_TIME_absolute_get ();
- cache = head;
- prev = NULL;
- while ((cache != NULL) &&
- ((cache->salen != salen) || (0 != memcmp (cache->sa, sav, salen))))
- {
- if (GNUNET_TIME_absolute_get_duration (cache->last_request).value <
- 60 * 60 * 1000)
- {
- if (prev != NULL)
- {
- prev->next = cache->next;
- GNUNET_free_non_null (cache->addr);
- GNUNET_free (cache->sa);
- GNUNET_free (cache);
- cache = prev->next;
- }
- else
- {
- head = cache->next;
- GNUNET_free_non_null (cache->addr);
- GNUNET_free (cache->sa);
- GNUNET_free (cache);
- cache = head;
- }
- continue;
- }
- prev = cache;
- cache = cache->next;
- }
- if (cache != NULL)
- {
- cache->last_request = now;
- if (GNUNET_TIME_absolute_get_duration (cache->last_request).value <
- 60 * 60 * 1000)
- {
- GNUNET_free_non_null (cache->addr);
- cache->addr = NULL;
- cache->salen = 0;
- cache_resolve (cache);
- }
- }
- else
- {
- cache = GNUNET_malloc (sizeof (struct IPCache));
- cache->next = head;
- cache->salen = salen;
- cache->sa = GNUNET_malloc (salen);
- memcpy (cache->sa, sav, salen);
- cache->last_request = GNUNET_TIME_absolute_get ();
- cache->last_refresh = GNUNET_TIME_absolute_get ();
- cache->addr = NULL;
- cache_resolve (cache);
- head = cache;
- }
- tc = GNUNET_SERVER_transmit_context_create (client);
- if (cache->addr != NULL)
- GNUNET_SERVER_transmit_context_append (tc,
- cache->addr,
- strlen (cache->addr) + 1,
- GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
- GNUNET_SERVER_transmit_context_append (tc, NULL, 0,
- GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
- GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
-}
-
-
-#if HAVE_GETADDRINFO
-static int
-getaddrinfo_resolve (struct GNUNET_SERVER_TransmitContext *tc,
- const char *hostname, int domain)
-{
- int s;
- struct addrinfo hints;
- struct addrinfo *result;
- struct addrinfo *pos;
-
- memset (&hints, 0, sizeof (struct addrinfo));
-// FIXME in PlibC
-#ifndef MINGW
- hints.ai_family = domain;
-#else
- hints.ai_family = AF_INET;
-#endif
- hints.ai_socktype = SOCK_STREAM; /* go for TCP */
-
- if (0 != (s = getaddrinfo (hostname, NULL, &hints, &result)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _("Could not resolve `%s' (%s): %s\n"), hostname,
- (domain ==
- AF_INET) ? "IPv4" : ((domain ==
- AF_INET6) ? "IPv6" : "any"),
- gai_strerror (s));
- if ((s == EAI_BADFLAGS) || (s == EAI_MEMORY) ||
-#ifndef MINGW
- (s == EAI_SYSTEM)
-#else
- // FIXME NILS
- 1
-#endif
- )
- return GNUNET_NO; /* other function may still succeed */
- return GNUNET_SYSERR;
- }
- if (result == NULL)
- return GNUNET_SYSERR;
- pos = result;
- while (pos != NULL)
- {
- GNUNET_SERVER_transmit_context_append (tc,
- result->ai_addr,
- result->ai_addrlen,
- GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
- pos = pos->ai_next;
- }
- freeaddrinfo (result);
- return GNUNET_OK;
-}
-#endif
-
-#if HAVE_GETHOSTBYNAME2
-static int
-gethostbyname2_resolve (struct GNUNET_SERVER_TransmitContext *tc,
- const char *hostname, int domain)
-{
- struct hostent *hp;
- struct sockaddr_in a4;
- struct sockaddr_in6 a6;
- int ret1;
- int ret2;
-
- if (domain == AF_UNSPEC)
- {
- ret1 = gethostbyname2_resolve (tc, hostname, AF_INET);
- ret2 = gethostbyname2_resolve (tc, hostname, AF_INET6);
- if ((ret1 == GNUNET_OK) || (ret2 == GNUNET_OK))
- return GNUNET_OK;
- if ((ret1 == GNUNET_SYSERR) || (ret2 == GNUNET_SYSERR))
- return GNUNET_SYSERR;
- return GNUNET_NO;
- }
- hp = gethostbyname2 (hostname, domain);
- if (hp == NULL)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _("Could not find IP of host `%s': %s\n"),
- hostname, hstrerror (h_errno));
- return GNUNET_SYSERR;
- }
- GNUNET_assert (hp->h_addrtype == domain);
- if (domain == AF_INET)
- {
- GNUNET_assert (hp->h_length == sizeof (struct in_addr));
- memset (&a4, 0, sizeof (a4));
- a4.sin_family = AF_INET;
- memcpy (&a4.sin_addr, hp->h_addr_list[0], hp->h_length);
- GNUNET_SERVER_transmit_context_append (tc,
- &a4,
- sizeof (a4),
- GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
- }
- else
- {
- GNUNET_assert (hp->h_length == sizeof (struct in6_addr));
- memset (&a6, 0, sizeof (a6));
- a6.sin6_family = AF_INET6;
- memcpy (&a6.sin6_addr, hp->h_addr_list[0], hp->h_length);
- GNUNET_SERVER_transmit_context_append (tc,
- &a6,
- sizeof (a6),
- GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
- }
- return GNUNET_OK;
-}
-#endif
-
-#if HAVE_GETHOSTBYNAME
-static int
-gethostbyname_resolve (struct GNUNET_SERVER_TransmitContext *tc,
- const char *hostname)
-{
- struct hostent *hp;
- struct sockaddr_in addr;
-
- hp = GETHOSTBYNAME (hostname);
- if (hp == NULL)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _("Could not find IP of host `%s': %s\n"),
- hostname, hstrerror (h_errno));
- return GNUNET_SYSERR;
- }
- if (hp->h_addrtype != AF_INET)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- GNUNET_assert (hp->h_length == sizeof (struct in_addr));
- memset (&addr, 0, sizeof (addr));
- addr.sin_family = AF_INET;
- memcpy (&addr.sin_addr, hp->h_addr_list[0], hp->h_length);
- GNUNET_SERVER_transmit_context_append (tc,
- &addr,
- sizeof (addr),
- GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
- return GNUNET_OK;
-}
-#endif
-
-
-/**
- * Convert a string to an IP address.
- *
- * @param client where to send the IP address
- * @param hostname the hostname to resolve
- * @param domain AF_INET or AF_INET6; use AF_UNSPEC for "any"
- */
-static void
-get_ip_from_hostname (struct GNUNET_SERVER_Client *client,
- const char *hostname, int domain)
-{
- int ret;
- struct GNUNET_SERVER_TransmitContext *tc;
-
- tc = GNUNET_SERVER_transmit_context_create (client);
- ret = GNUNET_NO;
-#if HAVE_GETADDRINFO
- if (ret == GNUNET_NO)
- ret = getaddrinfo_resolve (tc, hostname, domain);
-#endif
-#if HAVE_GETHOSTBYNAME2
- if (ret == GNUNET_NO)
- ret = gethostbyname2_resolve (tc, hostname, domain);
-#endif
-#if HAVE_GETHOSTBYNAME
- if ((ret == GNUNET_NO) && ((domain == AF_UNSPEC) || (domain == PF_INET)))
- gethostbyname_resolve (tc, hostname);
-#endif
- GNUNET_SERVER_transmit_context_append (tc, NULL, 0,
- GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
- GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
-}
-
-
-/**
- * Handle GET-message.
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message
- */
-static void
-handle_get (void *cls,
- struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- uint16_t msize;
- const struct GNUNET_RESOLVER_GetMessage *msg;
- const char *hostname;
- uint16_t size;
- int direction;
- int domain;
-
- msize = ntohs (message->size);
- if (msize < sizeof (struct GNUNET_RESOLVER_GetMessage))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- msg = (const struct GNUNET_RESOLVER_GetMessage *) message;
- size = msize - sizeof (struct GNUNET_RESOLVER_GetMessage);
- direction = ntohl (msg->direction);
- domain = ntohl (msg->domain);
- if (direction == GNUNET_NO)
- {
- /* IP from hostname */
- hostname = (const char *) &msg[1];
- if (hostname[size - 1] != '\0')
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-#if DEBUG_RESOLVER
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- _("Resolver asked to look up `%s'.\n"), hostname);
-#endif
- get_ip_from_hostname (client, hostname, domain);
- }
- else
- {
-#if DEBUG_RESOLVER
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- _("Resolver asked to look up IP address.\n"));
-#endif
- get_ip_as_string (client, (const struct sockaddr *) &msg[1], size);
- }
-}
-
-
-/**
- * List of handlers for the messages understood by this
- * service.
- */
-static struct GNUNET_SERVER_MessageHandler handlers[] = {
- {&handle_get, NULL, GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST, 0},
- {NULL, NULL, 0, 0}
-};
-
-
-/**
- * Process resolver requests.
- *
- * @param cls closure
- * @param sched scheduler to use
- * @param server the initialized server
- * @param cfg configuration to use
- */
-static void
-run (void *cls,
- struct GNUNET_SCHEDULER_Handle *sched,
- struct GNUNET_SERVER_Handle *server,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- GNUNET_SERVER_add_handlers (server, handlers);
-}
-
-
-/**
- * The main function for the resolver service.
- *
- * @param argc number of arguments from the command line
- * @param argv command line arguments
- * @return 0 ok, 1 on error
- */
-int
-main (int argc, char *const *argv)
-{
- int ret;
- struct IPCache *pos;
-
- ret = (GNUNET_OK ==
- GNUNET_SERVICE_run (argc,
- argv,
- "resolver", &run, NULL, NULL, NULL)) ? 0 : 1;
-
- while (head != NULL)
- {
- pos = head->next;
- GNUNET_free_non_null (head->addr);
- GNUNET_free (head->sa);
- GNUNET_free (head);
- head = pos;
- }
- return ret;
-}
-
-/* end of gnunet-service-resolver.c */
+++ /dev/null
-/*
- This file is part of GNUnet.
- (C) 2009 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 2, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @author Christian Grothoff
- * @file resolver/resolver.h
- */
-#ifndef RESOLVER_H
-#define RESOLVER_H
-
-#include "gnunet_common.h"
-
-#define DEBUG_RESOLVER GNUNET_NO
-
-/**
- * Request for the resolver. Followed by either
- * the "struct sockaddr" or the 0-terminated hostname.
- *
- * The response will be one or more messages of type
- * RESOLVER_RESPONSE, each with the message header
- * immediately followed by the requested data
- * (hostname or struct sockaddr, depending on direction).
- * The last RESOLVER_RESPONSE will just be a header
- * without any data (used to indicate the end of the list).
- */
-struct GNUNET_RESOLVER_GetMessage
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_STATISTICS_VALUE
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * GNUNET_YES to get hostname from IP,
- * GNUNET_NO to get IP from hostname.
- */
- int32_t direction GNUNET_PACKED;
-
- /**
- * Domain to use (AF_INET, AF_INET6 or AF_UNSPEC).
- */
- int32_t domain GNUNET_PACKED;
-
-};
-
-#endif
+++ /dev/null
-/*
- This file is part of GNUnet.
- (C) 2009 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 2, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file resolver/resolver_api.c
- * @brief resolver for writing a tool
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "gnunet_getopt_lib.h"
-#include "gnunet_client_lib.h"
-#include "gnunet_protocols.h"
-#include "gnunet_resolver_service.h"
-#include "gnunet_server_lib.h"
-#include "resolver.h"
-
-
-/**
- * FIXME.
- */
-struct GetAddressContext
-{
-
- /**
- * FIXME.
- */
- GNUNET_RESOLVER_AddressCallback callback;
-
- /**
- * Closure for "callback".
- */
- void *cls;
-
- /**
- * FIXME.
- */
- struct GNUNET_RESOLVER_GetMessage *msg;
-
- /**
- * FIXME.
- */
- struct GNUNET_CLIENT_Connection *client;
-
- /**
- * FIXME.
- */
- struct GNUNET_TIME_Absolute timeout;
-};
-
-
-/**
- * Possible hostnames for "loopback".
- */
-static const char *loopback[] = {
- "localhost",
- "127.0.0.1",
- "ip6-localnet",
- "::1",
- NULL
-};
-
-
-/**
- * Check that the resolver service runs on localhost
- * (or equivalent).
- */
-static void
-check_config (const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- char *hostname;
- unsigned int i;
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg,
- "resolver",
- "HOSTNAME",
- &hostname))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _("Must specify `%s' for `%s' in configuration!\n"),
- "HOSTNAME",
- "resolver");
- GNUNET_assert (0);
- }
- i = 0;
- while (loopback[i] != NULL)
- if (0 == strcmp (loopback[i++], hostname))
- {
- GNUNET_free (hostname);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _("Must specify `%s' for `%s' in configuration!\n"),
- "localhost",
- "resolver");
- GNUNET_free (hostname);
- GNUNET_assert (0);
-}
-
-
-/**
- * Convert IP address to string without DNS resolution.
- */
-static char *
-no_resolve (const struct sockaddr *sa, socklen_t salen)
-{
- char *ret;
- char inet4[INET_ADDRSTRLEN];
- char inet6[INET6_ADDRSTRLEN];
-
- if (salen < sizeof (struct sockaddr))
- return NULL;
- switch (sa->sa_family)
- {
- case AF_INET:
- if (salen != sizeof (struct sockaddr_in))
- return NULL;
- inet_ntop (AF_INET,
- &((struct sockaddr_in *) sa)->sin_addr,
- inet4, INET_ADDRSTRLEN);
- ret = GNUNET_strdup (inet4);
- break;
- case AF_INET6:
- if (salen != sizeof (struct sockaddr_in6))
- return NULL;
- inet_ntop (AF_INET6,
- &((struct sockaddr_in6 *) sa)->sin6_addr,
- inet6, INET6_ADDRSTRLEN);
- ret = GNUNET_strdup (inet6);
- break;
- default:
- ret = NULL;
- break;
- }
- return ret;
-}
-
-
-static void
-handle_address_response (void *cls, const struct GNUNET_MessageHeader *msg)
-{
- struct GetAddressContext *gac = cls;
- uint16_t size;
- const struct sockaddr *sa;
- socklen_t salen;
-
-
- if (msg == NULL)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _("Timeout trying to resolve hostname.\n"));
- gac->callback (gac->cls, NULL, 0);
- GNUNET_CLIENT_disconnect (gac->client);
- GNUNET_free (gac);
- return;
- }
- if (GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE != ntohs (msg->type))
- {
- GNUNET_break (0);
- gac->callback (gac->cls, NULL, 0);
- GNUNET_CLIENT_disconnect (gac->client);
- GNUNET_free (gac);
- return;
- }
-
- size = ntohs (msg->size);
- if (size == sizeof (struct GNUNET_MessageHeader))
- {
-#if DEBUG_RESOLVER
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- _("Received end message resolving hostname.\n"));
-#endif
- gac->callback (gac->cls, NULL, 0);
- GNUNET_CLIENT_disconnect (gac->client);
- GNUNET_free (gac);
- return;
- }
- sa = (const struct sockaddr *) &msg[1];
- salen = size - sizeof (struct GNUNET_MessageHeader);
- if (salen < sizeof (struct sockaddr))
- {
- GNUNET_break (0);
- gac->callback (gac->cls, NULL, 0);
- GNUNET_CLIENT_disconnect (gac->client);
- GNUNET_free (gac);
- return;
- }
-#if DEBUG_RESOLVER
- {
- char *ips = no_resolve (sa, salen);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Resolver returns `%s'.\n"), ips);
- GNUNET_free (ips);
- }
-#endif
- gac->callback (gac->cls, sa, salen);
- GNUNET_CLIENT_receive (gac->client,
- &handle_address_response,
- gac,
- GNUNET_TIME_absolute_get_remaining (gac->timeout));
-}
-
-
-static size_t
-transmit_get_ip (void *cls, size_t size, void *buf)
-{
- struct GetAddressContext *actx = cls;
- uint16_t ms;
-
- if (buf == NULL)
- {
- /* timeout / error */
- GNUNET_free (actx->msg);
- actx->callback (actx->cls, NULL, 0);
- GNUNET_CLIENT_disconnect (actx->client);
- GNUNET_free (actx);
- return 0;
- }
- ms = ntohs (actx->msg->header.size);
- GNUNET_assert (size >= ms);
- memcpy (buf, actx->msg, ms);
- GNUNET_free (actx->msg);
- actx->msg = NULL;
- GNUNET_CLIENT_receive (actx->client,
- &handle_address_response,
- actx,
- GNUNET_TIME_absolute_get_remaining (actx->timeout));
- return ms;
-}
-
-
-
-/**
- * Convert a string to one or more IP addresses.
- *
- * @param sched scheduler to use
- * @param cfg configuration to use
- * @param hostname the hostname to resolve
- * @param domain AF_INET or AF_INET6; use AF_UNSPEC for "any"
- * @param callback function to call with addresses
- * @param callback_cls closure for callback
- * @param timeout how long to try resolving
- */
-void
-GNUNET_RESOLVER_ip_get (struct GNUNET_SCHEDULER_Handle *sched,
- const struct GNUNET_CONFIGURATION_Handle *cfg,
- const char *hostname,
- int domain,
- struct GNUNET_TIME_Relative timeout,
- GNUNET_RESOLVER_AddressCallback callback,
- void *callback_cls)
-{
- struct GNUNET_CLIENT_Connection *client;
- struct GNUNET_RESOLVER_GetMessage *msg;
- struct GetAddressContext *actx;
- size_t slen;
- unsigned int i;
- struct sockaddr_in v4;
- struct sockaddr_in6 v6;
-
- check_config (cfg);
- i = 0;
- while (loopback[i] != NULL)
- if (0 == strcmp (loopback[i++], hostname))
- {
- memset (&v4, 0, sizeof(v4));
-#if HAVE_SOCKADDR_IN_SIN_LEN
- v4.sin_len = sizeof (v4);
-#endif
- v4.sin_family = AF_INET;
- v4.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-
- memset (&v6, 0, sizeof(v6));
-#if HAVE_SOCKADDR_IN_SIN_LEN
- v6.sin6_len = sizeof (v6);
-#endif
- v6.sin6_family = AF_INET6;
- v6.sin6_addr = in6addr_loopback;
-
- switch (domain)
- {
- case AF_INET:
- callback (callback_cls,
- (const struct sockaddr*) &v4,
- sizeof(v4));
- break;
- case AF_INET6:
- callback (callback_cls,
- (const struct sockaddr*) &v6,
- sizeof(v6));
- break;
- case AF_UNSPEC:
- callback (callback_cls,
- (const struct sockaddr*) &v4,
- sizeof(v4));
- callback (callback_cls,
- (const struct sockaddr*) &v6,
- sizeof(v6));
- break;
- }
- callback (callback_cls, NULL, 0);
- return;
- }
- slen = strlen (hostname) + 1;
- if (slen + sizeof (struct GNUNET_RESOLVER_GetMessage) >
- GNUNET_SERVER_MAX_MESSAGE_SIZE)
- {
- GNUNET_break (0);
- callback (callback_cls, NULL, 0);
- return;
- }
- client = GNUNET_CLIENT_connect (sched, "resolver", cfg);
- if (client == NULL)
- {
- callback (callback_cls, NULL, 0);
- return;
- }
- msg = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_GetMessage) + slen);
- msg->header.size =
- htons (sizeof (struct GNUNET_RESOLVER_GetMessage) + slen);
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST);
- msg->direction = htonl (GNUNET_NO);
- msg->domain = htonl (domain);
- memcpy (&msg[1], hostname, slen);
- actx = GNUNET_malloc (sizeof (struct GetAddressContext));
- actx->callback = callback;
- actx->cls = callback_cls;
- actx->client = client;
- actx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
- actx->msg = msg;
-
-#if DEBUG_RESOLVER
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- _("Resolver requests DNS resolution of hostname `%s'.\n"),
- hostname);
-#endif
- if (NULL ==
- GNUNET_CLIENT_notify_transmit_ready (client,
- slen +
- sizeof (struct
- GNUNET_RESOLVER_GetMessage),
- timeout, &transmit_get_ip, actx))
- {
- GNUNET_free (msg);
- GNUNET_free (actx);
- callback (callback_cls, NULL, 0);
- GNUNET_CLIENT_disconnect (client);
- return;
- }
-}
-
-
-struct GetHostnameContext
-{
- GNUNET_RESOLVER_HostnameCallback callback;
- void *cls;
- struct GNUNET_RESOLVER_GetMessage *msg;
- struct GNUNET_CLIENT_Connection *client;
- struct GNUNET_TIME_Absolute timeout;
-};
-
-
-static void
-handle_hostname_response (void *cls, const struct GNUNET_MessageHeader *msg)
-{
- struct GetHostnameContext *ghc = cls;
- uint16_t size;
- const char *hostname;
-
- if (msg == NULL)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _("Timeout trying to resolve IP address.\n"));
- ghc->callback (ghc->cls, NULL);
- GNUNET_CLIENT_disconnect (ghc->client);
- GNUNET_free (ghc);
- return;
- }
- size = ntohs (msg->size);
- if (size == sizeof (struct GNUNET_MessageHeader))
- {
-#if DEBUG_RESOLVER
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- _("Received end message resolving IP address.\n"));
-#endif
- ghc->callback (ghc->cls, NULL);
- GNUNET_CLIENT_disconnect (ghc->client);
- GNUNET_free (ghc);
- return;
- }
- hostname = (const char *) &msg[1];
- if (hostname[size - sizeof (struct GNUNET_MessageHeader) - 1] != '\0')
- {
- GNUNET_break (0);
- ghc->callback (ghc->cls, NULL);
- GNUNET_CLIENT_disconnect (ghc->client);
- GNUNET_free (ghc);
- return;
- }
-#if DEBUG_RESOLVER
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- _("Resolver returns `%s'.\n"), hostname);
-#endif
- ghc->callback (ghc->cls, hostname);
- GNUNET_CLIENT_receive (ghc->client,
- &handle_hostname_response,
- ghc,
- GNUNET_TIME_absolute_get_remaining (ghc->timeout));
-}
-
-
-static size_t
-transmit_get_hostname (void *cls, size_t size, void *buf)
-{
- struct GetHostnameContext *hctx = cls;
- uint16_t msize;
-
- if (buf == NULL)
- {
- GNUNET_free (hctx->msg);
- hctx->callback (hctx->cls, NULL);
- GNUNET_CLIENT_disconnect (hctx->client);
- GNUNET_free (hctx);
- return 0;
- }
- msize = ntohs (hctx->msg->header.size);
- GNUNET_assert (size >= msize);
- memcpy (buf, hctx->msg, msize);
- GNUNET_free (hctx->msg);
- hctx->msg = NULL;
- GNUNET_CLIENT_receive (hctx->client,
- &handle_hostname_response,
- hctx,
- GNUNET_TIME_absolute_get_remaining (hctx->timeout));
- return msize;
-}
-
-
-
-
-/**
- * Get an IP address as a string.
- *
- * @param sched scheduler to use
- * @param cfg configuration to use
- * @param sa host address
- * @param salen length of host address
- * @param do_resolve use GNUNET_NO to return numeric hostname
- * @param timeout how long to try resolving
- * @param callback function to call with hostnames
- * @param cls closure for callback
- */
-void
-GNUNET_RESOLVER_hostname_get (struct GNUNET_SCHEDULER_Handle *sched,
- const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct sockaddr *sa,
- socklen_t salen,
- int do_resolve,
- struct GNUNET_TIME_Relative timeout,
- GNUNET_RESOLVER_HostnameCallback callback,
- void *cls)
-{
- char *result;
- struct GNUNET_CLIENT_Connection *client;
- struct GNUNET_RESOLVER_GetMessage *msg;
- struct GetHostnameContext *hctx;
-
- check_config (cfg);
- if (GNUNET_NO == do_resolve)
- {
- result = no_resolve (sa, salen);
-#if DEBUG_RESOLVER
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- _("Resolver returns `%s'.\n"), result);
-#endif
- callback (cls, result);
- if (result != NULL)
- {
- GNUNET_free (result);
- callback (cls, NULL);
- }
- return;
- }
- if (salen + sizeof (struct GNUNET_RESOLVER_GetMessage) >
- GNUNET_SERVER_MAX_MESSAGE_SIZE)
- {
- GNUNET_break (0);
- callback (cls, NULL);
- return;
- }
- client = GNUNET_CLIENT_connect (sched, "resolver", cfg);
- if (client == NULL)
- {
- callback (cls, NULL);
- return;
- }
- msg = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_GetMessage) + salen);
- msg->header.size =
- htons (sizeof (struct GNUNET_RESOLVER_GetMessage) + salen);
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST);
- msg->direction = htonl (GNUNET_YES);
- msg->domain = htonl (sa->sa_family);
- memcpy (&msg[1], sa, salen);
-#if DEBUG_RESOLVER
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- _("Resolver requests DNS resolution of IP address.\n"));
-#endif
- hctx = GNUNET_malloc (sizeof (struct GetHostnameContext));
- hctx->callback = callback;
- hctx->cls = cls;
- hctx->client = client;
- hctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
- hctx->msg = msg;
- if (NULL ==
- GNUNET_CLIENT_notify_transmit_ready (client,
- sizeof (struct
- GNUNET_RESOLVER_GetMessage)
- + salen, timeout,
- &transmit_get_hostname, hctx))
- {
- GNUNET_free (msg);
- callback (cls, NULL);
- GNUNET_CLIENT_disconnect (client);
- GNUNET_free (hctx);
- }
-}
-
-/**
- * Maximum supported length of hostname
- */
-#define MAX_HOSTNAME 1024
-
-
-/**
- * Resolve our hostname to an IP address.
- *
- * @param sched scheduler to use
- * @param cfg configuration to use
- * @param domain AF_INET or AF_INET6; use AF_UNSPEC for "any"
- * @param callback function to call with addresses
- * @param cls closure for callback
- * @param timeout how long to try resolving
- */
-void
-GNUNET_RESOLVER_hostname_resolve (struct GNUNET_SCHEDULER_Handle *sched,
- const struct GNUNET_CONFIGURATION_Handle *cfg,
- int domain,
- struct GNUNET_TIME_Relative timeout,
- GNUNET_RESOLVER_AddressCallback callback,
- void *cls)
-{
- char hostname[MAX_HOSTNAME];
-
- check_config (cfg);
- if (0 != gethostname (hostname, sizeof (hostname) - 1))
- {
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR |
- GNUNET_ERROR_TYPE_BULK, "gethostname");
- callback (cls, NULL, 0);
- return;
- }
-#if DEBUG_RESOLVER
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- _("Resolving our hostname `%s'\n"), hostname);
-#endif
- GNUNET_RESOLVER_ip_get (sched,
- cfg, hostname, domain, timeout, callback, cls);
-}
-
-
-
-
-/* end of resolver_api.c */
+++ /dev/null
-/*
- This file is part of GNUnet.
- (C) 2009 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 2, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-/**
- * @file resolver/test_resolver_api.c
- * @brief testcase for resolver_api.c
- */
-#include "platform.h"
-#include "gnunet_common.h"
-#include "gnunet_getopt_lib.h"
-#include "gnunet_os_lib.h"
-#include "gnunet_program_lib.h"
-#include "gnunet_scheduler_lib.h"
-#include "gnunet_resolver_service.h"
-#include "resolver.h"
-
-#define VERBOSE GNUNET_NO
-
-
-static void
-check_hostname (void *cls, const struct sockaddr *sa, socklen_t salen)
-{
- int *ok = cls;
-
- if (salen == 0)
- {
- (*ok) &= ~8;
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _("Got IP address `%s' for our host.\n"),
- GNUNET_a2s (sa, salen));
-}
-
-
-static void
-check_localhost_num (void *cls, const char *hostname)
-{
- int *ok = cls;
- if (hostname == NULL)
- return;
- if (0 == strcmp (hostname, "127.0.0.1"))
- {
-#if DEBUG_RESOLVER
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received correct hostname `%s'.\n", hostname);
-#endif
- (*ok) &= ~4;
- }
- else
- {
-#if DEBUG_RESOLVER
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received invalid hostname `%s'.\n", hostname);
-#endif
- GNUNET_break (0);
- }
-}
-
-static void
-check_localhost (void *cls, const char *hostname)
-{
- int *ok = cls;
- if (hostname == NULL)
- return;
- if (0 == strcmp (hostname, "localhost"))
- {
-#if DEBUG_RESOLVER
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received correct hostname `%s'.\n", hostname);
-#endif
- (*ok) &= ~2;
- }
- else
- {
-#if DEBUG_RESOLVER
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received invalid hostname `%s'.\n", hostname);
-#endif
- GNUNET_break (0);
- }
-}
-
-static void
-check_127 (void *cls, const struct sockaddr *sa, socklen_t salen)
-{
- int *ok = cls;
- const struct sockaddr_in *sai = (const struct sockaddr_in *) sa;
-
- if (sa == NULL)
- return;
- GNUNET_assert (sizeof (struct sockaddr_in) == salen);
- if (sai->sin_addr.s_addr == htonl (INADDR_LOOPBACK))
- {
-#if DEBUG_RESOLVER
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received correct address.\n");
-#endif
- (*ok) &= ~1;
- }
- else
- {
-#if DEBUG_RESOLVER
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received incorrect address.\n");
-#endif
- GNUNET_break (0);
- }
-}
-
-static void
-run (void *cls,
- struct GNUNET_SCHEDULER_Handle *sched,
- char *const *args,
- const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- struct sockaddr_in sa;
- struct GNUNET_TIME_Relative timeout =
- GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
- 2500);
- memset (&sa, 0, sizeof (sa));
- sa.sin_family = AF_INET;
- sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
- GNUNET_RESOLVER_ip_get (sched,
- cfg,
- "localhost", AF_INET, timeout, &check_127, cls);
- GNUNET_RESOLVER_hostname_get (sched,
- cfg,
- (const struct sockaddr *) &sa,
- sizeof (struct sockaddr),
- GNUNET_YES, timeout, &check_localhost, cls);
- GNUNET_RESOLVER_hostname_get (sched,
- cfg,
- (const struct sockaddr *) &sa,
- sizeof (struct sockaddr),
- GNUNET_NO,
- timeout, &check_localhost_num, cls);
- GNUNET_RESOLVER_hostname_resolve (sched,
- cfg,
- AF_UNSPEC, timeout, &check_hostname, cls);
-}
-
-static int
-check ()
-{
- int ok = 1 + 2 + 4 + 8;
- pid_t pid;
- char *const argv[] = { "test-resolver-api",
- "-c",
- "test_resolver_api_data.conf",
-#if VERBOSE
- "-L", "DEBUG",
-#endif
- NULL
- };
- struct GNUNET_GETOPT_CommandLineOption options[] = {
- GNUNET_GETOPT_OPTION_END
- };
- pid = GNUNET_OS_start_process ("gnunet-service-resolver",
- "gnunet-service-resolver",
-#if VERBOSE
- "-L", "DEBUG",
-#endif
- "-c", "test_resolver_api_data.conf", NULL);
- sleep (1);
- GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
- argv, "test-resolver-api", "nohelp",
- options, &run, &ok);
- if (0 != PLIBC_KILL (pid, SIGTERM))
- {
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
- ok = 1;
- }
- GNUNET_OS_process_wait(pid);
- if (ok != 0)
- fprintf (stderr, "Missed some resolutions: %u\n", ok);
- return ok;
-}
-
-int
-main (int argc, char *argv[])
-{
- int ret;
-
- GNUNET_log_setup ("test-resolver-api",
-#if VERBOSE
- "DEBUG",
-#else
- "WARNING",
-#endif
- NULL);
- ret = check ();
-
- return ret;
-}
-
-/* end of test_resolver_api.c */
+++ /dev/null
-[PATHS]
-SERVICEHOME = /tmp/test-gnunetd-statistics/
-
-[resolver]
-PORT = 22354