fixes
[oweals/gnunet.git] / src / dv / dv_api.c
index 12801dcd7dcb9aefbdfb88615e86d3bf3817d13c..d954d718b30b45ba9da651e67d45f7f2710916ba 100644 (file)
@@ -4,7 +4,7 @@
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
      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
+     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
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
 #include "gnunet_time_lib.h"
 #include "gnunet_dv_service.h"
 #include "dv.h"
 #include "gnunet_time_lib.h"
 #include "gnunet_dv_service.h"
 #include "dv.h"
-#include "../transport/plugin_transport.h"
-
+#include "gnunet_transport_plugin.h"
 
 
+/**
+ * Store ready to send messages
+ */
 struct PendingMessages
 {
   /**
 struct PendingMessages
 {
   /**
@@ -58,17 +60,11 @@ struct PendingMessages
 
 };
 
 
 };
 
-
-
 /**
  * Handle for the service.
  */
 struct GNUNET_DV_Handle
 {
 /**
  * Handle for the service.
  */
 struct GNUNET_DV_Handle
 {
-  /**
-   * Our scheduler.
-   */
-  struct GNUNET_SCHEDULER_Handle *sched;
 
   /**
    * Configuration to use.
 
   /**
    * Configuration to use.
@@ -95,11 +91,6 @@ struct GNUNET_DV_Handle
    */
   struct PendingMessages *current;
 
    */
   struct PendingMessages *current;
 
-  /**
-   * Kill off the connection and any pending messages.
-   */
-  int do_destroy;
-
   /**
    * Handler for messages we receive from the DV service
    */
   /**
    * Handler for messages we receive from the DV service
    */
@@ -171,6 +162,8 @@ hash_from_uid (uint32_t uid,
 /**
  * Try to (re)connect to the dv service.
  *
 /**
  * Try to (re)connect to the dv service.
  *
+ * @param ret handle to the (disconnected) dv service
+ *
  * @return GNUNET_YES on success, GNUNET_NO on failure.
  */
 static int
  * @return GNUNET_YES on success, GNUNET_NO on failure.
  */
 static int
@@ -178,10 +171,10 @@ try_connect (struct GNUNET_DV_Handle *ret)
 {
   if (ret->client != NULL)
     return GNUNET_OK;
 {
   if (ret->client != NULL)
     return GNUNET_OK;
-  ret->client = GNUNET_CLIENT_connect (ret->sched, "dv", ret->cfg);
+  ret->client = GNUNET_CLIENT_connect ("dv", ret->cfg);
   if (ret->client != NULL)
     return GNUNET_YES;
   if (ret->client != NULL)
     return GNUNET_YES;
-#if DEBUG_STATISTICS
+#if DEBUG_DV_MESSAGES
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               _("Failed to connect to the dv service!\n"));
 #endif
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               _("Failed to connect to the dv service!\n"));
 #endif
@@ -192,6 +185,9 @@ static void process_pending_message(struct GNUNET_DV_Handle *handle);
 
 /**
  * Send complete, schedule next
 
 /**
  * Send complete, schedule next
+ *
+ * @param handle handle to the dv service
+ * @param code return code for send (unused)
  */
 static void
 finish (struct GNUNET_DV_Handle *handle, int code)
  */
 static void
 finish (struct GNUNET_DV_Handle *handle, int code)
@@ -200,10 +196,19 @@ finish (struct GNUNET_DV_Handle *handle, int code)
   handle->current = NULL;
   process_pending_message (handle);
 
   handle->current = NULL;
   process_pending_message (handle);
 
+  GNUNET_free(pos->msg);
   GNUNET_free (pos);
 }
 
   GNUNET_free (pos);
 }
 
-
+/**
+ * Notification that we can send data
+ *
+ * @param cls handle to the dv service (struct GNUNET_DV_Handle)
+ * @param size how many bytes can we send
+ * @param buf where to copy the message to send
+ *
+ * @return how many bytes we copied to buf
+ */
 static size_t
 transmit_pending (void *cls, size_t size, void *buf)
 {
 static size_t
 transmit_pending (void *cls, size_t size, void *buf)
 {
@@ -248,6 +253,8 @@ transmit_pending (void *cls, size_t size, void *buf)
 
 /**
  * Try to send messages from list of messages to send
 
 /**
  * Try to send messages from list of messages to send
+ *
+ * @param handle handle to the distance vector service
  */
 static void process_pending_message(struct GNUNET_DV_Handle *handle)
 {
  */
 static void process_pending_message(struct GNUNET_DV_Handle *handle)
 {
@@ -264,11 +271,6 @@ static void process_pending_message(struct GNUNET_DV_Handle *handle)
   handle->current = handle->pending_list;
   if (NULL == handle->current)
     {
   handle->current = handle->pending_list;
   if (NULL == handle->current)
     {
-      if (handle->do_destroy)
-        {
-          handle->do_destroy = GNUNET_NO;
-          //GNUNET_DV_disconnect (handle); /* FIXME: replace with proper disconnect stuffs */
-        }
       return;
     }
   handle->pending_list = handle->pending_list->next;
       return;
     }
   handle->pending_list = handle->pending_list->next;
@@ -276,10 +278,10 @@ static void process_pending_message(struct GNUNET_DV_Handle *handle)
 
   if (NULL ==
       (handle->th = GNUNET_CLIENT_notify_transmit_ready (handle->client,
 
   if (NULL ==
       (handle->th = GNUNET_CLIENT_notify_transmit_ready (handle->client,
-                                                    ntohl(handle->current->msg->msgbuf_size),
-                                                    handle->current->msg->timeout,
-                                                    GNUNET_YES,
-                                                    &transmit_pending, handle)))
+                                                         ntohs(handle->current->msg->header.size),
+                                                         handle->current->msg->timeout,
+                                                         GNUNET_YES,
+                                                         &transmit_pending, handle)))
     {
 #if DEBUG_DV
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
     {
 #if DEBUG_DV
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -312,12 +314,10 @@ static void add_pending(struct GNUNET_DV_Handle *handle, struct GNUNET_DV_SendMe
           last = pos;
           pos = pos->next;
         }
           last = pos;
           pos = pos->next;
         }
-      new_message->next = last->next; /* Should always be null */
       last->next = new_message;
     }
   else
     {
       last->next = new_message;
     }
   else
     {
-      new_message->next = handle->pending_list; /* Will always be null */
       handle->pending_list = new_message;
     }
 
       handle->pending_list = new_message;
     }
 
@@ -347,6 +347,9 @@ void handle_message_receipt (void *cls,
 
   if (msg == NULL)
   {
 
   if (msg == NULL)
   {
+#if DEBUG_DV_MESSAGES
+    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV_API receive: connection closed\n");
+#endif
     return; /* Connection closed? */
   }
 
     return; /* Connection closed? */
   }
 
@@ -360,16 +363,15 @@ void handle_message_receipt (void *cls,
 
     received_msg = (struct GNUNET_DV_MessageReceived *)msg;
     packed_msg_len = ntohl(received_msg->msg_len);
 
     received_msg = (struct GNUNET_DV_MessageReceived *)msg;
     packed_msg_len = ntohl(received_msg->msg_len);
-    sender_address_len = ntohl(received_msg->sender_address_len);
-
-    GNUNET_assert(ntohs(msg->size) == (sizeof(struct GNUNET_DV_MessageReceived) + packed_msg_len + sender_address_len));
+    sender_address_len = ntohs(msg->size) - packed_msg_len - sizeof(struct GNUNET_DV_MessageReceived);
+    GNUNET_assert(sender_address_len > 0);
     sender_address = GNUNET_malloc(sender_address_len);
     memcpy(sender_address, &received_msg[1], sender_address_len);
     packed_msg_start = (char *)&received_msg[1];
     packed_msg = GNUNET_malloc(packed_msg_len);
     memcpy(packed_msg, &packed_msg_start[sender_address_len], packed_msg_len);
 
     sender_address = GNUNET_malloc(sender_address_len);
     memcpy(sender_address, &received_msg[1], sender_address_len);
     packed_msg_start = (char *)&received_msg[1];
     packed_msg = GNUNET_malloc(packed_msg_len);
     memcpy(packed_msg, &packed_msg_start[sender_address_len], packed_msg_len);
 
-#if DEBUG_DV
+#if DEBUG_DV_MESSAGES
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV_API receive: packed message type: %d or %d\n", ntohs(((struct GNUNET_MessageHeader *)packed_msg)->type), ((struct GNUNET_MessageHeader *)packed_msg)->type);
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV_API receive: message sender reported as %s\n", GNUNET_i2s(&received_msg->sender));
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV_API receive: distance is %u\n", ntohl(received_msg->distance));
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV_API receive: packed message type: %d or %d\n", ntohs(((struct GNUNET_MessageHeader *)packed_msg)->type), ((struct GNUNET_MessageHeader *)packed_msg)->type);
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV_API receive: message sender reported as %s\n", GNUNET_i2s(&received_msg->sender));
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV_API receive: distance is %u\n", ntohl(received_msg->distance));
@@ -445,17 +447,18 @@ int GNUNET_DV_send (struct GNUNET_DV_Handle *dv_handle,
   struct SendCallbackContext *send_ctx;
   char *end_of_message;
   GNUNET_HashCode uidhash;
   struct SendCallbackContext *send_ctx;
   char *end_of_message;
   GNUNET_HashCode uidhash;
+  int msize;
 #if DEBUG_DV_MESSAGES
   dv_handle->uid_gen = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, UINT32_MAX);
 #else
   dv_handle->uid_gen++;
 #endif
 
 #if DEBUG_DV_MESSAGES
   dv_handle->uid_gen = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, UINT32_MAX);
 #else
   dv_handle->uid_gen++;
 #endif
 
-  msg = GNUNET_malloc(sizeof(struct GNUNET_DV_SendMessage) + addrlen + msgbuf_size);
-  msg->header.size = htons(sizeof(struct GNUNET_DV_SendMessage) + addrlen + msgbuf_size);
+  msize = sizeof(struct GNUNET_DV_SendMessage) + addrlen + msgbuf_size;
+  msg = GNUNET_malloc(msize);
+  msg->header.size = htons(msize);
   msg->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND);
   memcpy(&msg->target, target, sizeof(struct GNUNET_PeerIdentity));
   msg->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_DV_SEND);
   memcpy(&msg->target, target, sizeof(struct GNUNET_PeerIdentity));
-  msg->msgbuf_size = htonl(msgbuf_size);
   msg->priority = htonl(priority);
   msg->timeout = timeout;
   msg->addrlen = htonl(addrlen);
   msg->priority = htonl(priority);
   msg->timeout = timeout;
   msg->addrlen = htonl(addrlen);
@@ -475,16 +478,25 @@ int GNUNET_DV_send (struct GNUNET_DV_Handle *dv_handle,
   return GNUNET_OK;
 }
 
   return GNUNET_OK;
 }
 
-/* Forward declaration */
-void GNUNET_DV_disconnect(struct GNUNET_DV_Handle *handle);
-
+/**
+ * Callback to transmit a start message to
+ * the DV service, once we can send
+ *
+ * @param cls struct StartContext
+ * @param size how much can we send
+ * @param buf where to copy the message
+ *
+ * @return number of bytes copied to buf
+ */
 static size_t
 transmit_start (void *cls, size_t size, void *buf)
 {
   struct StartContext *start_context = cls;
   struct GNUNET_DV_Handle *handle = start_context->handle;
   size_t tsize;
 static size_t
 transmit_start (void *cls, size_t size, void *buf)
 {
   struct StartContext *start_context = cls;
   struct GNUNET_DV_Handle *handle = start_context->handle;
   size_t tsize;
-
+#if DEBUG_DV
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DV API: sending start request to service\n");
+#endif
   if (buf == NULL)
     {
       GNUNET_free(start_context->message);
   if (buf == NULL)
     {
       GNUNET_free(start_context->message);
@@ -497,6 +509,13 @@ transmit_start (void *cls, size_t size, void *buf)
   if (size >= tsize)
   {
     memcpy(buf, start_context->message, tsize);
   if (size >= tsize)
   {
     memcpy(buf, start_context->message, tsize);
+    GNUNET_free(start_context->message);
+    GNUNET_free(start_context);
+    GNUNET_CLIENT_receive (handle->client,
+                           &handle_message_receipt,
+                           handle, GNUNET_TIME_UNIT_FOREVER_REL);
+
+
     return tsize;
   }
 
     return tsize;
   }
 
@@ -506,7 +525,6 @@ transmit_start (void *cls, size_t size, void *buf)
 /**
  * Connect to the DV service
  *
 /**
  * Connect to the DV service
  *
- * @param sched the scheduler to use
  * @param cfg the configuration to use
  * @param receive_handler method call when on receipt from the service
  * @param receive_handler_cls closure for receive_handler
  * @param cfg the configuration to use
  * @param receive_handler method call when on receipt from the service
  * @param receive_handler_cls closure for receive_handler
@@ -514,8 +532,7 @@ transmit_start (void *cls, size_t size, void *buf)
  * @return handle to the DV service
  */
 struct GNUNET_DV_Handle *
  * @return handle to the DV service
  */
 struct GNUNET_DV_Handle *
-GNUNET_DV_connect (struct GNUNET_SCHEDULER_Handle *sched,
-                  const struct GNUNET_CONFIGURATION_Handle *cfg,
+GNUNET_DV_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
                   GNUNET_DV_MessageReceivedHandler receive_handler,
                   void *receive_handler_cls)
 {
                   GNUNET_DV_MessageReceivedHandler receive_handler,
                   void *receive_handler_cls)
 {
@@ -525,12 +542,10 @@ GNUNET_DV_connect (struct GNUNET_SCHEDULER_Handle *sched,
   handle = GNUNET_malloc(sizeof(struct GNUNET_DV_Handle));
 
   handle->cfg = cfg;
   handle = GNUNET_malloc(sizeof(struct GNUNET_DV_Handle));
 
   handle->cfg = cfg;
-  handle->sched = sched;
   handle->pending_list = NULL;
   handle->current = NULL;
   handle->pending_list = NULL;
   handle->current = NULL;
-  handle->do_destroy = GNUNET_NO;
   handle->th = NULL;
   handle->th = NULL;
-  handle->client = GNUNET_CLIENT_connect(sched, "dv", cfg);
+  handle->client = GNUNET_CLIENT_connect("dv", cfg);
   handle->receive_handler = receive_handler;
   handle->receive_cls = receive_handler_cls;
 
   handle->receive_handler = receive_handler;
   handle->receive_cls = receive_handler_cls;
 
@@ -555,10 +570,6 @@ GNUNET_DV_connect (struct GNUNET_SCHEDULER_Handle *sched,
 
   handle->send_callbacks = GNUNET_CONTAINER_multihashmap_create(100);
 
 
   handle->send_callbacks = GNUNET_CONTAINER_multihashmap_create(100);
 
-  GNUNET_CLIENT_receive (handle->client,
-                         &handle_message_receipt,
-                         handle, GNUNET_TIME_UNIT_FOREVER_REL);
-
   return handle;
 }
 
   return handle;
 }