+/**
+ * Closure for #append_port().
+ */
+struct PrettyPrinterContext
+{
+ /**
+ * DLL
+ */
+ struct PrettyPrinterContext *next;
+
+ /**
+ * DLL
+ */
+ struct PrettyPrinterContext *prev;
+
+ /**
+ * Resolver handle
+ */
+ struct GNUNET_RESOLVER_RequestHandle *resolver_handle;
+
+ /**
+ * Function to call with the result.
+ */
+ GNUNET_TRANSPORT_AddressStringCallback asc;
+
+ /**
+ * Clsoure for @e asc.
+ */
+ void *asc_cls;
+
+ /**
+ * Timeout task
+ */
+ struct GNUNET_SCHEDULER_Task * timeout_task;
+
+ /**
+ * Splitted Address
+ */
+ struct SplittedHTTPAddress *saddr;
+
+ /**
+ * Plugin String
+ */
+ char *plugin;
+
+ /**
+ * Was conversion successful
+ */
+ int sucess;
+
+ /**
+ * Address options
+ */
+ uint32_t options;
+};
+
+/**
+ * Head of PPC list
+ */
+static struct PrettyPrinterContext *dll_ppc_head;
+
+/**
+ * Tail of PPC list
+ */
+static struct PrettyPrinterContext *dll_ppc_tail;
+
+/**
+ * Function called for a quick conversion of the binary address to
+ * a numeric address. Note that the caller must not free the
+ * address and that the next call to this function is allowed
+ * to override the address again.
+ *
+ * @param plugin the name of the plugin
+ * @param saddr the splitted http address
+ * @param options address options
+ * @param dnsresult dns name to include in address
+ * @return string representing the same address or NULL on error
+ */
+static const char *
+http_common_plugin_dnsresult_to_address (const char *plugin,
+ const struct SplittedHTTPAddress *saddr,
+ uint32_t options,
+ const char *dnsresult)
+{
+ static char rbuf[1024];
+ char *res;
+
+ GNUNET_asprintf (&res, "%s.%u.%s://%s:%u%s", plugin, options, saddr->protocol,
+ dnsresult, saddr->port, saddr->path);
+ if (strlen (res) + 1 < 500)
+ {
+ GNUNET_memcpy (rbuf, res, strlen (res) + 1);
+ GNUNET_free(res);
+ return rbuf;
+ }
+ GNUNET_break(0);
+ GNUNET_free(res);
+ return NULL ;
+}
+
+
+static void
+http_common_dns_reverse_lookup_cb (void *cls, const char *hostname)
+{
+ struct PrettyPrinterContext *ppc = cls;
+
+ if (NULL != hostname)
+ {
+ ppc->asc (ppc->asc_cls,
+ http_common_plugin_dnsresult_to_address (ppc->plugin, ppc->saddr, ppc->options,
+ hostname), GNUNET_OK);
+ ppc->sucess = GNUNET_YES;
+
+ }
+ else
+ {
+ ppc->asc (ppc->asc_cls, NULL,
+ (GNUNET_NO == ppc->sucess) ? GNUNET_SYSERR : GNUNET_OK);
+
+ GNUNET_CONTAINER_DLL_remove(dll_ppc_head, dll_ppc_tail, ppc);
+ http_clean_splitted (ppc->saddr);
+ GNUNET_free(ppc->plugin);
+ GNUNET_free(ppc);
+ }
+}
+
+
+static int
+http_common_dns_reverse_lookup (const struct sockaddr *sockaddr,
+ socklen_t sockaddr_len,
+ const char *type,
+ struct SplittedHTTPAddress *saddr,
+ uint32_t options,
+ struct GNUNET_TIME_Relative timeout,
+ GNUNET_TRANSPORT_AddressStringCallback asc,
+ void *asc_cls)
+{
+ struct PrettyPrinterContext *ppc;
+
+ ppc = GNUNET_new (struct PrettyPrinterContext);
+ ppc->saddr = saddr;
+ ppc->asc = asc;
+ ppc->asc_cls = asc_cls;
+ ppc->plugin = GNUNET_strdup (type);
+ ppc->options = options;
+ ppc->resolver_handle = GNUNET_RESOLVER_hostname_get (sockaddr,
+ sockaddr_len,
+ GNUNET_YES,
+ timeout,
+ &http_common_dns_reverse_lookup_cb,
+ ppc);
+ if (NULL == ppc->resolver_handle)
+ {
+ GNUNET_free(ppc->plugin);
+ GNUNET_free(ppc);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_CONTAINER_DLL_insert (dll_ppc_head,
+ dll_ppc_tail,
+ ppc);
+ return GNUNET_OK;
+}
+
+
+static void
+http_common_dns_ip_lookup_cb (void *cls,
+ const struct sockaddr *addr,
+ socklen_t addrlen)
+{
+ struct PrettyPrinterContext *ppc = cls;
+
+ if (NULL != addr)
+ {
+ ppc->asc (ppc->asc_cls,
+ http_common_plugin_dnsresult_to_address (ppc->plugin, ppc->saddr, ppc->options,
+ GNUNET_a2s (addr, addrlen)), GNUNET_OK);
+ ppc->sucess = GNUNET_YES;
+ ppc->asc (ppc->asc_cls, GNUNET_a2s (addr, addrlen), GNUNET_OK);
+ }
+ else
+ {
+ ppc->asc (ppc->asc_cls, NULL,
+ (GNUNET_NO == ppc->sucess) ? GNUNET_SYSERR : GNUNET_OK);
+
+ GNUNET_CONTAINER_DLL_remove(dll_ppc_head, dll_ppc_tail, ppc);
+ GNUNET_free(ppc->plugin);
+ http_clean_splitted (ppc->saddr);
+ GNUNET_free(ppc);
+ }
+}
+
+
+static int
+http_common_dns_ip_lookup (const char *name,
+ const char *type,
+ struct SplittedHTTPAddress *saddr,
+ uint32_t options,
+ struct GNUNET_TIME_Relative timeout,
+ GNUNET_TRANSPORT_AddressStringCallback asc, void *asc_cls)
+{
+ struct PrettyPrinterContext *ppc;
+
+ ppc = GNUNET_new (struct PrettyPrinterContext);
+ ppc->sucess = GNUNET_NO;
+ ppc->saddr = saddr;
+ ppc->asc = asc;
+ ppc->asc_cls = asc_cls;
+ ppc->plugin = GNUNET_strdup (type);
+ ppc->options = options;
+ ppc->resolver_handle = GNUNET_RESOLVER_ip_get (name,
+ AF_UNSPEC,
+ timeout,
+ &http_common_dns_ip_lookup_cb,
+ ppc);
+ if (NULL == ppc->resolver_handle)
+ {
+ GNUNET_free(ppc->plugin);
+ GNUNET_free(ppc);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_CONTAINER_DLL_insert (dll_ppc_head,
+ dll_ppc_tail,
+ ppc);
+ return GNUNET_OK;
+}
+