Also a helper service.
A couple tools for installing/removing the provder.
And a resolver tool that loads the provider directly.
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
plugindir = $(libdir)/gnunet
pkgcfg_DATA = \
+ gns-helper-service-w32.conf \
gns.conf
lib_LTLIBRARIES = \
+ $(DO_W32_NSP) \
libgnunetgns.la
if HAVE_MHD
gnunet-service-gns \
$(DO_FCFSD) \
$(DO_PROXY) \
+ $(DO_W32_HELPER) \
+ $(DO_W32_NSPTOOLS) \
gnunet-gns
bin_SCRIPTS=gnunet-gns-proxy-setup-ca
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 \
$(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
--- /dev/null
+/*
+ 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 */
--- /dev/null
+#if !defined(GNUENT_W32NSP_LIB_H)\r
+#define GNUENT_W32NSP_LIB_H\r
+\r
+#include <basetyps.h>\r
+\r
+/* E0D24085-622C-4A93-9A0018-034469DE28DA */\r
+DEFINE_GUID (GNUNET_NAMESPACE_PROVIDER_DNS, 0xE0D24085L, 0x622C, 0x4A93, 0x9A, 0x18, 0x03, 0x44, 0x69, 0xDE, 0x28, 0xDA);\r
+\r
+#endif /* GNUENT_W32NSP_LIB_H */
\ No newline at end of file
--- /dev/null
+#define INITGUID\r
+#include <windows.h>\r
+#include <nspapi.h>\r
+#include <ws2spi.h>\r
+#include <gnunet_w32nsp_lib.h>\r
+#include <stdio.h>\r
+\r
+int\r
+main (int argc, char **argv)\r
+{\r
+ int ret;\r
+ int r = 1;\r
+ WSADATA wsd;\r
+ GUID id = GNUNET_NAMESPACE_PROVIDER_DNS;\r
+ wchar_t *cmdl;\r
+ int wargc;\r
+ wchar_t **wargv;\r
+\r
+ if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)\r
+ {\r
+ fprintf (stderr, "WSAStartup() failed: %lu\n", GetLastError());\r
+ return 5;\r
+ }\r
+\r
+ cmdl = GetCommandLineW ();\r
+ if (cmdl == NULL)\r
+ {\r
+ WSACleanup();\r
+ return 2;\r
+ }\r
+ wargv = CommandLineToArgvW (cmdl, &wargc);\r
+ if (wargv == NULL)\r
+ {\r
+ WSACleanup();\r
+ return 3;\r
+ }\r
+ r = 4;\r
+\r
+ if (wargc == 2)\r
+ {\r
+ ret = WSCInstallNameSpace (L"GNUnet DNS provider", wargv[1], NS_DNS, 1, &id);\r
+ if (ret == NO_ERROR)\r
+ {\r
+ r = 0;\r
+ }\r
+ else\r
+ {\r
+ r = 1;\r
+ fprintf (stderr,\r
+ "WSCInstallNameSpace(L\"GNUnet DNS provider\", \"%S\", %d, 0, %p) failed: %lu\n",\r
+ wargv[1], NS_DNS, &id, GetLastError ());\r
+ }\r
+ }\r
+ WSACleanup();\r
+ return r;\r
+}
\ No newline at end of file
--- /dev/null
+#define INITGUID\r
+#include <windows.h>\r
+#include <nspapi.h>\r
+#include <ws2spi.h>\r
+#include <nspapi.h>\r
+#include <ws2tcpip.h>\r
+#include <gnunet_w32nsp_lib.h>\r
+#include <stdio.h>\r
+\r
+typedef int (WSPAPI *LPNSPSTARTUP) (LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines);\r
+\r
+GUID host = {0x0002a800,0,0,{ 0xC0,0,0,0,0,0,0,0x46 }};\r
+GUID ip4 = {0x00090035,0,1,{ 0xc0,0,0,0,0,0,0,0x046}}; \r
+GUID ip6 = {0x00090035,0,0x001c, { 0xc0,0,0,0,0,0,0,0x046}};\r
+\r
+DEFINE_GUID(W32_DNS, 0x22059D40, 0x7E9E, 0x11CF, 0xAE, 0x5A, 0x00, 0xAA, 0x00, 0xA7, 0x11, 0x2B);\r
+\r
+#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);
+\r
+//\r
+// Utility to turn a list of offsets into a list of addresses. Used\r
+// to convert structures returned as BLOBs.\r
+//\r
+\r
+VOID FixList(PCHAR ** List, PCHAR Base)\r
+{\r
+ if(*List)\r
+ {\r
+ PCHAR * Addr;\r
+\r
+ Addr = *List = (PCHAR *)( ((DWORD)*List + Base) );\r
+ while(*Addr)\r
+ {\r
+ *Addr = (PCHAR)(((DWORD)*Addr + Base));\r
+ Addr++;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+//\r
+// Routine to convert a hostent returned in a BLOB to one with\r
+// usable pointers. The structure is converted in-place.\r
+//\r
+VOID UnpackHostEnt(struct hostent * hostent)\r
+{\r
+ PCHAR pch;\r
+\r
+ pch = (PCHAR)hostent;\r
+\r
+ if(hostent->h_name)\r
+ {\r
+ hostent->h_name = (PCHAR)((DWORD)hostent->h_name + pch);\r
+ }\r
+ FixList(&hostent->h_aliases, pch);\r
+ FixList(&hostent->h_addr_list, pch);\r
+}\r
+\r
+void\r
+print_hostent (struct hostent *he)\r
+{\r
+ int i;\r
+ char **pAlias;\r
+ printf("\tOfficial name: %s\n", he->h_name);\r
+ for (pAlias = he->h_aliases; *pAlias != 0; pAlias++) {\r
+ printf("\tAlternate name #%d: %s\n", ++i, *pAlias);\r
+ }\r
+ printf("\tAddress type: ");\r
+ switch (he->h_addrtype) {\r
+ case AF_INET:\r
+ printf("AF_INET\n");\r
+ break;\r
+ case AF_INET6:\r
+ printf("AF_INET6\n");\r
+ break;\r
+ case AF_NETBIOS:\r
+ printf("AF_NETBIOS\n");\r
+ break;\r
+ default:\r
+ printf(" %d\n", he->h_addrtype);\r
+ break;\r
+ }\r
+ printf("\tAddress length: %d\n", he->h_length);\r
+\r
+ if (he->h_addrtype == AF_INET) {\r
+ struct sockaddr_in addr;\r
+ memset (&addr, 0, sizeof (addr));\r
+ addr.sin_family = AF_INET;\r
+ addr.sin_port = 0;\r
+ i = 0;\r
+ while (he->h_addr_list[i] != 0) {\r
+ char buf[1024];\r
+ DWORD buflen = 1024;\r
+ addr.sin_addr = *(struct in_addr *) he->h_addr_list[i++];\r
+ if (NO_ERROR == WSAAddressToStringA ((LPSOCKADDR) &addr, sizeof (addr), NULL, buf, &buflen))\r
+ printf("\tIPv4 Address #%d: %s\n", i, buf);\r
+ else\r
+ printf("\tIPv4 Address #%d: Can't convert: %lu\n", i, GetLastError ());\r
+ }\r
+ } else if (he->h_addrtype == AF_INET6) {\r
+ struct sockaddr_in6 addr;\r
+ memset (&addr, 0, sizeof (addr));\r
+ addr.sin6_family = AF_INET6;\r
+ addr.sin6_port = 0;\r
+ i = 0;\r
+ while (he->h_addr_list[i] != 0) {\r
+ char buf[1024];\r
+ DWORD buflen = 1024;\r
+ addr.sin6_addr = *(struct in6_addr *) he->h_addr_list[i++];\r
+ if (NO_ERROR == WSAAddressToStringA ((LPSOCKADDR) &addr, sizeof (addr), NULL, buf, &buflen))\r
+ printf("\tIPv6 Address #%d: %s\n", i, buf);\r
+ else\r
+ printf("\tIPv6 Address #%d: Can't convert: %lu\n", i, GetLastError ());\r
+ }\r
+ }\r
+}\r
+\r
+int\r
+main (int argc, char **argv)\r
+{\r
+ int ret;\r
+ int r = 1;\r
+ WSADATA wsd;\r
+ GUID *prov = NULL;\r
+ GUID *sc = NULL;\r
+ wchar_t *cmdl;\r
+ int wargc;\r
+ wchar_t **wargv;\r
+\r
+ if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)\r
+ {\r
+ fprintf (stderr, "WSAStartup() failed: %lu\n", GetLastError());\r
+ return 5;\r
+ }\r
+\r
+ cmdl = GetCommandLineW ();\r
+ if (cmdl == NULL)\r
+ {\r
+ WSACleanup();\r
+ return 2;\r
+ }\r
+ wargv = CommandLineToArgvW (cmdl, &wargc);\r
+ if (wargv == NULL)\r
+ {\r
+ WSACleanup();\r
+ return 3;\r
+ }\r
+ r = 4;\r
+\r
+ if (wargc == 5)\r
+ {\r
+ if (wcscmp (wargv[1], L"A") == 0)\r
+ sc = &SVCID_DNS_TYPE_A;\r
+ else if (wcscmp (wargv[1], L"AAAA") == 0)\r
+ sc = &SVCID_DNS_TYPE_AAAA;\r
+ else if (wcscmp (wargv[1], L"name") == 0)\r
+ sc = &SVCID_HOSTNAME;\r
+ else if (wcscmp (wargv[1], L"addr") == 0)\r
+ sc = &SVCID_INET_HOSTADDRBYNAME;\r
+ else\r
+ wargc -= 1;\r
+ if (wcscmp (wargv[4], L"mswdns") == 0)\r
+ prov = &W32_DNS;\r
+ else if (wcscmp (wargv[4], L"gnunetdns") == 0)\r
+ prov = &GNUNET_NAMESPACE_PROVIDER_DNS;\r
+ else\r
+ wargc -= 1;\r
+ }\r
+\r
+ if (wargc == 5)\r
+ {\r
+ HMODULE nsp;\r
+ \r
+ nsp = LoadLibraryW (wargv[3]);\r
+ if (nsp == NULL)\r
+ {\r
+ fprintf (stderr, "Failed to load library `%S'\n", wargv[3]);\r
+ }\r
+ else\r
+ {\r
+ LPNSPSTARTUP startup = (LPNSPSTARTUP) GetProcAddress (nsp, "NSPStartup");\r
+ if (startup != NULL)\r
+ {\r
+ NSP_ROUTINE api;\r
+ ret = startup (prov, &api);\r
+ if (NO_ERROR != ret)\r
+ fprintf (stderr, "startup failed\n");\r
+ else\r
+ {\r
+ HANDLE lookup;\r
+ WSAQUERYSETW search;\r
+ char buf[4096];\r
+ WSAQUERYSETW *result = (WSAQUERYSETW *) buf;\r
+ DWORD resultsize;\r
+ DWORD err;\r
+ memset (&search, 0, sizeof (search));\r
+ search.dwSize = sizeof (search);\r
+ search.lpszServiceInstanceName = (wcscmp (wargv[2], L" ") == 0) ? NULL : wargv[2];\r
+ search.lpServiceClassId = sc;\r
+ search.lpNSProviderId = prov;\r
+ search.dwNameSpace = NS_ALL;\r
+ ret = api.NSPLookupServiceBegin (prov, &search, NULL, LUP_RETURN_ALL, &lookup);\r
+ if (ret != NO_ERROR)\r
+ {\r
+ fprintf (stderr, "lookup start failed\n");\r
+ }\r
+ else\r
+ {\r
+ resultsize = 4096;\r
+ ret = api.NSPLookupServiceNext (lookup, LUP_RETURN_ALL, &resultsize, result);\r
+ err = GetLastError ();\r
+ if (ret != NO_ERROR)\r
+ {\r
+ fprintf (stderr, "lookup next failed\n");\r
+ }\r
+ else\r
+ {\r
+ int i;\r
+ printf ("Got result:\n");\r
+ printf (" lpszServiceInstanceName: %S\n", result->lpszServiceInstanceName ? result->lpszServiceInstanceName : L"NULL");\r
+ if (result->lpServiceClassId)\r
+ 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",\r
+ result->lpServiceClassId->Data1, result->lpServiceClassId->Data2, result->lpServiceClassId->Data3, result->lpServiceClassId->Data4[0],\r
+ result->lpServiceClassId->Data4[1], result->lpServiceClassId->Data4[2], result->lpServiceClassId->Data4[3], result->lpServiceClassId->Data4[4],\r
+ result->lpServiceClassId->Data4[5], result->lpServiceClassId->Data4[6], result->lpServiceClassId->Data4[7]);\r
+ else\r
+ printf (" lpServiceClassId: NULL\n");\r
+ if (result->lpVersion)\r
+ printf (" lpVersion: 0x%08lX, %d\n", result->lpVersion->dwVersion, result->lpVersion->ecHow);\r
+ else\r
+ printf (" lpVersion: NULL\n");\r
+ printf (" lpszComment: %S\n", result->lpszComment ? result->lpszComment : L"NULL");\r
+ printf (" dwNameSpace: %lu\n", result->dwNameSpace);\r
+ if (result->lpNSProviderId)\r
+ 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",\r
+ result->lpNSProviderId->Data1, result->lpNSProviderId->Data2, result->lpNSProviderId->Data3, result->lpNSProviderId->Data4[0],\r
+ result->lpNSProviderId->Data4[1], result->lpNSProviderId->Data4[2], result->lpNSProviderId->Data4[3], result->lpNSProviderId->Data4[4],\r
+ result->lpNSProviderId->Data4[5], result->lpNSProviderId->Data4[6], result->lpNSProviderId->Data4[7]);\r
+ else\r
+ printf (" lpNSProviderId: NULL\n");\r
+ printf (" lpszContext: %S\n", result->lpszContext ? result->lpszContext : L"NULL");\r
+ printf (" dwNumberOfProtocols: %lu\n", result->dwNumberOfProtocols);\r
+ printf (" lpszQueryString: %S\n", result->lpszQueryString ? result->lpszQueryString : L"NULL");\r
+ printf (" dwNumberOfCsAddrs: %lu\n", result->dwNumberOfCsAddrs);\r
+ for (i = 0; i < result->dwNumberOfCsAddrs; i++)\r
+ {\r
+ switch (result->lpcsaBuffer[i].iSocketType)\r
+ {\r
+ case SOCK_STREAM:\r
+ printf (" %d: iSocketType = SOCK_STREAM\n", i);\r
+ break;\r
+ case SOCK_DGRAM:\r
+ printf (" %d: iSocketType = SOCK_DGRAM\n", i);\r
+ break;\r
+ default:\r
+ printf (" %d: iSocketType = %d\n", i, result->lpcsaBuffer[i].iSocketType);\r
+ }\r
+ switch (result->lpcsaBuffer[i].iProtocol)\r
+ {\r
+ case IPPROTO_TCP:\r
+ printf (" %d: iProtocol = IPPROTO_TCP\n", i);\r
+ break;\r
+ case IPPROTO_UDP:\r
+ printf (" %d: iProtocol = IPPROTO_UDP\n", i);\r
+ break;\r
+ default:\r
+ printf (" %d: iProtocol = %d\n", i, result->lpcsaBuffer[i].iProtocol);\r
+ }\r
+ switch (result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family)\r
+ {\r
+ case AF_INET:\r
+ printf (" %d: loc family = AF_INET\n", i);\r
+ break;\r
+ case AF_INET6:\r
+ printf (" %d: loc family = AF_INET6\n", i);\r
+ break;\r
+ default:\r
+ printf (" %d: loc family = %hu\n", i, result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family);\r
+ }\r
+ switch (result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family)\r
+ {\r
+ case AF_INET:\r
+ printf (" %d: rem family = AF_INET\n", i);\r
+ break;\r
+ case AF_INET6:\r
+ printf (" %d: rem family = AF_INET6\n", i);\r
+ break;\r
+ default:\r
+ printf (" %d: rem family = %hu\n", i, result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family);\r
+ }\r
+ char buf[1024];\r
+ DWORD buflen = 1024;\r
+ if (NO_ERROR == WSAAddressToStringA (result->lpcsaBuffer[i].LocalAddr.lpSockaddr, result->lpcsaBuffer[i].LocalAddr.iSockaddrLength, NULL, buf, &buflen))\r
+ printf("\tLocal Address #%d: %s\n", i, buf);\r
+ else\r
+ printf("\tLocal Address #%d: Can't convert: %lu\n", i, GetLastError ());\r
+ buflen = 1024;\r
+ if (NO_ERROR == WSAAddressToStringA (result->lpcsaBuffer[i].RemoteAddr.lpSockaddr, result->lpcsaBuffer[i].RemoteAddr.iSockaddrLength, NULL, buf, &buflen))\r
+ printf("\tRemote Address #%d: %s\n", i, buf);\r
+ else\r
+ printf("\tRemote Address #%d: Can't convert: %lu\n", i, GetLastError ());\r
+ }\r
+ printf (" dwOutputFlags: 0x%08lX\n", result->dwOutputFlags);\r
+ printf (" lpBlob: 0x%p\n", result->lpBlob);\r
+ if (result->lpBlob)\r
+ {\r
+ struct hostent *he = malloc (result->lpBlob->cbSize);\r
+ if (he != NULL)\r
+ {\r
+ memcpy (he, result->lpBlob->pBlobData, result->lpBlob->cbSize);\r
+ UnpackHostEnt (he);\r
+ print_hostent (he);\r
+ free (he);\r
+ }\r
+ }\r
+ }\r
+ ret = api.NSPLookupServiceEnd (lookup);\r
+ if (ret != NO_ERROR)\r
+ printf ("NSPLookupServiceEnd() failed: %lu\n", GetLastError ());\r
+ }\r
+ api.NSPCleanup (prov);\r
+ }\r
+ }\r
+ FreeLibrary (nsp);\r
+ }\r
+ }\r
+ WSACleanup();\r
+ return r;\r
+}
\ No newline at end of file
--- /dev/null
+#define INITGUID\r
+#include <windows.h>\r
+#include <nspapi.h>\r
+#include <ws2spi.h>\r
+#include <gnunet_w32nsp_lib.h>\r
+#include <stdio.h>\r
+\r
+int\r
+main (int argc, char **argv)\r
+{\r
+ int ret;\r
+ GUID id = GNUNET_NAMESPACE_PROVIDER_DNS;\r
+ WSADATA wsd;\r
+\r
+ if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)\r
+ {\r
+ fprintf (stderr, "WSAStartup() failed: %lu\n", GetLastError());\r
+ return 5;\r
+ }\r
+\r
+ ret = WSCUnInstallNameSpace (&id);\r
+ if (ret == NO_ERROR)\r
+ {\r
+ WSACleanup ();\r
+ return 0;\r
+ }\r
+ fprintf (stderr, "WSCUnInstallNameSpace() failed: %lu\n", GetLastError ());\r
+ WSACleanup ();\r
+ return 1;\r
+}
\ No newline at end of file
--- /dev/null
+/* This code is partially based upon samples from the book\r
+ * "Network Programming For Microsoft Windows, 2Nd Edition".\r
+ */\r
+\r
+#define INITGUID\r
+#include <windows.h>\r
+#include <nspapi.h>\r
+#include <stdint.h>\r
+#include <ws2tcpip.h>\r
+#include <ws2spi.h>\r
+\r
+#if 1\r
+# define DEBUGLOG(s, ...)\r
+#endif\r
+#if 0\r
+# define DEBUGLOG(s, ...) printf (s, ##__VA_ARGS__)\r
+#endif\r
+\r
+#define WINDOWS 1\r
+#define MINGW 1\r
+#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>\r
+#include <w32resolver.h>\r
+\r
+#define NSPAPI_VERSION_MAJOR 4\r
+#define NSPAPI_VERSION_MINOR 4\r
+\r
+#define REPLY_LIFETIME 60*5\r
+\r
+#define STATE_BEGIN 0x01\r
+#define STATE_END 0x02\r
+#define STATE_REPLY 0x04\r
+#define STATE_GHBN 0x08\r
+\r
+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
+}
+\r
+CRITICAL_SECTION records_cs;\r
+\r
+struct record\r
+{\r
+ SOCKET s;\r
+ DWORD flags;\r
+ uint8_t state;\r
+ char *buf;\r
+ wchar_t *name;\r
+};\r
+\r
+static struct record *records = NULL;\r
+static size_t records_len = 0;\r
+static size_t records_size = 0;\r
+\r
+int\r
+resize_records ()\r
+{\r
+ size_t new_size = records_len > 0 ? records_len * 2 : 5;\r
+ struct record *new_records = malloc (new_size * sizeof (struct record));\r
+ if (new_records == NULL)\r
+ {\r
+ SetLastError (WSA_NOT_ENOUGH_MEMORY);\r
+ return 0;\r
+ }\r
+ memcpy (new_records, records, records_len * sizeof (struct record));\r
+ memset (&new_records[records_len], 0, sizeof (struct record) * (new_size - records_len));\r
+ records_size = new_size;\r
+ free (records);\r
+ records = new_records;\r
+ return 1;\r
+}\r
+\r
+int\r
+add_record (SOCKET s, const wchar_t *name, DWORD flags)\r
+{\r
+ int res = 1;\r
+ int i;\r
+ int empty = -1;\r
+ //EnterCriticalSection (&records_cs);\r
+ for (i = 0; i < records_len; i++)\r
+ if (records[i].state == 0)\r
+ break;\r
+ empty = i;\r
+ if (i == records_len)\r
+ {\r
+ res = resize_records ();\r
+ if (res)\r
+ empty = records_len++;\r
+ }\r
+ if (res)\r
+ {\r
+ struct record r;\r
+ r.s = s;\r
+ r.flags = flags;\r
+ r.name = (wchar_t *) name;\r
+ r.state = 1;\r
+ r.buf = NULL;\r
+ if (name)\r
+ r.name = wcsdup (name);\r
+ records[empty] = r;\r
+ }\r
+ //LeaveCriticalSection (&records_cs);\r
+ return res;\r
+}\r
+\r
+void\r
+free_record (int i)\r
+{\r
+ if (records[i].name)\r
+ free (records[i].name);\r
+ records[i].state = 0;\r
+}\r
+\r
+/* These are not defined by mingw.org headers at the moment*/\r
+typedef INT (WSPAPI *LPNSPIOCTL) (HANDLE,DWORD,LPVOID,DWORD,LPVOID,DWORD,LPDWORD,LPWSACOMPLETION,LPWSATHREADID);\r
+typedef struct _NSP_ROUTINE_XP {\r
+ 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;
+\r
+static SOCKET\r
+connect_to_dns_resolver ()\r
+{\r
+ struct sockaddr_in addr;\r
+ SOCKET r;\r
+ int ret;\r
+\r
+ r = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);\r
+ if (INVALID_SOCKET == r)\r
+ {\r
+ SetLastError (16004);\r
+ return r;\r
+ }\r
+\r
+ addr.sin_family = AF_INET;\r
+ addr.sin_port = htons (5353); /* TCP 5353 is not registered; UDP 5353 is */\r
+ addr.sin_addr.s_addr = inet_addr ("127.0.0.1");\r
+\r
+ ret = connect (r, (struct sockaddr *) &addr, sizeof (addr));\r
+ if (SOCKET_ERROR == ret)\r
+ {\r
+ DWORD err = GetLastError ();\r
+ closesocket (r);\r
+ SetLastError (err);\r
+ SetLastError (16005);\r
+ r = INVALID_SOCKET;\r
+ }\r
+ return r;\r
+}\r
+\r
+static int\r
+send_name_to_ip_request (LPWSAQUERYSETW lpqsRestrictions,\r
+ LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags,\r
+ SOCKET *resolver)\r
+{\r
+ struct GNUNET_W32RESOLVER_GetMessage *msg;
+ int af4 = 0;
+ int af6 = 0;
+ char *buf;\r
+ int ret = 1;\r
+ int i;\r
+ uint32_t id;\r
+ size_t size = sizeof (struct GNUNET_W32RESOLVER_GetMessage);\r
+ size_t namelen = 0;\r
+ if (lpqsRestrictions->lpszServiceInstanceName)\r
+ namelen = sizeof (wchar_t) * (wcslen (lpqsRestrictions->lpszServiceInstanceName) + 1);\r
+ size += namelen;\r
+ buf = malloc (size);\r
+ msg = (struct GNUNET_W32RESOLVER_GetMessage *) buf;\r
+ 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))\r
+ {\r
+ DWORD err = GetLastError ();\r
+ closesocket (*resolver);\r
+ *resolver = INVALID_SOCKET;\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: failed to send request: %lu\n", err);\r
+ SetLastError (WSATRY_AGAIN);\r
+ ret = 0;\r
+ }\r
+ }\r
+ else\r
+ ret = 0;\r
+ free (buf);\r
+ return ret;\r
+}\r
+\r
+int WSPAPI\r
+NSPCleanup (LPGUID lpProviderId)\r
+{\r
+ DEBUGLOG ("NSPCleanup\n");\r
+ if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))\r
+ {\r
+ return NO_ERROR;\r
+ }\r
+ SetLastError (WSAEINVALIDPROVIDER);\r
+ return SOCKET_ERROR;\r
+}\r
+\r
+BOOL WINAPI\r
+DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)\r
+{\r
+ switch (fdwReason)\r
+ {\r
+ case DLL_PROCESS_ATTACH:\r
+ if (!InitializeCriticalSectionAndSpinCount (&records_cs, 0x00000400))\r
+ {\r
+ return FALSE;\r
+ }\r
+ break;\r
+ case DLL_THREAD_ATTACH:\r
+ break;\r
+ case DLL_THREAD_DETACH:\r
+ break;\r
+ case DLL_PROCESS_DETACH:\r
+ DeleteCriticalSection (&records_cs);\r
+ break;\r
+ }\r
+ return TRUE;\r
+}\r
+\r
+\r
+\r
+\r
+int WSPAPI\r
+GNUNET_W32NSP_LookupServiceBegin (LPGUID lpProviderId, LPWSAQUERYSETW lpqsRestrictions,\r
+ LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags,\r
+ LPHANDLE lphLookup)\r
+{\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin\n");\r
+ if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))\r
+ {\r
+ SOCKET s;\r
+ if (lpqsRestrictions->dwNameSpace != NS_DNS && lpqsRestrictions->dwNameSpace != NS_ALL)\r
+ {\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: wrong namespace\n");\r
+ SetLastError (WSANO_DATA);\r
+ return SOCKET_ERROR;\r
+ }\r
+ if (lpqsRestrictions->lpszServiceInstanceName != NULL)\r
+ {\r
+ wchar_t *s = lpqsRestrictions->lpszServiceInstanceName;\r
+ size_t len = wcslen (s);\r
+ if (len >= 4 && wcscmp (&s[len - 4], L"zkey") == 0)\r
+ {\r
+ }\r
+ else if (len >= 6 && wcscmp (&s[len - 6], L"gnunet") == 0)\r
+ {\r
+ }\r
+ else\r
+ {\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: unsupported TLD\n");\r
+ SetLastError (WSANO_DATA);\r
+ return SOCKET_ERROR;\r
+ }\r
+ }\r
+\r
+ if (send_name_to_ip_request (lpqsRestrictions,\r
+ lpServiceClassInfo, dwControlFlags, &s))\r
+ {\r
+ if (!(add_record (s, lpqsRestrictions->lpszServiceInstanceName, dwControlFlags)))\r
+ {\r
+ DWORD err = GetLastError ();\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: failed to add a record\n");\r
+ closesocket (s);\r
+ SetLastError (err);\r
+ return SOCKET_ERROR;\r
+ }\r
+ *lphLookup = (HANDLE) s;\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: OK (%lu)\n", GetLastError ());\r
+ return NO_ERROR;\r
+ }\r
+ return SOCKET_ERROR;\r
+ }\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: wrong provider\n");\r
+ SetLastError (WSAEINVALIDPROVIDER);\r
+ return SOCKET_ERROR;\r
+}\r
+\r
+#define UnmarshallPtr(ptr, ptrtype, base) \\r
+ if (ptr) \\r
+ ptr = (ptrtype *) (base + (uintptr_t) ptr)\r
+\r
+void\r
+UnmarshallWSAQUERYSETW (LPWSAQUERYSETW req)\r
+{\r
+ int i;\r
+ char *base = (char *) req;\r
+ UnmarshallPtr (req->lpszServiceInstanceName, wchar_t, base);\r
+ UnmarshallPtr (req->lpServiceClassId, GUID, base);\r
+ UnmarshallPtr (req->lpVersion, WSAVERSION, base);\r
+ UnmarshallPtr (req->lpszComment, wchar_t, base);\r
+ UnmarshallPtr (req->lpNSProviderId, GUID, base);\r
+ UnmarshallPtr (req->lpszContext, wchar_t, base);\r
+ UnmarshallPtr (req->lpafpProtocols, AFPROTOCOLS, base);\r
+ UnmarshallPtr (req->lpszQueryString, wchar_t, base);\r
+ UnmarshallPtr (req->lpcsaBuffer, CSADDR_INFO, base);\r
+ for (i = 0; i < req->dwNumberOfCsAddrs; i++)\r
+ {\r
+ UnmarshallPtr (req->lpcsaBuffer[i].LocalAddr.lpSockaddr, SOCKADDR, base);\r
+ UnmarshallPtr (req->lpcsaBuffer[i].RemoteAddr.lpSockaddr, SOCKADDR, base);\r
+ }\r
+ UnmarshallPtr (req->lpBlob, BLOB, base);\r
+ if (req->lpBlob)\r
+ UnmarshallPtr (req->lpBlob->pBlobData, BYTE, base);\r
+}\r
+\r
+int WSAAPI\r
+GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,\r
+ LPDWORD lpdwBufferLength, LPWSAQUERYSET lpqsResults)\r
+{\r
+ DWORD effective_flags;\r
+ int i;\r
+ struct GNUNET_MessageHeader header = {0, 0};
+ int rec = -1;\r
+ int rc;\r
+ int to_receive;\r
+ int t;\r
+ char *buf;\r
+\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext\n");\r
+ //EnterCriticalSection (&records_cs);\r
+ for (i = 0; i < records_len; i++)\r
+ {\r
+ if (records[i].s == (SOCKET) hLookup)\r
+ {\r
+ rec = i;\r
+ break;\r
+ }\r
+ }\r
+ if (rec == -1)\r
+ {\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: invalid handle\n");\r
+ SetLastError (WSA_INVALID_HANDLE);\r
+ //LeaveCriticalSection (&records_cs);\r
+ return SOCKET_ERROR;\r
+ }\r
+ if (records[rec].state & 4)\r
+ {\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: session is closed\n");\r
+ SetLastError (WSA_E_NO_MORE);\r
+ //LeaveCriticalSection (&records_cs);\r
+ return SOCKET_ERROR;\r
+ }\r
+ effective_flags = dwControlFlags & records[rec].flags;\r
+ if (records[rec].buf)\r
+ {\r
+ header = *((struct GNUNET_MessageHeader *) records[rec].buf);\r
+ if (dwControlFlags & LUP_FLUSHCACHE)\r
+ {\r
+ free (records[rec].buf);\r
+ records[rec].buf = NULL;\r
+ }\r
+ else\r
+ {\r
+ if (*lpdwBufferLength < header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage))\r
+ {\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n");\r
+ SetLastError (WSAEFAULT);\r
+ //LeaveCriticalSection (&records_cs);\r
+ return SOCKET_ERROR;\r
+ }\r
+ memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)records[rec].buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));\r
+ free (records[rec].buf);\r
+ records[rec].buf = NULL;\r
+ //LeaveCriticalSection (&records_cs);\r
+ UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK (from buffer)\n");\r
+ return NO_ERROR;\r
+ }\r
+ }\r
+ records[rec].state |= 8;\r
+ //LeaveCriticalSection (&records_cs);\r
+ to_receive = sizeof (header);\r
+ rc = 0;\r
+ while (to_receive > 0)\r
+ {\r
+ t = recv ((SOCKET) hLookup, &((char *) &header)[rc], to_receive, 0);\r
+ if (t > 0)\r
+ {\r
+ rc += t;\r
+ to_receive -= t;\r
+ }\r
+ else\r
+ break;\r
+ }\r
+ //EnterCriticalSection (&records_cs);\r
+ records[rec].state &= ~8;\r
+ if (rc != sizeof (header))\r
+ {\r
+ if (records[rec].state & 2)\r
+ {\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: call cancelled\n");\r
+ SetLastError (WSA_E_CANCELLED);\r
+ }\r
+ else\r
+ {\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: failed to receive enough data\n");\r
+ SetLastError (WSA_E_NO_MORE);\r
+ }\r
+ records[rec].state |= 4;\r
+ //LeaveCriticalSection (&records_cs);\r
+ return SOCKET_ERROR;\r
+ }\r
+ records[rec].state &= ~8;\r
+ header.type = ntohs (header.type);\r
+ header.size = ntohs (header.size);\r
+ if (header.type != GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE ||\r
+ (header.type == GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE &&\r
+ header.size == sizeof (header)))\r
+ {\r
+ records[rec].state |= 4;\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: header is wrong or type is wrong or no data\n");\r
+ //LeaveCriticalSection (&records_cs);\r
+ SetLastError (WSA_E_NO_MORE);\r
+ return SOCKET_ERROR;\r
+ }\r
+ buf = malloc (header.size);\r
+ if (buf == NULL)\r
+ {\r
+ records[rec].state |= 4;\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: malloc() failed\n");\r
+ //LeaveCriticalSection (&records_cs);\r
+ SetLastError (WSA_E_NO_MORE);\r
+ return SOCKET_ERROR;\r
+ }\r
+ records[rec].state |= 8;\r
+ //LeaveCriticalSection (&records_cs);\r
+ memcpy (buf, &header, sizeof (header));\r
+ to_receive = header.size - sizeof (header);\r
+ rc = 0;\r
+ while (to_receive > 0)\r
+ {\r
+ t = recv ((SOCKET) hLookup, &((char *) &((struct GNUNET_MessageHeader *) buf)[1])[rc], to_receive, 0);\r
+ if (t > 0)\r
+ {\r
+ rc += t;\r
+ to_receive -= t;\r
+ }\r
+ else\r
+ break;\r
+ }\r
+ //EnterCriticalSection (&records_cs);\r
+ records[rec].state &= ~8;\r
+ if (rc != header.size - sizeof (header))\r
+ {\r
+ free (buf);\r
+ if (records[rec].state & 2)\r
+ {\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: call cancelled\n");\r
+ SetLastError (WSA_E_CANCELLED);\r
+ }\r
+ else\r
+ {\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: failed to receive enough data\n");\r
+ SetLastError (WSA_E_NO_MORE);\r
+ }\r
+ records[rec].state |= 4;\r
+ //LeaveCriticalSection (&records_cs);\r
+ return SOCKET_ERROR;\r
+ }\r
+ if (*lpdwBufferLength < header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage))\r
+ {\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n");\r
+ SetLastError (WSAEFAULT);\r
+ records[rec].buf = buf;\r
+ //LeaveCriticalSection (&records_cs);\r
+ return SOCKET_ERROR;\r
+ }\r
+ //LeaveCriticalSection (&records_cs);\r
+ memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));\r
+ free (buf);\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK\n");\r
+ UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: returning (%lu)\n", GetLastError ());\r
+ return NO_ERROR;\r
+}\r
+\r
+int WSPAPI\r
+GNUNET_W32NSP_LookupServiceEnd (HANDLE hLookup)\r
+{\r
+ DWORD effective_flags;\r
+ int i;\r
+ struct GNUNET_MessageHeader header = {0, 0};
+ int rec = -1;\r
+ int rc;\r
+ char *buf;\r
+\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd\n");\r
+ //EnterCriticalSection (&records_cs);\r
+ for (i = 0; i < records_len; i++)\r
+ {\r
+ if (records[i].s == (SOCKET) hLookup)\r
+ {\r
+ rec = i;\r
+ break;\r
+ }\r
+ }\r
+ if (rec == -1)\r
+ {\r
+ SetLastError (WSA_INVALID_HANDLE);\r
+ //LeaveCriticalSection (&records_cs);\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd: invalid handle\n");\r
+ return SOCKET_ERROR;\r
+ }\r
+ records[rec].state |= 2;\r
+ closesocket (records[rec].s);\r
+ while (records[rec].state & 8)\r
+ {\r
+ //LeaveCriticalSection (&records_cs);\r
+ Sleep (10);\r
+ //EnterCriticalSection (&records_cs);\r
+ }\r
+ if (records[rec].buf)\r
+ free (records[rec].buf);\r
+ records[rec].buf = NULL;\r
+ records[rec].state = 0;\r
+ if (records[rec].name)\r
+ free (records[rec].name);\r
+ //LeaveCriticalSection (&records_cs);\r
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd: OK\n");\r
+ return NO_ERROR;\r
+}\r
+\r
+int WSAAPI\r
+GNUNET_W32NSP_SetService (LPGUID lpProviderId,\r
+ LPWSASERVICECLASSINFOW lpServiceClassInfo, LPWSAQUERYSETW lpqsRegInfo,\r
+ WSAESETSERVICEOP essOperation, DWORD dwControlFlags)\r
+{\r
+ DEBUGLOG ("GNUNET_W32NSP_SetService\n");\r
+ SetLastError (WSAEOPNOTSUPP);\r
+ return SOCKET_ERROR;\r
+}\r
+\r
+int WSAAPI\r
+GNUNET_W32NSP_InstallServiceClass (LPGUID lpProviderId,\r
+ LPWSASERVICECLASSINFOW lpServiceClassInfo)\r
+{\r
+ DEBUGLOG ("GNUNET_W32NSP_InstallServiceClass\n");\r
+ SetLastError (WSAEOPNOTSUPP);\r
+ return SOCKET_ERROR;\r
+}\r
+\r
+\r
+int WSAAPI\r
+GNUNET_W32NSP_RemoveServiceClass (LPGUID lpProviderId, LPGUID lpServiceClassId)\r
+{\r
+ DEBUGLOG ("GNUNET_W32NSP_RemoveServiceClass\n");\r
+ SetLastError (WSAEOPNOTSUPP);\r
+ return SOCKET_ERROR;\r
+}\r
+\r
+int WSAAPI\r
+GNUNET_W32NSP_GetServiceClassInfo (LPGUID lpProviderId, LPDWORD lpdwBufSize,\r
+ LPWSASERVICECLASSINFOW lpServiceClassInfo)\r
+{\r
+ DEBUGLOG ("GNUNET_W32NSP_GetServiceClassInfo\n");\r
+ SetLastError (WSAEOPNOTSUPP);\r
+ return SOCKET_ERROR;\r
+}\r
+\r
+int WSAAPI\r
+GNUNET_W32NSP_Ioctl (HANDLE hLookup, DWORD dwControlCode, LPVOID lpvInBuffer,\r
+ DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer,\r
+ LPDWORD lpcbBytesReturned, LPWSACOMPLETION lpCompletion,\r
+ LPWSATHREADID lpThreadId)\r
+{\r
+ DEBUGLOG ("GNUNET_W32NSP_Ioctl\n");\r
+ SetLastError (WSAEOPNOTSUPP);\r
+ return SOCKET_ERROR;\r
+}\r
+\r
+/**\r
+ * This function is called by Winsock to hook up our provider.\r
+ * It is the only function that [should be/is] exported by the\r
+ * provider. All other routines are passed as pointers in lpnspRoutines.\r
+ */\r
+int WSPAPI\r
+NSPStartup (LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines)\r
+{\r
+ if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))\r
+ {\r
+ if (!connect_to_dns_resolver ())\r
+ {\r
+ return SOCKET_ERROR;\r
+ }\r
+ /* This assumes that NSP_ROUTINE struct doesn't have a NSPIoctl member.\r
+ * If it does, you need to use FIELD_OFFSET() macro to get offset of NSPIoctl\r
+ * and use that offset as cbSize.\r
+ */\r
+ lpnspRoutines->cbSize = sizeof(NSP_ROUTINE_XP);\r
+\r
+ lpnspRoutines->dwMajorVersion = NSPAPI_VERSION_MAJOR;\r
+ lpnspRoutines->dwMinorVersion = NSPAPI_VERSION_MINOR;\r
+ lpnspRoutines->NSPCleanup = NSPCleanup;\r
+ lpnspRoutines->NSPLookupServiceBegin = GNUNET_W32NSP_LookupServiceBegin;\r
+ lpnspRoutines->NSPLookupServiceNext = GNUNET_W32NSP_LookupServiceNext;\r
+ lpnspRoutines->NSPLookupServiceEnd = GNUNET_W32NSP_LookupServiceEnd;\r
+ lpnspRoutines->NSPSetService = GNUNET_W32NSP_SetService;\r
+ lpnspRoutines->NSPInstallServiceClass = GNUNET_W32NSP_InstallServiceClass;\r
+ lpnspRoutines->NSPRemoveServiceClass = GNUNET_W32NSP_RemoveServiceClass;\r
+ lpnspRoutines->NSPGetServiceClassInfo = GNUNET_W32NSP_GetServiceClassInfo;\r
+ ((NSP_ROUTINE_XP *) lpnspRoutines)->NSPIoctl = GNUNET_W32NSP_Ioctl;\r
+ return NO_ERROR;\r
+ }\r
+ SetLastError (WSAEINVALIDPROVIDER);\r
+ return SOCKET_ERROR;\r
+}\r
+\r
--- /dev/null
+/*
+ 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