Merge branch 'credentials' of git+ssh://gnunet.org/gnunet into credentials
[oweals/gnunet.git] / src / gns / gnunet-gns-helper-service-w32.c
index 2d79c3aae5fe6c510f0eb309198b86682eb92bda..bfee2b498c947c23d8dbed037b8f46edcb647033 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2012 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2012 GNUnet e.V.
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -14,8 +14,8 @@
 
      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.
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
 */
 /**
  * @file gnunet-gns-helper-service-w32.c
  * @author Christian Grothoff
  * @author LRN
  */
-#define INITGUID
 #include "platform.h"
 #include <gnunet_util_lib.h>
 #include <gnunet_identity_service.h>
 #include <gnunet_dnsparser_lib.h>
 #include <gnunet_namestore_service.h>
 #include <gnunet_gns_service.h>
+#include <initguid.h>
 #include "gnunet_w32nsp_lib.h"
 #include "w32resolver.h"
 #include <nspapi.h>
@@ -50,6 +50,16 @@ DEFINE_GUID(SVCID_INET_HOSTADDRBYNAME, 0x0002a803, 0x0000, 0x0000, 0xc0, 0x00, 0
 
 struct request
 {
+  /**
+   * We keep these in a doubly-linked list (for cleanup).
+   */
+  struct request *next;
+
+  /**
+   * We keep these in a doubly-linked list (for cleanup).
+   */
+  struct request *prev;
+
   struct GNUNET_SERVER_Client *client;
   GUID sc;
   int af;
@@ -58,6 +68,16 @@ struct request
   struct GNUNET_GNS_LookupRequest *lookup_request;
 };
 
+/**
+ * Head of the doubly-linked list (for cleanup).
+ */
+static struct request *rq_head;
+
+/**
+ * Tail of the doubly-linked list (for cleanup).
+ */
+static struct request *rq_tail;
+
 /**
  * Handle to GNS service.
  */
@@ -92,12 +112,11 @@ static int got_egos = 0;
  * 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)
+do_shutdown (void *cls)
 {
+  struct request *rq;
   if (NULL != id_op)
   {
     GNUNET_IDENTITY_cancel (id_op);
@@ -108,6 +127,16 @@ do_shutdown (void *cls,
     GNUNET_IDENTITY_disconnect (identity);
     identity = NULL;
   }
+  while (NULL != (rq = rq_head))
+  {
+    if (NULL != rq->lookup_request)
+      GNUNET_GNS_lookup_cancel(rq->lookup_request);
+    GNUNET_CONTAINER_DLL_remove (rq_head, rq_tail, rq);
+    GNUNET_free_non_null (rq->name);
+    if (rq->u8name)
+      free (rq->u8name);
+    GNUNET_free (rq);
+  }
   if (NULL != gns)
   {
     GNUNET_GNS_disconnect (gns);
@@ -195,7 +224,7 @@ transmit_callback (void *cls, size_t size, void *buf)
     return 0;
   }
   GNUNET_assert (size >= msize);
-  memcpy (buf, tcc->msg, msize);
+  GNUNET_memcpy (buf, tcc->msg, msize);
   GNUNET_free (tcc->msg);
   GNUNET_free (tcc);
   for (tcc = tcc_head; tcc; tcc = tcc->next)
@@ -300,6 +329,7 @@ process_lookup_result (void* cls, uint32_t rd_count,
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
       "Got lookup result with count %u for rq %p with client %p\n",
       rd_count, rq, rq->client);
+  rq->lookup_request = NULL;
 
   if (rd_count == 0)
   {
@@ -308,6 +338,7 @@ process_lookup_result (void* cls, uint32_t rd_count,
     msg->header.size = htons (size);
     msg->header.type = htons (GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE);
     transmit (rq->client, &msg->header);
+    GNUNET_CONTAINER_DLL_remove (rq_head, rq_tail, rq);
     GNUNET_free_non_null (rq->name);
     if (rq->u8name)
       free (rq->u8name);
@@ -387,14 +418,14 @@ process_lookup_result (void* cls, uint32_t rd_count,
   ptr += sizeof (GUID);
   size_recalc += sizeof (GUID);
   GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
-  memcpy (qs->lpServiceClassId, &rq->sc, sizeof (GUID));
+  GNUNET_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));
+  GNUNET_memcpy (qs->lpNSProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS, sizeof (GUID));
   qs->lpszContext = NULL;
   qs->dwNumberOfProtocols = 0;
   qs->lpafpProtocols = NULL;
@@ -509,7 +540,7 @@ process_lookup_result (void* cls, uint32_t rd_count,
         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));
+        GNUNET_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_DNSPARSER_TYPE_AAAA)
@@ -520,7 +551,7 @@ process_lookup_result (void* cls, uint32_t rd_count,
         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));
+        GNUNET_memcpy (he->h_addr_list[j], rd[i].data, sizeof (struct in6_addr));
         j++;
       }
     }
@@ -538,6 +569,7 @@ process_lookup_result (void* cls, uint32_t rd_count,
   MarshallWSAQUERYSETW (qs, &rq->sc);
   transmit (rq->client, &msg->header);
   transmit (rq->client, msgend);
+  GNUNET_CONTAINER_DLL_remove (rq_head, rq_tail, rq);
   GNUNET_free_non_null (rq->name);
   if (rq->u8name)
     free (rq->u8name);
@@ -608,7 +640,7 @@ get_ip_from_hostname (struct GNUNET_SERVER_Client *client,
   if (namelen)
   {
     rq->name = GNUNET_malloc ((namelen + 1) * sizeof (wchar_t));
-    memcpy (rq->name, name, (namelen + 1) * sizeof (wchar_t));
+    GNUNET_memcpy (rq->name, name, (namelen + 1) * sizeof (wchar_t));
     rq->u8name = hostname;
   }
 
@@ -625,6 +657,7 @@ get_ip_from_hostname (struct GNUNET_SERVER_Client *client,
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Lookup launched, waiting for a reply\n");
     GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_CONTAINER_DLL_insert (rq_head, rq_tail, rq);
   }
   else
   {
@@ -694,10 +727,12 @@ handle_get (void *cls, struct GNUNET_SERVER_Client *client,
               sc.Data4[3], sc.Data4[4], sc.Data4[5], sc.Data4[6], sc.Data4[7]);
 
   hostname = (const wchar_t *) &msg[1];
-  if (hostname[size - 1] != L'\0')
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "name of %u bytes (last word is 0x%0X): %*S\n",
+        size, hostname[size / 2 - 2], size / 2, hostname);
+  if (hostname[size / 2 - 1] != L'\0')
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "name of length %u, not 0-terminated: %*S\n",
-        size, size, hostname);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "name of length %u, not 0-terminated (%d-th word is 0x%0X): %*S\n",
+        size, size / 2 - 1, hostname[size / 2 - 1], size, hostname);
     GNUNET_break (0);
     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
     return;
@@ -792,8 +827,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
-  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_shutdown,
-      NULL);
+  GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
+                                NULL);
 
   identity = GNUNET_IDENTITY_connect (cfg, NULL, NULL);
   if (NULL == identity)