[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r22512 - gnunet/src/gns,
gnunet <=