gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnunet] 01/02: attempting to fix #5464


From: gnunet
Subject: [GNUnet-SVN] [gnunet] 01/02: attempting to fix #5464
Date: Thu, 01 Nov 2018 15:29:54 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository gnunet.

commit 11916b980c6f022ef4be5e34eea2a0abdce68b10
Author: Christian Grothoff <address@hidden>
AuthorDate: Thu Nov 1 15:29:10 2018 +0100

    attempting to fix #5464
---
 src/cadet/.gitignore                         |   3 +-
 src/cadet/gnunet-service-cadet_channel.c     |   7 +-
 src/transport/transport_api2_communication.c | 432 +++++++++++++++++++++++++++
 3 files changed, 439 insertions(+), 3 deletions(-)

diff --git a/src/cadet/.gitignore b/src/cadet/.gitignore
index 44382fde9..935049ce8 100644
--- a/src/cadet/.gitignore
+++ b/src/cadet/.gitignore
@@ -21,4 +21,5 @@ test_cadet_local
 test_cadet_single
 gnunet-service-cadet-new
 test_cadet_local_mq
-test_cadet_*_new
\ No newline at end of file
+test_cadet_*_newtest_cadet_2_reopen
+test_cadet_5_reopen
diff --git a/src/cadet/gnunet-service-cadet_channel.c 
b/src/cadet/gnunet-service-cadet_channel.c
index 06711dc8b..8ef598132 100644
--- a/src/cadet/gnunet-service-cadet_channel.c
+++ b/src/cadet/gnunet-service-cadet_channel.c
@@ -500,6 +500,11 @@ channel_destroy (struct CadetChannel *ch)
     GNUNET_free (crm->data_message);
     GNUNET_free (crm);
   }
+  if (CADET_CHANNEL_LOOSE == ch->state)
+  {
+    GSC_drop_loose_channel (&ch->h_port,
+                           ch);
+  }
   if (NULL != ch->owner)
   {
     free_channel_client (ch->owner);
@@ -1136,8 +1141,6 @@ GCCH_channel_local_destroy (struct CadetChannel *ch,
          target, but that never went anywhere. Nothing to do here. */
       break;
     case CADET_CHANNEL_LOOSE:
-      GSC_drop_loose_channel (&ch->h_port,
-                              ch);
       break;
     default:
       GCT_send_channel_destroy (ch->t,
diff --git a/src/transport/transport_api2_communication.c 
b/src/transport/transport_api2_communication.c
new file mode 100644
index 000000000..e33c5f444
--- /dev/null
+++ b/src/transport/transport_api2_communication.c
@@ -0,0 +1,432 @@
+/*
+     This file is part of GNUnet.
+     Copyright (C) 2018 GNUnet e.V.
+
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License,
+     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
+     Affero General Public License for more details.
+    
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file transport/transport_api2_communication.c
+ * @brief implementation of the gnunet_transport_communication_service.h API
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_protocols.h"
+#include "gnunet_transport_communication_service.h"
+#include "transport.h"
+
+
+/**
+ * Opaque handle to the transport service for communicators.
+ */
+struct GNUNET_TRANSPORT_CommunicatorHandle
+{
+  /**
+   * Head of DLL of addresses this communicator offers to the transport 
service.
+   */
+  struct GNUNET_TRANSPORT_AddressIdentifier *ai_head;
+
+  /**
+   * Tail of DLL of addresses this communicator offers to the transport 
service.
+   */
+  struct GNUNET_TRANSPORT_AddressIdentifier *ai_tail;
+
+  /**
+   * Our configuration.
+   */
+  const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+  /**
+   * Name of the communicator.
+   */
+  const char *name;
+
+  /**
+   * Function to call when the transport service wants us to initiate
+   * a communication channel with another peer.
+   */
+  GNUNET_TRANSPORT_CommunicatorMqInit mq_init;
+
+  /**
+   * Closure for @e mq_init.
+   */
+  void *mq_init_cls;
+
+  /**
+   * MTU of the communicator
+   */
+  size_t mtu;
+  
+  /**
+   * Internal UUID for the address used in communication with the
+   * transport service.
+   */
+  uint32_t aid_gen;
+  
+};
+
+
+
+/**
+ * Internal representation of an address a communicator is
+ * currently providing for the transport service.
+ */
+struct GNUNET_TRANSPORT_AddressIdentifier
+{
+
+  /**
+   * Kept in a DLL.
+   */
+  struct GNUNET_TRANSPORT_AddressIdentifier *next;
+
+  /**
+   * Kept in a DLL.
+   */
+  struct GNUNET_TRANSPORT_AddressIdentifier *prev;
+  
+  /**
+   * Transport handle where the address was added.
+   */
+  struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
+
+  /**
+   * The actual address.
+   */
+  char *address;
+
+  /**
+   * When does the address expire? (Expected lifetime of the
+   * address.)
+   */
+  struct GNUNET_TIME_Relative expiration;
+  
+  /**
+   * Internal UUID for the address used in communication with the
+   * transport service.
+   */
+  uint32_t aid;
+
+  /**
+   * Network type for the address.
+   */
+  enum GNUNET_ATS_Network_Type nt;
+  
+};
+
+
+/**
+ * (re)connect our communicator to the transport service
+ *
+ * @param ch handle to reconnect
+ */
+static void
+reconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch);
+
+
+/**
+ * Send message to the transport service about address @a ai
+ * being now available.
+ *
+ * @param ai address to add
+ */
+static void
+send_add_address (struct GNUNET_TRANSPORT_AddressIdentifier *ai)
+{
+  struct GNUNET_MQ_Envelope *env;
+  struct GNUNET_TRANSPORT_AddAddressMessage *aam;
+  
+  if (NULL == ai->ch->mq)
+    return;
+  env = GNUNET_MQ_msg_extra (aam,
+                            strlen (ai->address) + 1,
+                            GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_ADDRESS);
+  aam->expiration = GNUNET_TIME_relative_to_nbo (ai->expiration);
+  aam->nt = htonl ((uint32_t) ai->nt);
+  memcpy (&aam[1],
+         ai->address,
+         strlen (ai->address) + 1);
+  GNUNET_MQ_send (ai->ch->mq,
+                 env);
+}
+
+
+/**
+ * Send message to the transport service about address @a ai
+ * being no longer available.
+ *
+ * @param ai address to delete
+ */
+static void
+send_del_address (struct GNUNET_TRANSPORT_AddressIdentifier *ai)
+{
+  struct GNUNET_MQ_Envelope *env;
+  struct GNUNET_TRANSPORT_DelAddressMessage *dam;
+  
+  if (NULL == ai->ch->mq)
+    return;
+  env = GNUNET_MQ_msg (dam,                         
+                      GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_ADDRESS);
+  dam.aid = htonl (ai->aid);
+  GNUNET_MQ_send (ai->ch->mq,
+                 env);
+}
+
+
+/**
+ * Function called on MQ errors.
+ */
+static void
+error_handler (void *cls,
+              enum GNUNET_MQ_Error error)
+{
+  struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
+  
+  GNUNET_MQ_destroy (ch->mq);
+  ch->mq = NULL;
+  /* TODO: maybe do this with exponential backoff/delay */
+  reconnect (ch);
+}
+
+
+/**
+ * (re)connect our communicator to the transport service
+ *
+ * @param ch handle to reconnect
+ */
+static void
+reconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
+{
+  struct GNUNET_MQ_MessageHandler handlers[] = {
+    GNUNET_MQ_handler_end()
+  };
+  
+  ch->mq = GNUNET_CLIENT_connect (cfg,
+                                 "transport",
+                                 handlers,
+                                 &error_handler,
+                                 ch);
+  for (struct GNUNET_TRANSPORT_AddressIdentifier ai = ch->ai_head;
+       NULL != ai;
+       ai = ai->next)
+    send_add_address (ai);
+}
+
+
+/**
+ * Connect to the transport service.
+ *
+ * @param cfg configuration to use
+ * @param name name of the communicator that is connecting
+ * @param mtu maximum message size supported by communicator, 0 if
+ *            sending is not supported, SIZE_MAX for no MTU
+ * @param mq_init function to call to initialize a message queue given
+ *                the address of another peer, can be NULL if the
+ *                communicator only supports receiving messages
+ * @param mq_init_cls closure for @a mq_init
+ * @return NULL on error
+ */
+struct GNUNET_TRANSPORT_CommunicatorHandle *
+GNUNET_TRANSPORT_communicator_connect (const struct 
GNUNET_CONFIGURATION_Handle *cfg,
+                                       const char *name,
+                                       size_t mtu,
+                                       GNUNET_TRANSPORT_CommunicatorMqInit 
mq_init,
+                                       void *mq_init_cls)
+{
+  struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
+  
+  ch = GNUNET_new (struct GNUNET_TRANSPORT_CommunicatorHandle);
+  ch->cfg = cfg;
+  ch->name = name;
+  ch->mtu = mtu;
+  ch->mq_init = mq_init;
+  ch->mq_init_cls = mq_init_cls;
+  reconnect (ch);
+  if (NULL == ch->mq)
+  {
+    GNUNET_free (ch);
+    return NULL;
+  }
+  return ch;
+}
+
+
+/**
+ * Disconnect from the transport service.
+ *
+ * @param ch handle returned from connect
+ */
+void
+GNUNET_TRANSPORT_communicator_disconnect (struct 
GNUNET_TRANSPORT_CommunicatorHandle *ch)
+{
+  while (NULL != ch->ai_head)
+  {
+    GNUNET_break (0); /* communicator forgot to remove address, warn! */
+    GNUNET_TRANSPORT_communicator_address_remove (ch->ai_head);
+  }
+  GNUNET_MQ_destroy (ch->mq);
+  GNUNET_free (ch);
+}
+
+
+/* ************************* Receiving *************************** */
+
+
+/**
+ * Notify transport service that the communicator has received
+ * a message.
+ *
+ * @param ch connection to transport service
+ * @param sender presumed sender of the message (details to be checked
+ *        by higher layers)
+ * @param msg the message
+ * @param cb function to call once handling the message is done, NULL if
+ *         flow control is not supported by this communicator
+ * @param cb_cls closure for @a cb
+ * @return #GNUNET_OK if all is well, #GNUNET_NO if the message was
+ *         immediately dropped due to memory limitations (communicator
+ *         should try to apply back pressure),
+ *         #GNUNET_SYSERR if the message is ill formed and communicator
+ *         should try to reset stream
+ */
+int
+GNUNET_TRANSPORT_communicator_receive (struct 
GNUNET_TRANSPORT_CommunicatorHandle *ch,
+                                       const struct GNUNET_PeerIdentity 
*sender,
+                                       const struct GNUNET_MessageHeader *msg,
+                                       
GNUNET_TRANSPORT_MessageCompletedCallback cb,
+                                       void *cb_cls)
+{
+  struct GNUNET_MQ_Envelope *env;
+  struct GNUNET_TRANSPORT_IncomingMessage *im;
+  uint16_t msize;
+  
+  if (NULL == ai->ch->mq)
+    return;
+  msize = ntohs (msg->size);
+  env = GNUNET_MQ_msg_extra (im,
+                            msize,
+                            GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG);
+  if (NULL == env)
+  {
+    GNUNET_break (0);
+    return;
+  }
+  im->sender = *sender;
+  memcpy (&im[1],
+         msg,
+         msize);
+  GNUNET_MQ_send (ai->ch->mq,
+                 env);
+}
+
+
+/* ************************* Discovery *************************** */
+
+/**
+ * Handle returned to identify the internal data structure the transport
+ * API has created to manage a message queue to a particular peer.
+ */
+struct GNUNET_TRANSPORT_QueueHandle
+{
+};
+
+
+/**
+ * Notify transport service that an MQ became available due to an
+ * "inbound" connection or because the communicator discovered the
+ * presence of another peer.
+ *
+ * @param ch connection to transport service
+ * @param peer peer with which we can now communicate
+ * @param address address in human-readable format, 0-terminated, UTF-8
+ * @param nt which network type does the @a address belong to?
+ * @param mq message queue of the @a peer
+ * @return API handle identifying the new MQ
+ */
+struct GNUNET_TRANSPORT_QueueHandle *
+GNUNET_TRANSPORT_communicator_mq_add (struct 
GNUNET_TRANSPORT_CommunicatorHandle *ch,
+                                      const struct GNUNET_PeerIdentity *peer,
+                                      const char *address,
+                                      enum GNUNET_ATS_Network_Type nt,
+                                      struct GNUNET_MQ_Handle *mq)
+{
+}
+
+
+/**
+ * Notify transport service that an MQ became unavailable due to a
+ * disconnect or timeout.
+ *
+ * @param qh handle for the queue that must be invalidated
+ */
+void
+GNUNET_TRANSPORT_communicator_mq_del (struct GNUNET_TRANSPORT_QueueHandle *qh)
+{
+}
+
+
+
+
+/**
+ * Notify transport service about an address that this communicator
+ * provides for this peer.
+ *
+ * @param ch connection to transport service
+ * @param address our address in human-readable format, 0-terminated, UTF-8
+ * @param nt which network type does the address belong to?
+ * @param expiration when does the communicator forsee this address expiring?
+ */
+struct GNUNET_TRANSPORT_AddressIdentifier *
+GNUNET_TRANSPORT_communicator_address_add (struct 
GNUNET_TRANSPORT_CommunicatorHandle *ch,
+                                           const char *address,
+                                           enum GNUNET_ATS_Network_Type nt,
+                                           struct GNUNET_TIME_Relative 
expiration)
+{
+  struct GNUNET_TRANSPORT_AddressIdentifier *ai;
+
+  ai = GNUNET_new (struct GNUNET_TRANSPORT_AddressIdentifier);
+  ai->ch = ch;
+  ai->address = GNUNET_strdup (address);
+  ai->nt = nt;
+  ai->expiration = expiration;
+  ai->aid = handle->aid_gen++;
+  GNUNET_CONTAINER_DLL_insert (handle->ai_head,
+                              handle->ai_tail,
+                              ai);
+  send_add_address (ai);
+  return ai;
+}
+
+
+/**
+ * Notify transport service about an address that this communicator no
+ * longer provides for this peer.
+ *
+ * @param ai address that is no longer provided
+ */
+void
+GNUNET_TRANSPORT_communicator_address_remove (struct 
GNUNET_TRANSPORT_AddressIdentifier *ai)
+{
+  struct GNUNET_TRANSPORT_CommunicatorHandle *ch = ai->ch;
+
+  send_del_address (ai);
+  GNUNET_free (ai->address);
+  GNUNET_CONTAINER_DLL_remove (ch->ai_head,
+                              ch->ai_tail,
+                              ai);
+  GNUNET_free (ai);
+}
+
+
+/* end of transport_api2_communication.c */

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]