- fixes, intendation
[oweals/gnunet.git] / src / gns / gnunet-gns-helper-service-w32.c
index 93b8436979e9a384a254e4ced4a7590e522ea0ac..02badb50bfa0136d3b506b715c22ec8e755fd963 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2012 Christian Grothoff (and other contributing authors)
+     Copyright (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
@@ -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.
  */
@@ -98,6 +118,7 @@ static void
 do_shutdown (void *cls,
             const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
+  struct request *rq;
   if (NULL != id_op)
   {
     GNUNET_IDENTITY_cancel (id_op);
@@ -108,6 +129,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);
@@ -141,6 +172,11 @@ struct TransmitCallbackContext
    */
   struct GNUNET_SERVER_TransmitHandle *th;
 
+
+  /**
+   * Handle for the client to which to send
+   */
+  struct GNUNET_SERVER_Client *client;
 };
 
 
@@ -193,6 +229,17 @@ transmit_callback (void *cls, size_t size, void *buf)
   memcpy (buf, tcc->msg, msize);
   GNUNET_free (tcc->msg);
   GNUNET_free (tcc);
+  for (tcc = tcc_head; tcc; tcc = tcc->next)
+  {
+    if (NULL == tcc->th)
+    {
+      tcc->th = GNUNET_SERVER_notify_transmit_ready (tcc->client,
+          ntohs (tcc->msg->size),
+          GNUNET_TIME_UNIT_FOREVER_REL,
+          &transmit_callback, tcc);
+      break;
+    }
+  }
   return msize;
 }
 
@@ -218,18 +265,11 @@ transmit (struct GNUNET_SERVER_Client *client,
   }
   tcc = GNUNET_new (struct TransmitCallbackContext);
   tcc->msg = msg;
-  if (NULL ==
-      (tcc->th =
-       GNUNET_SERVER_notify_transmit_ready (client,
-                                           ntohs (msg->size),
-                                            GNUNET_TIME_UNIT_FOREVER_REL,
-                                            &transmit_callback, tcc)))
-  {
-    GNUNET_break (0);
-    GNUNET_free (msg);
-    GNUNET_free (tcc);
-    return;
-  }
+  tcc->client = client;
+  tcc->th = GNUNET_SERVER_notify_transmit_ready (client,
+      ntohs (msg->size),
+      GNUNET_TIME_UNIT_FOREVER_REL,
+      &transmit_callback, tcc);
   GNUNET_CONTAINER_DLL_insert (tcc_head, tcc_tail, tcc);
 }
 
@@ -291,6 +331,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)
   {
@@ -299,6 +340,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);
@@ -355,7 +397,6 @@ process_lookup_result (void* cls, uint32_t rd_count,
     }
     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));
@@ -364,10 +405,8 @@ process_lookup_result (void* cls, uint32_t rd_count,
   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);
+    msg->sc_data4[i] = rq->sc.Data4[i];
   qs = (WSAQUERYSETW *) &msg[1];
   ptr = (char *) &qs[1];
   GNUNET_break (size_recalc == (size_t) ((char *) ptr - (char *) msg));
@@ -520,9 +559,7 @@ process_lookup_result (void* cls, uint32_t rd_count,
     }
     he->h_addr_list[j] = NULL;
   }
-  msgend = (struct GNUNET_MessageHeader *) ptr;
-  ptr += sizeof (struct GNUNET_MessageHeader);
-  size_recalc += sizeof (struct GNUNET_MessageHeader);
+  msgend = GNUNET_new (struct GNUNET_MessageHeader);
 
   msgend->type = htons (GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE);
   msgend->size = htons (sizeof (struct GNUNET_MessageHeader));
@@ -533,6 +570,8 @@ 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);
@@ -620,6 +659,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
   {
@@ -649,7 +689,6 @@ handle_get (void *cls, struct GNUNET_SERVER_Client *client,
   const struct GNUNET_W32RESOLVER_GetMessage *msg;
   GUID sc;
   uint16_t size;
-  uint64_t data4;
   int i;
   const wchar_t *hostname;
   int af;
@@ -665,7 +704,7 @@ handle_get (void *cls, struct GNUNET_SERVER_Client *client,
   }
 
   msize = ntohs (message->size);
-  if (msize < sizeof (struct GNUNET_W32RESOLVER_GetMessage))
+  if (msize <= sizeof (struct GNUNET_W32RESOLVER_GetMessage))
   {
     GNUNET_break (0);
     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
@@ -674,22 +713,28 @@ handle_get (void *cls, struct GNUNET_SERVER_Client *client,
   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);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+      "Got NBO GUID: %08X-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
+      msg->sc_data1, msg->sc_data2, msg->sc_data3, msg->sc_data4[0], msg->sc_data4[1],
+      msg->sc_data4[2], msg->sc_data4[3], msg->sc_data4[4], msg->sc_data4[5],
+      msg->sc_data4[6], msg->sc_data4[7]);
   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));
+    sc.Data4[i] = msg->sc_data4[i];
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Got 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]);
 
   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;