gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r22512 - gnunet/src/gns


From: gnunet
Subject: [GNUnet-SVN] r22512 - gnunet/src/gns
Date: Fri, 6 Jul 2012 09:39:24 +0200

Author: grothoff
Date: 2012-07-06 09:39:24 +0200 (Fri, 06 Jul 2012)
New Revision: 22512

Added:
   gnunet/src/gns/gnunet-gns-helper-service-w32.c
   gnunet/src/gns/gnunet_w32nsp_lib.h
   gnunet/src/gns/w32nsp-install.c
   gnunet/src/gns/w32nsp-resolve.c
   gnunet/src/gns/w32nsp-uninstall.c
   gnunet/src/gns/w32nsp.c
   gnunet/src/gns/w32resolver.h
Modified:
   gnunet/src/gns/Makefile.am
Log:
-LRN: W32 NS provider for GNS

Also a helper service.
A couple tools for installing/removing the provder.
And a resolver tool that loads the provider directly.


Modified: gnunet/src/gns/Makefile.am
===================================================================
--- gnunet/src/gns/Makefile.am  2012-07-06 07:38:54 UTC (rev 22511)
+++ gnunet/src/gns/Makefile.am  2012-07-06 07:39:24 UTC (rev 22512)
@@ -8,6 +8,9 @@
 
 if MINGW
   WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
+  DO_W32_HELPER = gnunet-gns-helper-service-w32
+  DO_W32_NSP = libw32nsp.la
+  DO_W32_NSPTOOLS = w32nsp-install w32nsp-uninstall w32nsp-resolve
 endif
 
 if USE_COVERAGE
@@ -19,9 +22,11 @@
 plugindir = $(libdir)/gnunet
 
 pkgcfg_DATA = \
+  gns-helper-service-w32.conf \
   gns.conf
 
 lib_LTLIBRARIES = \
+  $(DO_W32_NSP) \
   libgnunetgns.la
 
 if HAVE_MHD
@@ -35,6 +40,8 @@
   gnunet-service-gns \
   $(DO_FCFSD) \
        $(DO_PROXY) \
+  $(DO_W32_HELPER) \
+  $(DO_W32_NSPTOOLS) \
   gnunet-gns
 
 bin_SCRIPTS=gnunet-gns-proxy-setup-ca
@@ -274,6 +281,27 @@
 gnunet_gns_proxy_DEPENDENCIES = \
   libgnunetgns.la
 
+gnunet_gns_helper_service_w32_SOURCES = \
+  gnunet-gns-helper-service-w32.c
+gnunet_gns_helper_service_w32_LDADD = \
+  $(top_builddir)/src/gns/libgnunetgns.la \
+  $(top_builddir)/src/util/libgnunetutil.la \
+  $(GN_LIBINTL)
+gnunet_gns_helper_service_w32_DEPENDENCIES = \
+  libgnunetgns.la
+
+w32nsp_install_SOURCES = \
+  w32nsp-install.c
+w32nsp_install_LDADD = -lws2_32
+
+w32nsp_uninstall_SOURCES = \
+  w32nsp-uninstall.c
+w32nsp_uninstall_LDADD = -lws2_32
+
+w32nsp_resolve_SOURCES = \
+  w32nsp-resolve.c
+w32nsp_resolve_LDADD = -lws2_32
+
 gnunet_service_gns_SOURCES = \
  gnunet-service-gns.c \
  gnunet-service-gns_resolver.c gnunet-service-gns_resolver.h \
@@ -308,6 +336,13 @@
   $(top_builddir)/src/util/libgnunetutil.la \
   $(top_builddir)/src/namestore/libgnunetnamestore.la
 
+libw32nsp_la_SOURCES = \
+  w32nsp.c
+libw32nsp_la_LIBADD = \
+  -lole32 -lws2_32
+libw32nsp_la_LDFLAGS = \
+  -export-symbols $(top_srcdir)/src/gns/w32nsp.def \
+  $(GN_LIB_LDFLAGS)
 
 libgnunetgns_la_SOURCES = \
  gns_api.c gns.h

Added: gnunet/src/gns/gnunet-gns-helper-service-w32.c
===================================================================
--- gnunet/src/gns/gnunet-gns-helper-service-w32.c                              
(rev 0)
+++ gnunet/src/gns/gnunet-gns-helper-service-w32.c      2012-07-06 07:39:24 UTC 
(rev 22512)
@@ -0,0 +1,748 @@
+/*
+     This file is part of GNUnet.
+     (C) 2012 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 3, 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 gnunet-gns-helper-service-w32.c
+ * @brief an intermediary service to access distributed GNS
+ * @author Christian Grothoff
+ * @author LRN
+ */
+#define INITGUID
+#include "platform.h"
+#include <gnunet_util_lib.h>
+#include <gnunet_dnsparser_lib.h>
+#include <gnunet_namestore_service.h>
+#include <gnunet_gns_service.h>
+#include <gnunet_w32nsp_lib.h>
+#include "w32resolver.h"
+#include <nspapi.h>
+#include <unistr.h>
+
+#define DEFINE_DNS_GUID(a,x) DEFINE_GUID(a, 0x00090035, 0x0000, x, 0xc0, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x46)
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_A, 0x0001);
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_NS, 0x0002);
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_CNAME, 0x0005);
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_SOA, 0x0006);
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_PTR, 0x000c);
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_MX, 0x000f);
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_TEXT, 0x0010);
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_AAAA, 0x001c);
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_SRV, 0x0021);
+DEFINE_GUID(SVCID_HOSTNAME, 0x0002a800, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x46);
+DEFINE_GUID(SVCID_INET_HOSTADDRBYNAME, 0x0002a803, 0x0000, 0x0000, 0xc0, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
+
+struct request
+{
+  struct GNUNET_SERVER_Client *client;
+  GUID sc;
+  int af;
+  wchar_t *name;
+  char *u8name;
+};
+
+/**
+ * Handle to GNS service.
+ */
+static struct GNUNET_GNS_Handle *gns;
+
+static struct GNUNET_CRYPTO_ShortHashCode *zone = NULL;
+static struct GNUNET_CRYPTO_ShortHashCode user_zone;
+struct GNUNET_CRYPTO_RsaPrivateKey *shorten_key = NULL;
+
+
+/**
+ * Task run on shutdown.  Cleans up everything.
+ *
+ * @param cls unused
+ * @param tc scheduler context
+ */
+static void
+do_shutdown (void *cls,
+            const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  if (NULL != gns)
+  {
+    GNUNET_GNS_disconnect (gns);
+    gns = NULL;
+  }
+}
+
+/**
+ * Context for transmitting replies to clients.
+ */
+struct TransmitCallbackContext
+{
+
+  /**
+   * We keep these in a doubly-linked list (for cleanup).
+   */
+  struct TransmitCallbackContext *next;
+
+  /**
+   * We keep these in a doubly-linked list (for cleanup).
+   */
+  struct TransmitCallbackContext *prev;
+
+  /**
+   * The message that we're asked to transmit.
+   */
+  struct GNUNET_MessageHeader *msg;
+
+  size_t msgsize;
+
+  /**
+   * Handle for the transmission request.
+   */
+  struct GNUNET_SERVER_TransmitHandle *th;
+
+  /**
+   * Client that we are transmitting to.
+   */
+  struct GNUNET_SERVER_Client *client;
+
+};
+
+
+/**
+ * Head of the doubly-linked list (for cleanup).
+ */
+static struct TransmitCallbackContext *tcc_head;
+
+/**
+ * Tail of the doubly-linked list (for cleanup).
+ */
+static struct TransmitCallbackContext *tcc_tail;
+
+/**
+ * Have we already cleaned up the TCCs and are hence no longer
+ * willing (or able) to transmit anything to anyone?
+ */
+static int cleaning_done;
+
+/**
+ * Function called to notify a client about the socket
+ * begin ready to queue more data.  "buf" will be
+ * NULL and "size" zero if the socket was closed for
+ * writing in the meantime.
+ *
+ * @param cls closure
+ * @param size number of bytes available in buf
+ * @param buf where the callee should write the message
+ * @return number of bytes written to buf
+ */
+static size_t
+transmit_callback (void *cls, size_t size, void *buf)
+{
+  struct TransmitCallbackContext *tcc = cls;
+  size_t msize;
+
+  tcc->th = NULL;
+  GNUNET_CONTAINER_DLL_remove (tcc_head, tcc_tail, tcc);
+  msize = tcc->msgsize;
+  if (size == 0)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                _("Transmission to client failed!\n"));
+    GNUNET_SERVER_client_drop (tcc->client);
+    GNUNET_free (tcc->msg);
+    GNUNET_free (tcc);
+    return 0;
+  }
+  GNUNET_assert (size >= msize);
+  memcpy (buf, tcc->msg, msize);
+  GNUNET_SERVER_client_drop (tcc->client);
+  GNUNET_free (tcc->msg);
+  GNUNET_free (tcc);
+  return msize;
+}
+
+
+/**
+ * Transmit the given message to the client.
+ *
+ * @param client target of the message
+ * @param msg message to transmit, will be freed!
+ */
+static void
+transmit (struct GNUNET_SERVER_Client *client, struct GNUNET_MessageHeader 
*msg, size_t msgsize)
+{
+  struct TransmitCallbackContext *tcc;
+
+  if (GNUNET_YES == cleaning_done)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                _("Shutdown in progress, aborting transmission.\n"));
+    GNUNET_SERVER_client_drop (client);
+    GNUNET_free (msg);
+    return;
+  }
+  tcc = GNUNET_malloc (sizeof (struct TransmitCallbackContext));
+  tcc->msg = msg;
+  tcc->msgsize = msgsize;
+  tcc->client = client;
+  if (NULL ==
+      (tcc->th =
+       GNUNET_SERVER_notify_transmit_ready (client, msgsize,
+                                            GNUNET_TIME_UNIT_FOREVER_REL,
+                                            &transmit_callback, tcc)))
+  {
+    GNUNET_break (0);
+    GNUNET_SERVER_client_drop (client);
+    GNUNET_free (msg);
+    GNUNET_free (tcc);
+    return;
+  }
+  GNUNET_SERVER_client_keep (client);
+  GNUNET_CONTAINER_DLL_insert (tcc_head, tcc_tail, tcc);
+}
+
+#define MarshallPtr(ptr, base, type) \
+  if (ptr) \
+    ptr = (type *) ((char *) ptr - (char *) base)
+
+void
+MarshallWSAQUERYSETW (WSAQUERYSETW *qs, GUID *sc)
+{
+  int i;
+  MarshallPtr (qs->lpszServiceInstanceName, qs, wchar_t);
+  MarshallPtr (qs->lpServiceClassId, qs, GUID);
+  MarshallPtr (qs->lpVersion, qs, WSAVERSION);
+  MarshallPtr (qs->lpNSProviderId, qs, GUID);
+  MarshallPtr (qs->lpszContext, qs, wchar_t);
+  MarshallPtr (qs->lpafpProtocols, qs, AFPROTOCOLS);
+  MarshallPtr (qs->lpszQueryString, qs, wchar_t);
+  for (i = 0; i < qs->dwNumberOfCsAddrs; i++)
+  {
+    MarshallPtr (qs->lpcsaBuffer[i].LocalAddr.lpSockaddr, qs, SOCKADDR);
+    MarshallPtr (qs->lpcsaBuffer[i].RemoteAddr.lpSockaddr, qs, SOCKADDR);
+  }
+  MarshallPtr (qs->lpcsaBuffer, qs, CSADDR_INFO);
+  if (IsEqualGUID (&SVCID_INET_HOSTADDRBYNAME, sc) && qs->lpBlob != NULL && 
qs->lpBlob->pBlobData != NULL)
+  {
+    struct hostent *he;
+    he = (struct hostent *) qs->lpBlob->pBlobData;
+    for (i = 0; he->h_aliases[i] != NULL; i++)
+      MarshallPtr (he->h_aliases[i], he, char);
+    MarshallPtr (he->h_aliases, he, char *);
+    MarshallPtr (he->h_name, he, char);
+    for (i = 0; he->h_addr_list[i] != NULL; i++)
+      MarshallPtr (he->h_addr_list[i], he, void);
+    MarshallPtr (he->h_addr_list, he, char *);
+    MarshallPtr (qs->lpBlob->pBlobData, qs, void);
+  }
+  MarshallPtr (qs->lpBlob, qs, BLOB);
+}
+
+static void
+process_ip_lookup_result (void* cls, uint32_t rd_count,
+    const struct GNUNET_NAMESTORE_RecordData *rd)
+{
+  int i, j, csanum;
+  struct request *rq = (struct request *) cls;
+  struct GNUNET_W32RESOLVER_GetMessage *msg;
+  struct GNUNET_MessageHeader *msgend;
+  WSAQUERYSETW *qs;
+  size_t size;
+  size_t size_recalc;
+  char *ptr;
+  size_t blobsize = 0;
+  size_t blobaddrcount = 0;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Got lookup result with count %u for rq %p with client %p\n",
+              rd_count, rq, rq->client);
+
+  if (rd_count == 0)
+  {
+    size = sizeof (struct GNUNET_MessageHeader);
+    msg = GNUNET_malloc (size);
+    msg->header.size = htons (size);
+    msg->header.type = htons (GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE);
+    transmit (rq->client, &msg->header, msg->header.size);
+    return;
+  }
+
+  size = sizeof (struct GNUNET_W32RESOLVER_GetMessage) + sizeof (WSAQUERYSETW);
+  size += (wcslen (rq->name) + 1) * sizeof (wchar_t);
+  size += sizeof (GUID);
+  /* lpszComment ? a TXT record? */
+  size += sizeof (GUID);
+  /* lpszContext ? Not sure what it is */
+  csanum = 0;
+  for (i = 0; i < rd_count; i++)
+  {
+    switch (rd[i].record_type)
+    {
+    case GNUNET_GNS_RECORD_A:
+      if (rd[i].data_size != sizeof (struct in_addr))
+        continue;
+      size += sizeof (CSADDR_INFO) + sizeof (struct sockaddr_in) * 2;
+      csanum++;
+      break;
+    case GNUNET_GNS_RECORD_AAAA:
+      if (rd[i].data_size != sizeof (struct in6_addr))
+        continue;
+      size += sizeof (CSADDR_INFO) + sizeof (struct sockaddr_in6) * 2;
+      csanum++;
+      break;
+    }
+  }
+  if (IsEqualGUID (&SVCID_INET_HOSTADDRBYNAME, &rq->sc))
+  {
+    size += sizeof (BLOB);
+    blobsize += sizeof (struct hostent);
+    blobsize += strlen (rq->u8name) + 1;
+    blobsize += sizeof (void *); /* For aliases */
+    blobsize += sizeof (void *); /* For addresses */
+    for (i = 0; i < rd_count; i++)
+    {
+      if ((rq->af == AF_INET || rq->af == AF_UNSPEC) && rd[i].record_type == 
GNUNET_GNS_RECORD_A)
+      {
+        blobsize += sizeof (void *);
+        blobsize += sizeof (struct in_addr);
+        blobaddrcount++;
+      }
+      else if (rq->af == AF_INET6 && rd[i].record_type == 
GNUNET_GNS_RECORD_AAAA)
+      {
+        blobsize += sizeof (void *);
+        blobsize += sizeof (struct in6_addr);
+        blobaddrcount++;
+      }
+    }
+    size += blobsize;
+  }
+  size += sizeof (struct GNUNET_MessageHeader);
+  size_recalc = sizeof (struct GNUNET_W32RESOLVER_GetMessage) + sizeof 
(WSAQUERYSETW);
+  msg = GNUNET_malloc (size);
+  msg->header.size = htons (size - sizeof (struct GNUNET_MessageHeader));
+  msg->header.type = htons (GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE);
+  msg->af = htonl (rq->af);
+  msg->sc_data1 = htonl (rq->sc.Data1);
+  msg->sc_data2 = htons (rq->sc.Data2);
+  msg->sc_data3 = htons (rq->sc.Data3);
+  msg->sc_data4 = 0;
+  for (i = 0; i < 8; i++)
+    msg->sc_data4 |= rq->sc.Data4[i] << ((7 - i) * 8);
+  msg->sc_data4 = GNUNET_htonll (msg->sc_data4);
+  qs = (WSAQUERYSETW *) &msg[1];
+  ptr = (char *) &qs[1];
+  GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
+  qs->dwSize = sizeof (WSAQUERYSETW);
+  qs->lpszServiceInstanceName = (wchar_t *) ptr;
+  ptr += (wcslen (rq->name) + 1) * sizeof (wchar_t);
+  size_recalc += (wcslen (rq->name) + 1) * sizeof (wchar_t);
+  GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
+  wcscpy (qs->lpszServiceInstanceName, rq->name);
+  qs->lpServiceClassId = (GUID *) ptr;
+  ptr += sizeof (GUID);
+  size_recalc += sizeof (GUID);
+  GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
+  memcpy (qs->lpServiceClassId, &rq->sc, sizeof (GUID));
+  qs->lpVersion = NULL;
+  qs->dwNameSpace = NS_DNS;
+  qs->lpNSProviderId = (GUID *) ptr;
+  ptr += sizeof (GUID);
+  size_recalc += sizeof (GUID);
+  GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
+  memcpy (qs->lpNSProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS, sizeof (GUID));
+  qs->lpszContext = NULL;
+  qs->dwNumberOfProtocols = 0;
+  qs->lpafpProtocols = NULL;
+  /* Don't bother with this... */
+  qs->lpszQueryString = NULL;
+  qs->dwNumberOfCsAddrs = rd_count;
+  qs->lpcsaBuffer = (CSADDR_INFO *) ptr;
+  ptr += sizeof (CSADDR_INFO) * csanum;
+  j = 0;
+  for (i = 0; i < rd_count; i++)
+  {
+    switch (rd[i].record_type)
+    {
+    case GNUNET_GNS_RECORD_A:
+      if (rd[i].data_size != sizeof (struct in_addr))
+        continue;
+      qs->lpcsaBuffer[j].iSocketType = SOCK_STREAM;
+      qs->lpcsaBuffer[j].iProtocol = IPPROTO_TCP;
+
+      qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength = sizeof (struct 
sockaddr_in);
+      qs->lpcsaBuffer[j].LocalAddr.lpSockaddr = (SOCKADDR *) ptr;
+      ptr += qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength;
+      memset (qs->lpcsaBuffer[j].LocalAddr.lpSockaddr, 0, 
qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength);
+      ((struct sockaddr_in 
*)qs->lpcsaBuffer[j].LocalAddr.lpSockaddr)->sin_family = AF_INET;
+
+      qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength = sizeof (struct 
sockaddr_in);
+      qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr = (SOCKADDR *) ptr;
+      ptr += qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength;
+      memset (qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr, 0, 
qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength);
+      ((struct sockaddr_in 
*)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin_family = AF_INET;
+      ((struct sockaddr_in 
*)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin_port = htonl (53); /* Don't 
ask why it's 53 */
+      ((struct sockaddr_in 
*)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin_addr = *(struct in_addr *) 
rd[i].data;
+      size_recalc += sizeof (CSADDR_INFO) + sizeof (struct sockaddr_in) * 2;
+      j++;
+      break;
+    case GNUNET_GNS_RECORD_AAAA:
+      if (rd[i].data_size != sizeof (struct in6_addr))
+        continue;
+      qs->lpcsaBuffer[j].iSocketType = SOCK_STREAM;
+      qs->lpcsaBuffer[j].iProtocol = IPPROTO_TCP;
+
+      qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength = sizeof (struct 
sockaddr_in6);
+      qs->lpcsaBuffer[j].LocalAddr.lpSockaddr = (SOCKADDR *) ptr;
+      ptr += qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength;
+      memset (qs->lpcsaBuffer[j].LocalAddr.lpSockaddr, 0, 
qs->lpcsaBuffer[j].LocalAddr.iSockaddrLength);
+      ((struct sockaddr_in6 
*)qs->lpcsaBuffer[j].LocalAddr.lpSockaddr)->sin6_family = AF_INET6;
+
+      qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength = sizeof (struct 
sockaddr_in6);
+      qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr = (SOCKADDR *) ptr;
+      ptr += qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength;
+      memset (qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr, 0, 
qs->lpcsaBuffer[j].RemoteAddr.iSockaddrLength);
+      ((struct sockaddr_in6 
*)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin6_family = AF_INET6;
+      ((struct sockaddr_in6 
*)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin6_port = htonl (53); /* Don't 
ask why it's 53 */
+      ((struct sockaddr_in6 
*)qs->lpcsaBuffer[j].RemoteAddr.lpSockaddr)->sin6_addr = *(struct in6_addr *) 
rd[i].data;
+      size_recalc += sizeof (CSADDR_INFO) + sizeof (struct sockaddr_in6) * 2;
+      j++;
+      break;
+    default:
+      break;
+    }
+  }
+  GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
+  qs->dwOutputFlags = 0;
+  if (IsEqualGUID (&SVCID_INET_HOSTADDRBYNAME, &rq->sc))
+  {
+    struct hostent *he;
+    qs->lpBlob = (BLOB *) ptr;
+    ptr += sizeof (BLOB);
+
+    size_recalc += sizeof (BLOB);
+    GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
+
+    qs->lpBlob->cbSize = blobsize;
+    qs->lpBlob->pBlobData = (BYTE *) ptr;
+    ptr += sizeof (struct hostent);
+
+    size_recalc += sizeof (struct hostent);
+    GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
+
+    he = (struct hostent *) qs->lpBlob->pBlobData;
+    he->h_name = (char *) ptr;
+    ptr += strlen (rq->u8name) + 1;
+
+    size_recalc += strlen (rq->u8name) + 1;
+    GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
+
+    strcpy (he->h_name, rq->u8name);
+    he->h_aliases = (char **) ptr;
+    ptr += sizeof (void *);
+
+    size_recalc += sizeof (void *); /* For aliases */
+    GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
+
+    he->h_aliases[0] = NULL;
+    he->h_addrtype = rq->af;
+    he->h_length = rq->af == AF_INET || rq->af == AF_UNSPEC ? sizeof (struct 
in_addr) : sizeof (struct in6_addr);
+    he->h_addr_list = (char **) ptr;
+    ptr += sizeof (void *) * (blobaddrcount + 1);
+
+    size_recalc += sizeof (void *) * (blobaddrcount + 1); /* For addresses */
+    GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
+
+    j = 0;
+    for (i = 0; i < rd_count; i++)
+    {
+      if ((rq->af == AF_INET || rq->af == AF_UNSPEC) &&
+          rd[i].record_type == GNUNET_GNS_RECORD_A)
+      {
+        he->h_addr_list[j] = (char *) ptr;
+        ptr += sizeof (struct in_addr);
+
+        size_recalc += sizeof (struct in_addr);
+        GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
+
+        memcpy (he->h_addr_list[j], rd[i].data, sizeof (struct in_addr));
+        j++;
+      }
+      else if (rq->af == AF_INET6 && rd[i].record_type == 
GNUNET_GNS_RECORD_AAAA)
+      {
+        he->h_addr_list[j] = (char *) ptr;
+        ptr += sizeof (struct in6_addr);
+
+        size_recalc += sizeof (struct in6_addr);
+        GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
+
+        memcpy (he->h_addr_list[j], rd[i].data, sizeof (struct in6_addr));
+        j++;
+      }
+    }
+    he->h_addr_list[j] = NULL;
+  }
+  msgend = (struct GNUNET_MessageHeader *) ptr;
+  ptr += sizeof (struct GNUNET_MessageHeader);
+  size_recalc += sizeof (struct GNUNET_MessageHeader);
+
+  msgend->type = htons (GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE);
+  msgend->size = htons (sizeof (struct GNUNET_MessageHeader));
+
+  if ((char *) ptr - (char *) msg != size || size_recalc != size || 
size_recalc != ((char *) ptr - (char *) msg))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error in WSAQUERYSETW size calc: 
expected %lu, got %lu (recalc %lu)\n", size, (unsigned long) ((char *) ptr - 
(char *) msg), size_recalc);
+  }
+  MarshallWSAQUERYSETW (qs, &rq->sc);
+  transmit (rq->client, &msg->header, size);
+}
+
+static void
+get_ip_from_hostname (struct GNUNET_SERVER_Client *client,
+    const wchar_t *name, int af, GUID sc)
+{
+  struct request *rq;
+  char *hostname;
+  size_t strl;
+  size_t namelen;
+  uint32_t rtype;
+
+  if (IsEqualGUID (&SVCID_DNS_TYPE_A, &sc))
+    rtype = GNUNET_GNS_RECORD_A;
+  else if (IsEqualGUID (&SVCID_DNS_TYPE_NS, &sc))
+    rtype = GNUNET_GNS_RECORD_NS;
+  else if (IsEqualGUID (&SVCID_DNS_TYPE_CNAME, &sc))
+    rtype = GNUNET_GNS_RECORD_CNAME;
+  else if (IsEqualGUID (&SVCID_DNS_TYPE_SOA, &sc))
+    rtype = GNUNET_GNS_RECORD_SOA;
+  else if (IsEqualGUID (&SVCID_DNS_TYPE_PTR, &sc))
+    rtype = GNUNET_GNS_RECORD_PTR;
+  else if (IsEqualGUID (&SVCID_DNS_TYPE_MX, &sc))
+    rtype = GNUNET_GNS_RECORD_MX;
+  else if (IsEqualGUID (&SVCID_DNS_TYPE_TEXT, &sc))
+    rtype = GNUNET_GNS_RECORD_TXT;
+  else if (IsEqualGUID (&SVCID_DNS_TYPE_AAAA, &sc))
+    rtype = GNUNET_GNS_RECORD_AAAA;
+  else if (IsEqualGUID (&SVCID_DNS_TYPE_SRV, &sc))
+    rtype = GNUNET_GNS_RECORD_SRV;
+  else if (IsEqualGUID (&SVCID_INET_HOSTADDRBYNAME, &sc))
+    rtype = GNUNET_GNS_RECORD_A;
+  else
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Unknown GUID: 
%08X-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
+                sc.Data1, sc.Data2, sc.Data3, sc.Data4[0], sc.Data4[1], 
sc.Data4[2],
+                sc.Data4[3], sc.Data4[4], sc.Data4[5], sc.Data4[6], 
sc.Data4[7]);
+    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    return;
+  }
+
+  if (name)
+    namelen = wcslen (name);
+  else
+    namelen = 0;
+  if (namelen > 0)
+    hostname = (char *) u16_to_u8 (name, namelen + 1, NULL, &strl);
+  
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "W32 DNS resolver asked to look up %s for `%s'.\n",
+              af == AF_INET ? "IPv4" : af == AF_INET6 ? "IPv6" : "anything",
+              hostname);
+  rq = GNUNET_malloc (sizeof (struct request));
+  rq->sc = sc;
+  rq->client = client;
+  rq->af = af;
+  if (rq->af != AF_INET && rq->af != AF_INET6)
+    rq->af = AF_INET;
+  if (namelen)
+  {
+    rq->name = GNUNET_malloc ((namelen + 1) * sizeof (wchar_t));
+    memcpy (rq->name, name, (namelen + 1) * sizeof (wchar_t));
+    rq->u8name = hostname;
+  }
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Launching a lookup for client %p with rq %p\n",
+              client, rq);
+
+  if (NULL != GNUNET_GNS_lookup_zone (gns, hostname, zone, rtype,
+      GNUNET_YES, shorten_key, &process_ip_lookup_result, rq))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Lookup launched, waiting for a reply\n");
+    GNUNET_SERVER_client_keep (client);
+    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  }
+  else
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Lookup was not, disconnecting the client\n");
+    if (namelen)
+    {
+      GNUNET_free (rq->name);
+      free (rq->u8name);
+    }
+    GNUNET_free (rq);
+    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+  }
+}
+
+/**
+ * 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_W32RESOLVER_GetMessage *msg;
+  GUID sc;
+  uint16_t size;
+  uint64_t data4;
+  int i;
+  const wchar_t *hostname;
+  int af;
+
+  msize = ntohs (message->size);
+  if (msize < sizeof (struct GNUNET_W32RESOLVER_GetMessage))
+  {
+    GNUNET_break (0);
+    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    return;
+  }
+  msg = (const struct GNUNET_W32RESOLVER_GetMessage *) message;
+  size = msize - sizeof (struct GNUNET_W32RESOLVER_GetMessage);
+  af = ntohl (msg->af);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got NBO GUID: 
%08X-%04X-%04X-%016llX\n",
+      msg->sc_data1, msg->sc_data2, msg->sc_data3, msg->sc_data4);
+  sc.Data1 = ntohl (msg->sc_data1);
+  sc.Data2 = ntohs (msg->sc_data2);
+  sc.Data3 = ntohs (msg->sc_data3);
+  data4 = GNUNET_ntohll (msg->sc_data4);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got GUID: %08X-%04X-%04X-%016llX\n",
+      sc.Data1, sc.Data2, sc.Data3, data4);
+  for (i = 0; i < 8; i++)
+    sc.Data4[i] = 0xFF & (data4 >> ((7 - i) * 8));
+  
+  hostname = (const wchar_t *) &msg[1];
+  if (hostname[size - 1] != L'\0')
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "name of length %u, not 0-terminated: 
%*S\n",
+        size, size, hostname);
+    GNUNET_break (0);
+    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    return;
+  }
+  get_ip_from_hostname (client, hostname, af, sc);
+  return;
+}
+
+
+/**
+ * Start up gns-helper-w32 service.
+ *
+ * @param cls closure
+ * @param server the initialized server
+ * @param cfg configuration to use
+ */
+static void
+run (void *cls, struct GNUNET_SERVER_Handle *server,
+     const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+  static const struct GNUNET_SERVER_MessageHandler handlers[] = {
+    {&handle_get, NULL, GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST, 0},
+    {NULL, NULL, 0, 0}
+  };
+
+  char* keyfile;
+  struct GNUNET_CRYPTO_RsaPrivateKey *key = NULL;
+  struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
+  struct GNUNET_CRYPTO_ShortHashAsciiEncoded zonename;
+
+  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
+                                                           "ZONEKEY", 
&keyfile))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "No private key for root zone found, using default!\n");
+    zone = NULL;
+  }
+  else
+  {
+    if (GNUNET_YES == GNUNET_DISK_file_test (keyfile))
+    {
+      key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
+      GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
+      GNUNET_CRYPTO_short_hash(&pkey,
+                         sizeof(struct 
GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
+                         &user_zone);
+      zone = &user_zone;
+      GNUNET_CRYPTO_short_hash_to_enc (zone, &zonename);
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Using zone: %s!\n", &zonename);
+      GNUNET_CRYPTO_rsa_key_free(key);
+    }
+    GNUNET_free(keyfile);
+  }
+
+  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
+                                                   "SHORTEN_ZONEKEY", 
&keyfile))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "No shorten key found!\n");
+    shorten_key = NULL;
+  }
+  else
+  {
+    if (GNUNET_YES == GNUNET_DISK_file_test (keyfile))
+    {
+      shorten_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
+    }
+    GNUNET_free(keyfile);
+  }
+
+  gns = GNUNET_GNS_connect (cfg);
+  if (gns == NULL)
+    return;
+
+  GNUNET_SERVER_add_handlers (server, handlers);
+  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_shutdown,
+                                NULL);
+
+}
+
+
+/**
+ * The main function for gns-helper-w32.
+ *
+ * @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;
+
+  ret =
+      (GNUNET_OK ==
+       GNUNET_SERVICE_run (argc, argv, "gns-helper-service-w32", 
GNUNET_SERVICE_OPTION_NONE,
+                           &run, NULL)) ? 0 : 1;
+
+  return ret;
+}
+
+/* end of gnunet-gns.c */

Added: gnunet/src/gns/gnunet_w32nsp_lib.h
===================================================================
--- gnunet/src/gns/gnunet_w32nsp_lib.h                          (rev 0)
+++ gnunet/src/gns/gnunet_w32nsp_lib.h  2012-07-06 07:39:24 UTC (rev 22512)
@@ -0,0 +1,9 @@
+#if !defined(GNUENT_W32NSP_LIB_H)
+#define GNUENT_W32NSP_LIB_H
+
+#include <basetyps.h>
+
+/* E0D24085-622C-4A93-9A0018-034469DE28DA */
+DEFINE_GUID (GNUNET_NAMESPACE_PROVIDER_DNS, 0xE0D24085L, 0x622C, 0x4A93, 0x9A, 
0x18, 0x03, 0x44, 0x69, 0xDE, 0x28, 0xDA);
+
+#endif /* GNUENT_W32NSP_LIB_H */
\ No newline at end of file

Added: gnunet/src/gns/w32nsp-install.c
===================================================================
--- gnunet/src/gns/w32nsp-install.c                             (rev 0)
+++ gnunet/src/gns/w32nsp-install.c     2012-07-06 07:39:24 UTC (rev 22512)
@@ -0,0 +1,56 @@
+#define INITGUID
+#include <windows.h>
+#include <nspapi.h>
+#include <ws2spi.h>
+#include <gnunet_w32nsp_lib.h>
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+  int ret;
+  int r = 1;
+  WSADATA wsd;
+  GUID id = GNUNET_NAMESPACE_PROVIDER_DNS;
+  wchar_t *cmdl;
+  int wargc;
+  wchar_t **wargv;
+
+  if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
+  {
+    fprintf (stderr, "WSAStartup() failed: %lu\n", GetLastError());
+    return 5;
+  }
+
+  cmdl = GetCommandLineW ();
+  if (cmdl == NULL)
+  {
+    WSACleanup();
+    return 2;
+  }
+  wargv = CommandLineToArgvW (cmdl, &wargc);
+  if (wargv == NULL)
+  {
+    WSACleanup();
+    return 3;
+  }
+  r = 4;
+
+  if (wargc == 2)
+  {
+    ret = WSCInstallNameSpace (L"GNUnet DNS provider", wargv[1], NS_DNS, 1, 
&id);
+    if (ret == NO_ERROR)
+    {
+      r = 0;
+    }
+    else
+    {
+      r = 1;
+      fprintf (stderr,
+          "WSCInstallNameSpace(L\"GNUnet DNS provider\", \"%S\", %d, 0, %p) 
failed: %lu\n",
+          wargv[1], NS_DNS, &id, GetLastError ());
+    }
+  }
+  WSACleanup();
+  return r;
+}
\ No newline at end of file

Added: gnunet/src/gns/w32nsp-resolve.c
===================================================================
--- gnunet/src/gns/w32nsp-resolve.c                             (rev 0)
+++ gnunet/src/gns/w32nsp-resolve.c     2012-07-06 07:39:24 UTC (rev 22512)
@@ -0,0 +1,340 @@
+#define INITGUID
+#include <windows.h>
+#include <nspapi.h>
+#include <ws2spi.h>
+#include <nspapi.h>
+#include <ws2tcpip.h>
+#include <gnunet_w32nsp_lib.h>
+#include <stdio.h>
+
+typedef int (WSPAPI *LPNSPSTARTUP) (LPGUID lpProviderId, LPNSP_ROUTINE 
lpnspRoutines);
+
+GUID host = {0x0002a800,0,0,{ 0xC0,0,0,0,0,0,0,0x46 }};
+GUID ip4 = {0x00090035,0,1,{ 0xc0,0,0,0,0,0,0,0x046}}; 
+GUID ip6 = {0x00090035,0,0x001c, { 0xc0,0,0,0,0,0,0,0x046}};
+
+DEFINE_GUID(W32_DNS, 0x22059D40, 0x7E9E, 0x11CF, 0xAE, 0x5A, 0x00, 0xAA, 0x00, 
0xA7, 0x11, 0x2B);
+
+#define DEFINE_DNS_GUID(a,x) DEFINE_GUID(a, 0x00090035, 0x0000, x, 0xc0, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x46)
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_A, 0x0001);
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_NS, 0x0002);
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_CNAME, 0x0005);
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_SOA, 0x0006);
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_PTR, 0x000c);
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_MX, 0x000f);
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_TEXT, 0x0010);
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_AAAA, 0x001c);
+DEFINE_DNS_GUID(SVCID_DNS_TYPE_SRV, 0x0021);
+DEFINE_GUID(SVCID_HOSTNAME, 0x0002a800, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x46);
+DEFINE_GUID(SVCID_INET_HOSTADDRBYNAME, 0x0002a803, 0x0000, 0x0000, 0xc0, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
+
+//
+// Utility to turn a list of offsets into a list of addresses. Used
+// to convert structures returned as BLOBs.
+//
+
+VOID FixList(PCHAR ** List, PCHAR Base)
+{
+    if(*List)
+    {
+        PCHAR * Addr;
+
+        Addr = *List = (PCHAR *)( ((DWORD)*List + Base) );
+        while(*Addr)
+        {
+            *Addr = (PCHAR)(((DWORD)*Addr + Base));
+            Addr++;
+        }
+    }
+}
+
+
+//
+// Routine to convert a hostent returned in a BLOB to one with
+// usable pointers. The structure is converted in-place.
+//
+VOID UnpackHostEnt(struct hostent * hostent)
+{
+     PCHAR pch;
+
+     pch = (PCHAR)hostent;
+
+     if(hostent->h_name)
+     {
+         hostent->h_name = (PCHAR)((DWORD)hostent->h_name + pch);
+     }
+     FixList(&hostent->h_aliases, pch);
+     FixList(&hostent->h_addr_list, pch);
+}
+
+void
+print_hostent (struct hostent *he)
+{
+  int i;
+  char **pAlias;
+  printf("\tOfficial name: %s\n", he->h_name);
+  for (pAlias = he->h_aliases; *pAlias != 0; pAlias++) {
+      printf("\tAlternate name #%d: %s\n", ++i, *pAlias);
+  }
+  printf("\tAddress type: ");
+  switch (he->h_addrtype) {
+  case AF_INET:
+      printf("AF_INET\n");
+      break;
+  case AF_INET6:
+      printf("AF_INET6\n");
+      break;
+  case AF_NETBIOS:
+      printf("AF_NETBIOS\n");
+      break;
+  default:
+      printf(" %d\n", he->h_addrtype);
+      break;
+  }
+  printf("\tAddress length: %d\n", he->h_length);
+
+  if (he->h_addrtype == AF_INET) {
+    struct sockaddr_in addr;
+    memset (&addr, 0, sizeof (addr));
+    addr.sin_family = AF_INET;
+    addr.sin_port = 0;
+    i = 0;
+    while (he->h_addr_list[i] != 0) {
+      char buf[1024];
+      DWORD buflen = 1024;
+      addr.sin_addr = *(struct in_addr *) he->h_addr_list[i++];
+      if (NO_ERROR == WSAAddressToStringA ((LPSOCKADDR) &addr, sizeof (addr), 
NULL, buf, &buflen))
+        printf("\tIPv4 Address #%d: %s\n", i, buf);
+      else
+        printf("\tIPv4 Address #%d: Can't convert: %lu\n", i, GetLastError ());
+    }
+  } else if (he->h_addrtype == AF_INET6) {
+    struct sockaddr_in6 addr;
+    memset (&addr, 0, sizeof (addr));
+    addr.sin6_family = AF_INET6;
+    addr.sin6_port = 0;
+    i = 0;
+    while (he->h_addr_list[i] != 0) {
+      char buf[1024];
+      DWORD buflen = 1024;
+      addr.sin6_addr = *(struct in6_addr *) he->h_addr_list[i++];
+      if (NO_ERROR == WSAAddressToStringA ((LPSOCKADDR) &addr, sizeof (addr), 
NULL, buf, &buflen))
+        printf("\tIPv6 Address #%d: %s\n", i, buf);
+      else
+        printf("\tIPv6 Address #%d: Can't convert: %lu\n", i, GetLastError ());
+    }
+  }
+}
+
+int
+main (int argc, char **argv)
+{
+  int ret;
+  int r = 1;
+  WSADATA wsd;
+  GUID *prov = NULL;
+  GUID *sc = NULL;
+  wchar_t *cmdl;
+  int wargc;
+  wchar_t **wargv;
+
+  if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
+  {
+    fprintf (stderr, "WSAStartup() failed: %lu\n", GetLastError());
+    return 5;
+  }
+
+  cmdl = GetCommandLineW ();
+  if (cmdl == NULL)
+  {
+    WSACleanup();
+    return 2;
+  }
+  wargv = CommandLineToArgvW (cmdl, &wargc);
+  if (wargv == NULL)
+  {
+    WSACleanup();
+    return 3;
+  }
+  r = 4;
+
+  if (wargc == 5)
+  {
+    if (wcscmp (wargv[1], L"A") == 0)
+      sc = &SVCID_DNS_TYPE_A;
+    else if (wcscmp (wargv[1], L"AAAA") == 0)
+      sc = &SVCID_DNS_TYPE_AAAA;
+    else if (wcscmp (wargv[1], L"name") == 0)
+      sc = &SVCID_HOSTNAME;
+    else if (wcscmp (wargv[1], L"addr") == 0)
+      sc = &SVCID_INET_HOSTADDRBYNAME;
+    else
+      wargc -= 1;
+    if (wcscmp (wargv[4], L"mswdns") == 0)
+      prov = &W32_DNS;
+    else if (wcscmp (wargv[4], L"gnunetdns") == 0)
+      prov = &GNUNET_NAMESPACE_PROVIDER_DNS;
+    else
+      wargc -= 1;
+  }
+
+  if (wargc == 5)
+  {
+    HMODULE nsp;
+   
+    nsp = LoadLibraryW (wargv[3]);
+    if (nsp == NULL)
+    {
+      fprintf (stderr, "Failed to load library `%S'\n", wargv[3]);
+    }
+    else
+    {
+      LPNSPSTARTUP startup = (LPNSPSTARTUP) GetProcAddress (nsp, "NSPStartup");
+      if (startup != NULL)
+      {
+        NSP_ROUTINE api;
+        ret = startup (prov, &api);
+        if (NO_ERROR != ret)
+          fprintf (stderr, "startup failed\n");
+        else
+        {
+          HANDLE lookup;
+          WSAQUERYSETW search;
+          char buf[4096];
+          WSAQUERYSETW *result = (WSAQUERYSETW *) buf;
+          DWORD resultsize;
+          DWORD err;
+          memset (&search, 0, sizeof (search));
+          search.dwSize = sizeof (search);
+          search.lpszServiceInstanceName = (wcscmp (wargv[2], L" ") == 0) ? 
NULL : wargv[2];
+          search.lpServiceClassId = sc;
+          search.lpNSProviderId = prov;
+          search.dwNameSpace = NS_ALL;
+          ret = api.NSPLookupServiceBegin (prov, &search, NULL, 
LUP_RETURN_ALL, &lookup);
+          if (ret != NO_ERROR)
+          {
+            fprintf (stderr, "lookup start failed\n");
+          }
+          else
+          {
+            resultsize = 4096;
+            ret = api.NSPLookupServiceNext (lookup, LUP_RETURN_ALL, 
&resultsize, result);
+            err = GetLastError ();
+            if (ret != NO_ERROR)
+            {
+              fprintf (stderr, "lookup next failed\n");
+            }
+            else
+            {
+              int i;
+              printf ("Got result:\n");
+              printf ("  lpszServiceInstanceName: %S\n", 
result->lpszServiceInstanceName ? result->lpszServiceInstanceName : L"NULL");
+              if (result->lpServiceClassId)
+                printf ("  lpServiceClassId:        { 0x%08lX,0x%04X,0x%04X, { 
0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X } }\n",
+                    result->lpServiceClassId->Data1, 
result->lpServiceClassId->Data2, result->lpServiceClassId->Data3, 
result->lpServiceClassId->Data4[0],
+                    result->lpServiceClassId->Data4[1], 
result->lpServiceClassId->Data4[2], result->lpServiceClassId->Data4[3], 
result->lpServiceClassId->Data4[4],
+                    result->lpServiceClassId->Data4[5], 
result->lpServiceClassId->Data4[6], result->lpServiceClassId->Data4[7]);
+              else
+                printf ("  lpServiceClassId:        NULL\n");
+              if (result->lpVersion)
+                printf ("  lpVersion:               0x%08lX, %d\n", 
result->lpVersion->dwVersion, result->lpVersion->ecHow);
+              else
+                printf ("  lpVersion:               NULL\n");
+              printf ("  lpszComment:             %S\n", result->lpszComment ? 
result->lpszComment : L"NULL");
+              printf ("  dwNameSpace:             %lu\n", result->dwNameSpace);
+              if (result->lpNSProviderId)
+                printf ("  lpNSProviderId:          { 0x%08lX,0x%04X,0x%04X, { 
0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X } }\n",
+                    result->lpNSProviderId->Data1, 
result->lpNSProviderId->Data2, result->lpNSProviderId->Data3, 
result->lpNSProviderId->Data4[0],
+                    result->lpNSProviderId->Data4[1], 
result->lpNSProviderId->Data4[2], result->lpNSProviderId->Data4[3], 
result->lpNSProviderId->Data4[4],
+                    result->lpNSProviderId->Data4[5], 
result->lpNSProviderId->Data4[6], result->lpNSProviderId->Data4[7]);
+              else
+                printf ("  lpNSProviderId:          NULL\n");
+              printf ("  lpszContext:             %S\n", result->lpszContext ? 
result->lpszContext : L"NULL");
+              printf ("  dwNumberOfProtocols:     %lu\n", 
result->dwNumberOfProtocols);
+              printf ("  lpszQueryString:         %S\n", 
result->lpszQueryString ? result->lpszQueryString : L"NULL");
+              printf ("  dwNumberOfCsAddrs:       %lu\n", 
result->dwNumberOfCsAddrs);
+              for (i = 0; i < result->dwNumberOfCsAddrs; i++)
+              {
+                switch (result->lpcsaBuffer[i].iSocketType)
+                {
+                case SOCK_STREAM:
+                  printf ("    %d: iSocketType = SOCK_STREAM\n", i);
+                  break;
+                case SOCK_DGRAM:
+                  printf ("    %d: iSocketType = SOCK_DGRAM\n", i);
+                  break;
+                default:
+                  printf ("    %d: iSocketType = %d\n", i, 
result->lpcsaBuffer[i].iSocketType);
+                }
+                switch (result->lpcsaBuffer[i].iProtocol)
+                {
+                case IPPROTO_TCP:
+                  printf ("    %d: iProtocol   = IPPROTO_TCP\n", i);
+                  break;
+                case IPPROTO_UDP:
+                  printf ("    %d: iProtocol   = IPPROTO_UDP\n", i);
+                  break;
+                default:
+                  printf ("    %d: iProtocol   = %d\n", i, 
result->lpcsaBuffer[i].iProtocol);
+                }
+                switch (result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family)
+                {
+                case AF_INET:
+                  printf ("    %d: loc family  = AF_INET\n", i);
+                  break;
+                case AF_INET6:
+                  printf ("    %d: loc family  = AF_INET6\n", i);
+                  break;
+                default:
+                  printf ("    %d: loc family  = %hu\n", i, 
result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family);
+                }
+                switch 
(result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family)
+                {
+                case AF_INET:
+                  printf ("    %d: rem family  = AF_INET\n", i);
+                  break;
+                case AF_INET6:
+                  printf ("    %d: rem family  = AF_INET6\n", i);
+                  break;
+                default:
+                  printf ("    %d: rem family = %hu\n", i, 
result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family);
+                }
+                char buf[1024];
+                DWORD buflen = 1024;
+                if (NO_ERROR == WSAAddressToStringA 
(result->lpcsaBuffer[i].LocalAddr.lpSockaddr, 
result->lpcsaBuffer[i].LocalAddr.iSockaddrLength, NULL, buf, &buflen))
+                  printf("\tLocal Address #%d: %s\n", i, buf);
+                else
+                  printf("\tLocal Address #%d: Can't convert: %lu\n", i, 
GetLastError ());
+                buflen = 1024;
+                if (NO_ERROR == WSAAddressToStringA 
(result->lpcsaBuffer[i].RemoteAddr.lpSockaddr, 
result->lpcsaBuffer[i].RemoteAddr.iSockaddrLength, NULL, buf, &buflen))
+                  printf("\tRemote Address #%d: %s\n", i, buf);
+                else
+                  printf("\tRemote Address #%d: Can't convert: %lu\n", i, 
GetLastError ());
+              }
+              printf ("  dwOutputFlags:           0x%08lX\n", 
result->dwOutputFlags);
+              printf ("  lpBlob:                  0x%p\n", result->lpBlob);
+              if (result->lpBlob)
+              {
+                struct hostent *he = malloc (result->lpBlob->cbSize);
+                if (he != NULL)
+                {
+                  memcpy (he, result->lpBlob->pBlobData, 
result->lpBlob->cbSize);
+                  UnpackHostEnt (he);
+                  print_hostent (he);
+                  free (he);
+                }
+              }
+            }
+            ret = api.NSPLookupServiceEnd (lookup);
+            if (ret != NO_ERROR)
+              printf ("NSPLookupServiceEnd() failed: %lu\n", GetLastError ());
+          }
+          api.NSPCleanup (prov);
+        }
+      }
+      FreeLibrary (nsp);
+    }
+  }
+  WSACleanup();
+  return r;
+}
\ No newline at end of file

Added: gnunet/src/gns/w32nsp-uninstall.c
===================================================================
--- gnunet/src/gns/w32nsp-uninstall.c                           (rev 0)
+++ gnunet/src/gns/w32nsp-uninstall.c   2012-07-06 07:39:24 UTC (rev 22512)
@@ -0,0 +1,30 @@
+#define INITGUID
+#include <windows.h>
+#include <nspapi.h>
+#include <ws2spi.h>
+#include <gnunet_w32nsp_lib.h>
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+  int ret;
+  GUID id = GNUNET_NAMESPACE_PROVIDER_DNS;
+  WSADATA wsd;
+
+  if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
+  {
+    fprintf (stderr, "WSAStartup() failed: %lu\n", GetLastError());
+    return 5;
+  }
+
+  ret = WSCUnInstallNameSpace (&id);
+  if (ret == NO_ERROR)
+  {
+    WSACleanup ();
+    return 0;
+  }
+  fprintf (stderr, "WSCUnInstallNameSpace() failed: %lu\n", GetLastError ());
+  WSACleanup ();
+  return 1;
+}
\ No newline at end of file

Added: gnunet/src/gns/w32nsp.c
===================================================================
--- gnunet/src/gns/w32nsp.c                             (rev 0)
+++ gnunet/src/gns/w32nsp.c     2012-07-06 07:39:24 UTC (rev 22512)
@@ -0,0 +1,681 @@
+/* This code is partially based upon samples from the book
+ * "Network Programming For Microsoft Windows, 2Nd Edition".
+ */
+
+#define INITGUID
+#include <windows.h>
+#include <nspapi.h>
+#include <stdint.h>
+#include <ws2tcpip.h>
+#include <ws2spi.h>
+
+#if 1
+#  define DEBUGLOG(s, ...)
+#endif
+#if 0
+#  define DEBUGLOG(s, ...) printf (s, ##__VA_ARGS__)
+#endif
+
+#define WINDOWS 1
+#define MINGW 1
+#ifndef __BYTE_ORDER
+#ifdef _BYTE_ORDER
+#define __BYTE_ORDER _BYTE_ORDER
+#else
+#ifdef BYTE_ORDER
+#define __BYTE_ORDER BYTE_ORDER
+#endif
+#endif
+#endif
+#ifndef __BIG_ENDIAN
+#ifdef _BIG_ENDIAN
+#define __BIG_ENDIAN _BIG_ENDIAN
+#else
+#ifdef BIG_ENDIAN
+#define __BIG_ENDIAN BIG_ENDIAN
+#endif
+#endif
+#endif
+#ifndef __LITTLE_ENDIAN
+#ifdef _LITTLE_ENDIAN
+#define __LITTLE_ENDIAN _LITTLE_ENDIAN
+#else
+#ifdef LITTLE_ENDIAN
+#define __LITTLE_ENDIAN LITTLE_ENDIAN
+#endif
+#endif
+#endif
+#include <gnunet_w32nsp_lib.h>
+#include <w32resolver.h>
+
+#define NSPAPI_VERSION_MAJOR 4
+#define NSPAPI_VERSION_MINOR 4
+
+#define REPLY_LIFETIME 60*5
+
+#define STATE_BEGIN  0x01
+#define STATE_END    0x02
+#define STATE_REPLY  0x04
+#define STATE_GHBN   0x08
+
+uint64_t
+GNUNET_htonll (uint64_t n)
+{
+#if __BYTE_ORDER == __BIG_ENDIAN
+  return n;
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+  return (((uint64_t) htonl (n)) << 32) + htonl (n >> 32);
+#else
+  #error byteorder undefined
+#endif
+}
+
+CRITICAL_SECTION records_cs;
+
+struct record
+{
+  SOCKET s;
+  DWORD flags;
+  uint8_t state;
+  char *buf;
+  wchar_t *name;
+};
+
+static struct record *records = NULL;
+static size_t records_len = 0;
+static size_t records_size = 0;
+
+int
+resize_records ()
+{
+  size_t new_size = records_len > 0 ? records_len * 2 : 5;
+  struct record *new_records = malloc (new_size * sizeof (struct record));
+  if (new_records == NULL)
+  {
+    SetLastError (WSA_NOT_ENOUGH_MEMORY);
+    return 0;
+  }
+  memcpy (new_records, records, records_len * sizeof (struct record));
+  memset (&new_records[records_len], 0, sizeof (struct record) * (new_size - 
records_len));
+  records_size = new_size;
+  free (records);
+  records = new_records;
+  return 1;
+}
+
+int
+add_record (SOCKET s, const wchar_t *name, DWORD flags)
+{
+  int res = 1;
+  int i;
+  int empty = -1;
+  //EnterCriticalSection (&records_cs);
+  for (i = 0; i < records_len; i++)
+    if (records[i].state == 0)
+      break;
+  empty = i;
+  if (i == records_len)
+  {
+    res = resize_records ();
+    if (res)
+      empty = records_len++;
+  }
+  if (res)
+  {
+    struct record r;
+    r.s = s;
+    r.flags = flags;
+    r.name = (wchar_t *) name;
+    r.state = 1;
+    r.buf = NULL;
+    if (name)
+      r.name = wcsdup (name);
+    records[empty] = r;
+  }
+  //LeaveCriticalSection (&records_cs);
+  return res;
+}
+
+void
+free_record (int i)
+{
+  if (records[i].name)
+    free (records[i].name);
+  records[i].state = 0;
+}
+
+/* These are not defined by mingw.org headers at the moment*/
+typedef INT (WSPAPI *LPNSPIOCTL) 
(HANDLE,DWORD,LPVOID,DWORD,LPVOID,DWORD,LPDWORD,LPWSACOMPLETION,LPWSATHREADID);
+typedef struct _NSP_ROUTINE_XP {
+  DWORD cbSize;
+  DWORD dwMajorVersion;
+  DWORD dwMinorVersion;
+  LPNSPCLEANUP NSPCleanup;
+  LPNSPLOOKUPSERVICEBEGIN NSPLookupServiceBegin;
+  LPNSPLOOKUPSERVICENEXT NSPLookupServiceNext;
+  LPNSPLOOKUPSERVICEEND NSPLookupServiceEnd;
+  LPNSPSETSERVICE NSPSetService;
+  LPNSPINSTALLSERVICECLASS NSPInstallServiceClass;
+  LPNSPREMOVESERVICECLASS NSPRemoveServiceClass;
+  LPNSPGETSERVICECLASSINFO NSPGetServiceClassInfo;
+  LPNSPIOCTL NSPIoctl;
+} NSP_ROUTINE_XP, *PNSP_ROUTINE_XP, *LPNSP_ROUTINE_XP;
+
+static SOCKET
+connect_to_dns_resolver ()
+{
+  struct sockaddr_in addr;
+  SOCKET r;
+  int ret;
+
+  r = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (INVALID_SOCKET == r)
+  {
+    SetLastError (16004);
+    return r;
+  }
+
+  addr.sin_family = AF_INET;
+  addr.sin_port = htons (5353); /* TCP 5353 is not registered; UDP 5353 is */
+  addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
+
+  ret = connect (r, (struct sockaddr *) &addr, sizeof (addr));
+  if (SOCKET_ERROR == ret)
+  {
+    DWORD err = GetLastError ();
+    closesocket (r);
+    SetLastError (err);
+    SetLastError (16005);
+    r = INVALID_SOCKET;
+  }
+  return r;
+}
+
+static int
+send_name_to_ip_request (LPWSAQUERYSETW lpqsRestrictions,
+    LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags,
+    SOCKET *resolver)
+{
+  struct GNUNET_W32RESOLVER_GetMessage *msg;
+  int af4 = 0;
+  int af6 = 0;
+  char *buf;
+  int ret = 1;
+  int i;
+  uint32_t id;
+  size_t size = sizeof (struct GNUNET_W32RESOLVER_GetMessage);
+  size_t namelen = 0;
+  if (lpqsRestrictions->lpszServiceInstanceName)
+    namelen = sizeof (wchar_t) * (wcslen 
(lpqsRestrictions->lpszServiceInstanceName) + 1);
+  size += namelen;
+  buf = malloc (size);
+  msg = (struct GNUNET_W32RESOLVER_GetMessage *) buf;
+  msg->header.size = htons (size);
+  msg->header.type = htons (GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST);
+  if (lpqsRestrictions->dwNumberOfProtocols > 0)
+  {
+    int i;
+    for (i = 0; i < lpqsRestrictions->dwNumberOfProtocols; i++)
+    {
+      if (lpqsRestrictions->lpafpProtocols[0].iAddressFamily == AF_INET)
+        af4 = 1;
+      if (lpqsRestrictions->lpafpProtocols[0].iAddressFamily == AF_INET6)
+        af6 = 1;
+    }
+  }
+  if (af4 && !af6)
+    msg->af = htonl (AF_INET);
+  else if (af6 && !af4)
+    msg->af = htonl (AF_INET6);
+  else
+    msg->af = htonl (AF_UNSPEC);
+  if (lpqsRestrictions->lpszServiceInstanceName)
+    memcpy (&msg[1], lpqsRestrictions->lpszServiceInstanceName, namelen);
+  msg->sc_data1 = htonl (lpqsRestrictions->lpServiceClassId->Data1);
+  msg->sc_data2 = htons (lpqsRestrictions->lpServiceClassId->Data2);
+  msg->sc_data3 = htons (lpqsRestrictions->lpServiceClassId->Data3);
+  msg->sc_data4 = 0;
+  for (i = 0; i < 8; i++)
+    msg->sc_data4 |= ((uint64_t) lpqsRestrictions->lpServiceClassId->Data4[i]) 
<< ((7 - i) * 8);
+  msg->sc_data4 = GNUNET_htonll (msg->sc_data4);
+  *resolver = connect_to_dns_resolver ();
+  if (*resolver != INVALID_SOCKET)
+  {
+    if (size != send (*resolver, buf, size, 0))
+    {
+      DWORD err = GetLastError ();
+      closesocket (*resolver);
+      *resolver = INVALID_SOCKET;
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: failed to send request: 
%lu\n", err);
+      SetLastError (WSATRY_AGAIN);
+      ret = 0;
+    }
+  }
+  else
+    ret = 0;
+  free (buf);
+  return ret;
+}
+
+int WSPAPI
+NSPCleanup (LPGUID lpProviderId)
+{
+  DEBUGLOG ("NSPCleanup\n");
+  if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
+  {
+    return NO_ERROR;
+  }
+  SetLastError (WSAEINVALIDPROVIDER);
+  return SOCKET_ERROR;
+}
+
+BOOL WINAPI
+DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+  switch (fdwReason)
+  {
+    case DLL_PROCESS_ATTACH:
+      if (!InitializeCriticalSectionAndSpinCount (&records_cs, 0x00000400))
+      {
+        return FALSE;
+      }
+      break;
+    case DLL_THREAD_ATTACH:
+      break;
+    case DLL_THREAD_DETACH:
+      break;
+    case DLL_PROCESS_DETACH:
+      DeleteCriticalSection (&records_cs);
+      break;
+  }
+  return TRUE;
+}
+
+
+
+
+int WSPAPI
+GNUNET_W32NSP_LookupServiceBegin (LPGUID lpProviderId, LPWSAQUERYSETW 
lpqsRestrictions,
+    LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags,
+    LPHANDLE lphLookup)
+{
+  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin\n");
+  if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
+  {
+    SOCKET s;
+    if (lpqsRestrictions->dwNameSpace != NS_DNS && 
lpqsRestrictions->dwNameSpace != NS_ALL)
+    {
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: wrong namespace\n");
+      SetLastError (WSANO_DATA);
+      return SOCKET_ERROR;
+    }
+    if (lpqsRestrictions->lpszServiceInstanceName != NULL)
+    {
+      wchar_t *s = lpqsRestrictions->lpszServiceInstanceName;
+      size_t len = wcslen (s);
+      if (len >= 4 && wcscmp (&s[len - 4], L"zkey") == 0)
+      {
+      }
+      else if (len >= 6 && wcscmp (&s[len - 6], L"gnunet") == 0)
+      {
+      }
+      else
+      {
+        DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: unsupported TLD\n");
+        SetLastError (WSANO_DATA);
+        return SOCKET_ERROR;
+      }
+    }
+
+    if (send_name_to_ip_request (lpqsRestrictions,
+        lpServiceClassInfo, dwControlFlags, &s))
+    {
+      if (!(add_record (s, lpqsRestrictions->lpszServiceInstanceName, 
dwControlFlags)))
+      {
+        DWORD err = GetLastError ();
+        DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: failed to add a 
record\n");
+        closesocket (s);
+        SetLastError (err);
+        return SOCKET_ERROR;
+      }
+      *lphLookup = (HANDLE) s;
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: OK (%lu)\n", GetLastError 
());
+      return NO_ERROR;
+    }
+    return SOCKET_ERROR;
+  }
+  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: wrong provider\n");
+  SetLastError (WSAEINVALIDPROVIDER);
+  return SOCKET_ERROR;
+}
+
+#define UnmarshallPtr(ptr, ptrtype, base) \
+  if (ptr) \
+    ptr = (ptrtype *) (base + (uintptr_t) ptr)
+
+void
+UnmarshallWSAQUERYSETW (LPWSAQUERYSETW req)
+{
+  int i;
+  char *base = (char *) req;
+  UnmarshallPtr (req->lpszServiceInstanceName, wchar_t, base);
+  UnmarshallPtr (req->lpServiceClassId, GUID, base);
+  UnmarshallPtr (req->lpVersion, WSAVERSION, base);
+  UnmarshallPtr (req->lpszComment, wchar_t, base);
+  UnmarshallPtr (req->lpNSProviderId, GUID, base);
+  UnmarshallPtr (req->lpszContext, wchar_t, base);
+  UnmarshallPtr (req->lpafpProtocols, AFPROTOCOLS, base);
+  UnmarshallPtr (req->lpszQueryString, wchar_t, base);
+  UnmarshallPtr (req->lpcsaBuffer, CSADDR_INFO, base);
+  for (i = 0; i < req->dwNumberOfCsAddrs; i++)
+  {
+    UnmarshallPtr (req->lpcsaBuffer[i].LocalAddr.lpSockaddr, SOCKADDR, base);
+    UnmarshallPtr (req->lpcsaBuffer[i].RemoteAddr.lpSockaddr, SOCKADDR, base);
+  }
+  UnmarshallPtr (req->lpBlob, BLOB, base);
+  if (req->lpBlob)
+    UnmarshallPtr (req->lpBlob->pBlobData, BYTE, base);
+}
+
+int WSAAPI
+GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,
+    LPDWORD lpdwBufferLength, LPWSAQUERYSET lpqsResults)
+{
+  DWORD effective_flags;
+  int i;
+  struct GNUNET_MessageHeader header = {0, 0};
+  int rec = -1;
+  int rc;
+  int to_receive;
+  int t;
+  char *buf;
+
+  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext\n");
+  //EnterCriticalSection (&records_cs);
+  for (i = 0; i < records_len; i++)
+  {
+    if (records[i].s == (SOCKET) hLookup)
+    {
+      rec = i;
+      break;
+    }
+  }
+  if (rec == -1)
+  {
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: invalid handle\n");
+    SetLastError (WSA_INVALID_HANDLE);
+    //LeaveCriticalSection (&records_cs);
+    return SOCKET_ERROR;
+  }
+  if (records[rec].state & 4)
+  {
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: session is closed\n");
+    SetLastError (WSA_E_NO_MORE);
+    //LeaveCriticalSection (&records_cs);
+    return SOCKET_ERROR;
+  }
+  effective_flags = dwControlFlags & records[rec].flags;
+  if (records[rec].buf)
+  {
+    header = *((struct GNUNET_MessageHeader *) records[rec].buf);
+    if (dwControlFlags & LUP_FLUSHCACHE)
+    {
+      free (records[rec].buf);
+      records[rec].buf = NULL;
+    }
+    else
+    {
+      if (*lpdwBufferLength < header.size - sizeof (struct 
GNUNET_W32RESOLVER_GetMessage))
+      {
+        DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too 
small\n");
+        SetLastError (WSAEFAULT);
+        //LeaveCriticalSection (&records_cs);
+        return SOCKET_ERROR;
+      }
+      memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage 
*)records[rec].buf)[1], header.size - sizeof (struct 
GNUNET_W32RESOLVER_GetMessage));
+      free (records[rec].buf);
+      records[rec].buf = NULL;
+      //LeaveCriticalSection (&records_cs);
+      UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK (from buffer)\n");
+      return NO_ERROR;
+    }
+  }
+  records[rec].state |= 8;
+  //LeaveCriticalSection (&records_cs);
+  to_receive = sizeof (header);
+  rc = 0;
+  while (to_receive > 0)
+  {
+    t = recv ((SOCKET) hLookup, &((char *) &header)[rc], to_receive, 0);
+    if (t > 0)
+    {
+      rc += t;
+      to_receive -= t;
+    }
+    else
+      break;
+  }
+  //EnterCriticalSection (&records_cs);
+  records[rec].state &= ~8;
+  if (rc != sizeof (header))
+  {
+    if (records[rec].state & 2)
+    {
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: call cancelled\n");
+      SetLastError (WSA_E_CANCELLED);
+    }
+    else
+    {
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: failed to receive enough 
data\n");
+      SetLastError (WSA_E_NO_MORE);
+    }
+    records[rec].state |= 4;
+    //LeaveCriticalSection (&records_cs);
+    return SOCKET_ERROR;
+  }
+  records[rec].state &= ~8;
+  header.type = ntohs (header.type);
+  header.size = ntohs (header.size);
+  if (header.type != GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE ||
+      (header.type == GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE &&
+      header.size == sizeof (header)))
+  {
+    records[rec].state |= 4;
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: header is wrong or type is 
wrong or no data\n");
+    //LeaveCriticalSection (&records_cs);
+    SetLastError (WSA_E_NO_MORE);
+    return SOCKET_ERROR;
+  }
+  buf = malloc (header.size);
+  if (buf == NULL)
+  {
+    records[rec].state |= 4;
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: malloc() failed\n");
+    //LeaveCriticalSection (&records_cs);
+    SetLastError (WSA_E_NO_MORE);
+    return SOCKET_ERROR;
+  }
+  records[rec].state |= 8;
+  //LeaveCriticalSection (&records_cs);
+  memcpy (buf, &header, sizeof (header));
+  to_receive = header.size - sizeof (header);
+  rc = 0;
+  while (to_receive > 0)
+  {
+    t = recv ((SOCKET) hLookup, &((char *) &((struct GNUNET_MessageHeader *) 
buf)[1])[rc], to_receive, 0);
+    if (t > 0)
+    {
+      rc += t;
+      to_receive -= t;
+    }
+    else
+      break;
+  }
+  //EnterCriticalSection (&records_cs);
+  records[rec].state &= ~8;
+  if (rc != header.size - sizeof (header))
+  {
+    free (buf);
+    if (records[rec].state & 2)
+    {
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: call cancelled\n");
+      SetLastError (WSA_E_CANCELLED);
+    }
+    else
+    {
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: failed to receive enough 
data\n");
+      SetLastError (WSA_E_NO_MORE);
+    }
+    records[rec].state |= 4;
+    //LeaveCriticalSection (&records_cs);
+    return SOCKET_ERROR;
+  }
+  if (*lpdwBufferLength < header.size - sizeof (struct 
GNUNET_W32RESOLVER_GetMessage))
+  {
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n");
+    SetLastError (WSAEFAULT);
+    records[rec].buf = buf;
+    //LeaveCriticalSection (&records_cs);
+    return SOCKET_ERROR;
+  }
+  //LeaveCriticalSection (&records_cs);
+  memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)buf)[1], 
header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
+  free (buf);
+  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK\n");
+  UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);
+  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: returning (%lu)\n", GetLastError 
());
+  return NO_ERROR;
+}
+
+int WSPAPI
+GNUNET_W32NSP_LookupServiceEnd (HANDLE hLookup)
+{
+  DWORD effective_flags;
+  int i;
+  struct GNUNET_MessageHeader header = {0, 0};
+  int rec = -1;
+  int rc;
+  char *buf;
+
+  DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd\n");
+  //EnterCriticalSection (&records_cs);
+  for (i = 0; i < records_len; i++)
+  {
+    if (records[i].s == (SOCKET) hLookup)
+    {
+      rec = i;
+      break;
+    }
+  }
+  if (rec == -1)
+  {
+    SetLastError (WSA_INVALID_HANDLE);
+    //LeaveCriticalSection (&records_cs);
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd: invalid handle\n");
+    return SOCKET_ERROR;
+  }
+  records[rec].state |= 2;
+  closesocket (records[rec].s);
+  while (records[rec].state & 8)
+  {
+    //LeaveCriticalSection (&records_cs);
+    Sleep (10);
+    //EnterCriticalSection (&records_cs);
+  }
+  if (records[rec].buf)
+    free (records[rec].buf);
+  records[rec].buf = NULL;
+  records[rec].state = 0;
+  if (records[rec].name)
+    free (records[rec].name);
+  //LeaveCriticalSection (&records_cs);
+  DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd: OK\n");
+  return NO_ERROR;
+}
+
+int WSAAPI
+GNUNET_W32NSP_SetService (LPGUID lpProviderId,
+    LPWSASERVICECLASSINFOW lpServiceClassInfo, LPWSAQUERYSETW lpqsRegInfo,
+    WSAESETSERVICEOP essOperation, DWORD dwControlFlags)
+{
+  DEBUGLOG ("GNUNET_W32NSP_SetService\n");
+  SetLastError (WSAEOPNOTSUPP);
+  return SOCKET_ERROR;
+}
+
+int WSAAPI
+GNUNET_W32NSP_InstallServiceClass (LPGUID lpProviderId,
+    LPWSASERVICECLASSINFOW lpServiceClassInfo)
+{
+  DEBUGLOG ("GNUNET_W32NSP_InstallServiceClass\n");
+  SetLastError (WSAEOPNOTSUPP);
+  return SOCKET_ERROR;
+}
+
+
+int WSAAPI
+GNUNET_W32NSP_RemoveServiceClass (LPGUID lpProviderId, LPGUID lpServiceClassId)
+{
+  DEBUGLOG ("GNUNET_W32NSP_RemoveServiceClass\n");
+  SetLastError (WSAEOPNOTSUPP);
+  return SOCKET_ERROR;
+}
+
+int WSAAPI
+GNUNET_W32NSP_GetServiceClassInfo (LPGUID lpProviderId, LPDWORD lpdwBufSize,
+  LPWSASERVICECLASSINFOW lpServiceClassInfo)
+{
+  DEBUGLOG ("GNUNET_W32NSP_GetServiceClassInfo\n");
+  SetLastError (WSAEOPNOTSUPP);
+  return SOCKET_ERROR;
+}
+
+int WSAAPI
+GNUNET_W32NSP_Ioctl (HANDLE hLookup, DWORD dwControlCode, LPVOID lpvInBuffer,
+    DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer,
+    LPDWORD lpcbBytesReturned, LPWSACOMPLETION lpCompletion,
+    LPWSATHREADID lpThreadId)
+{
+  DEBUGLOG ("GNUNET_W32NSP_Ioctl\n");
+  SetLastError (WSAEOPNOTSUPP);
+  return SOCKET_ERROR;
+}
+
+/**
+ * This function is called by Winsock to hook up our provider.
+ * It is the only function that [should be/is] exported by the
+ * provider. All other routines are passed as pointers in lpnspRoutines.
+ */
+int WSPAPI
+NSPStartup (LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines)
+{
+  if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
+  {
+    if (!connect_to_dns_resolver ())
+    {
+      return SOCKET_ERROR;
+    }
+    /* This assumes that NSP_ROUTINE struct doesn't have a NSPIoctl member.
+     * If it does, you need to use FIELD_OFFSET() macro to get offset of 
NSPIoctl
+     * and use that offset as cbSize.
+     */
+    lpnspRoutines->cbSize = sizeof(NSP_ROUTINE_XP);
+
+    lpnspRoutines->dwMajorVersion = NSPAPI_VERSION_MAJOR;
+    lpnspRoutines->dwMinorVersion = NSPAPI_VERSION_MINOR;
+    lpnspRoutines->NSPCleanup = NSPCleanup;
+    lpnspRoutines->NSPLookupServiceBegin = GNUNET_W32NSP_LookupServiceBegin;
+    lpnspRoutines->NSPLookupServiceNext = GNUNET_W32NSP_LookupServiceNext;
+    lpnspRoutines->NSPLookupServiceEnd = GNUNET_W32NSP_LookupServiceEnd;
+    lpnspRoutines->NSPSetService = GNUNET_W32NSP_SetService;
+    lpnspRoutines->NSPInstallServiceClass = GNUNET_W32NSP_InstallServiceClass;
+    lpnspRoutines->NSPRemoveServiceClass = GNUNET_W32NSP_RemoveServiceClass;
+    lpnspRoutines->NSPGetServiceClassInfo = GNUNET_W32NSP_GetServiceClassInfo;
+    ((NSP_ROUTINE_XP *) lpnspRoutines)->NSPIoctl = GNUNET_W32NSP_Ioctl;
+    return NO_ERROR;
+  }
+  SetLastError (WSAEINVALIDPROVIDER);
+  return SOCKET_ERROR;
+}
+

Added: gnunet/src/gns/w32resolver.h
===================================================================
--- gnunet/src/gns/w32resolver.h                                (rev 0)
+++ gnunet/src/gns/w32resolver.h        2012-07-06 07:39:24 UTC (rev 22512)
@@ -0,0 +1,69 @@
+/*
+     This file is part of GNUnet.
+     (C) 2009, 2012 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 gns/w32resolver.h
+ */
+#ifndef W32RESOLVER_H
+#define W32RESOLVER_H
+
+#include "gnunet_common.h"
+
+/**
+ * Request DNS resolution.
+ */
+#define GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST 4
+
+/**
+ * Response to a DNS resolution request.
+ */
+#define GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE 5
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Request for the resolver.  Followed by the 0-terminated hostname.
+ *
+ * The response will be one or more messages of type
+ * W32RESOLVER_RESPONSE, each with the message header immediately
+ * followed by the requested data (struct in[6]_addr).
+ * The last W32RESOLVER_RESPONSE will just be a header without any data
+ * (used to indicate the end of the list).
+ */
+struct GNUNET_W32RESOLVER_GetMessage
+{
+  /**
+   * Type:  GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST
+   */
+  struct GNUNET_MessageHeader header;
+
+  uint32_t af GNUNET_PACKED;
+
+  uint32_t sc_data1 GNUNET_PACKED;
+  uint16_t sc_data2 GNUNET_PACKED;
+  uint16_t sc_data3 GNUNET_PACKED;
+  uint64_t sc_data4 GNUNET_PACKED;
+  /* followed by 0-terminated string for A/AAAA lookup */
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+#endif




reply via email to

[Prev in Thread] Current Thread [Next in Thread]