gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [gnunet] branch master updated: starting with TNG implement


From: gnunet
Subject: [GNUnet-SVN] [gnunet] branch master updated: starting with TNG implementation
Date: Thu, 08 Nov 2018 23:10:49 +0100

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

grothoff pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new 54f722729 starting with TNG implementation
54f722729 is described below

commit 54f722729882247a318fbf686f2b2c31137ab72b
Author: Christian Grothoff <address@hidden>
AuthorDate: Thu Nov 8 23:10:47 2018 +0100

    starting with TNG implementation
---
 src/transport/gnunet-service-tng.c | 719 +++++++++++++++++++++++++++++++++++++
 src/transport/transport.h          |  23 +-
 2 files changed, 731 insertions(+), 11 deletions(-)

diff --git a/src/transport/gnunet-service-tng.c 
b/src/transport/gnunet-service-tng.c
new file mode 100644
index 000000000..8cbca3188
--- /dev/null
+++ b/src/transport/gnunet-service-tng.c
@@ -0,0 +1,719 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2010-2016, 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/gnunet-service-transport.c
+ * @brief main for gnunet-service-transport
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_statistics_service.h"
+#include "gnunet_transport_service.h"
+#include "gnunet_peerinfo_service.h"
+#include "gnunet_ats_service.h"
+#include "gnunet-service-transport.h"
+#include "transport.h"
+
+
+/**
+ * How many messages can we have pending for a given client process
+ * before we start to drop incoming messages?  We typically should
+ * have only one client and so this would be the primary buffer for
+ * messages, so the number should be chosen rather generously.
+ *
+ * The expectation here is that most of the time the queue is large
+ * enough so that a drop is virtually never required.  Note that
+ * this value must be about as large as 'TOTAL_MSGS' in the
+ * 'test_transport_api_reliability.c', otherwise that testcase may
+ * fail.
+ */
+#define MAX_PENDING (128 * 1024)
+
+
+/**
+ * What type of client is the `struct TransportClient` about?
+ */
+enum ClientType
+{
+  /**
+   * We do not know yet (client is fresh).
+   */
+  CT_NONE = 0,
+
+  /**
+   * Is the CORE service, we need to forward traffic to it.
+   */
+  CT_CORE = 1,
+
+  /**
+   * It is a monitor, forward monitor data.
+   */
+  CT_MONITOR = 2,
+
+  /**
+   * It is a communicator, use for communication.
+   */
+  CT_COMMUNICATOR = 3
+};
+
+
+/**
+ * Client connected to the transport service.
+ */
+struct TransportClient
+{
+
+  /**
+   * Kept in a DLL.
+   */
+  struct TransportClient *next;
+
+  /**
+   * Kept in a DLL.
+   */
+  struct TransportClient *prev;
+
+  /**
+   * Handle to the client.
+   */
+  struct GNUNET_SERVICE_Client *client;
+
+  /**
+   * Message queue to the client.
+   */
+  struct GNUNET_MQ_Handle *mq;
+
+  /**
+   * What type of client is this?
+   */
+  enum ClientType type;
+
+  union
+  {
+
+    /**
+     * Peer identity to monitor the addresses of.
+     * Zero to monitor all neighbours.  Valid if
+     * @e type is #CT_MONITOR.
+     */
+    struct GNUNET_PeerIdentity monitor_peer;
+
+    /**
+     * If @e type is #CT_COMMUNICATOR, this communicator
+     * supports communicating using these addresses.
+     */
+    const char *address_prefix;
+
+  } details;
+
+};
+
+
+/**
+ * Head of linked list of all clients to this service.
+ */
+static struct TransportClient *clients_head;
+
+/**
+ * Tail of linked list of all clients to this service.
+ */
+static struct TransportClient *clients_tail;
+
+/**
+ * Statistics handle.
+ */
+struct GNUNET_STATISTICS_Handle *GST_stats;
+
+/**
+ * Configuration handle.
+ */
+const struct GNUNET_CONFIGURATION_Handle *GST_cfg;
+
+/**
+ * Configuration handle.
+ */
+struct GNUNET_PeerIdentity GST_my_identity;
+
+/**
+ * Handle to peerinfo service.
+ */
+struct GNUNET_PEERINFO_Handle *GST_peerinfo;
+
+/**
+ * Our private key.
+ */
+struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key;
+
+
+/**
+ * Called whenever a client connects.  Allocates our
+ * data structures associated with that client.
+ *
+ * @param cls closure, NULL
+ * @param client identification of the client
+ * @param mq message queue for the client
+ * @return our `struct TransportClient`
+ */
+static void *
+client_connect_cb (void *cls,
+                  struct GNUNET_SERVICE_Client *client,
+                  struct GNUNET_MQ_Handle *mq)
+{
+  struct TransportClient *tc;
+
+  tc = GNUNET_new (struct TransportClient);
+  tc->client = client;
+  tc->mq = mq;
+  GNUNET_CONTAINER_DLL_insert (clients_head,
+                               clients_tail,
+                               tc);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Client %p connected\n",
+              tc);
+  return tc;
+}
+
+
+/**
+ * Called whenever a client is disconnected.  Frees our
+ * resources associated with that client.
+ *
+ * @param cls closure, NULL
+ * @param client identification of the client
+ * @param app_ctx our `struct TransportClient`
+ */
+static void
+client_disconnect_cb (void *cls,
+                     struct GNUNET_SERVICE_Client *client,
+                     void *app_ctx)
+{
+  struct TransportClient *tc = app_ctx;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Client %p disconnected, cleaning up.\n",
+              tc);
+  GNUNET_CONTAINER_DLL_remove (clients_head,
+                               clients_tail,
+                               tc);
+  switch (tc->type)
+  {
+  case CT_NONE:
+    break;
+  case CT_CORE:
+    break;
+  case CT_MONITOR:
+    break;
+  case CT_COMMUNICATOR:
+    break;
+  }
+  GNUNET_free (tc);
+}
+
+
+/**
+ * Initialize a "CORE" client.  We got a start message from this
+ * client, so add it to the list of clients for broadcasting of
+ * inbound messages.
+ *
+ * @param cls the client
+ * @param start the start message that was sent
+ */
+static void
+handle_client_start (void *cls,
+                    const struct StartMessage *start)
+{
+  struct TransportClient *tc = cls;
+  const struct GNUNET_MessageHeader *hello;
+  uint32_t options;
+
+  options = ntohl (start->options);
+  if ( (0 != (1 & options)) &&
+       (0 !=
+        memcmp (&start->self,
+                &GST_my_identity,
+                sizeof (struct GNUNET_PeerIdentity)) ) )
+  {
+    /* client thinks this is a different peer, reject */
+    GNUNET_break (0);
+    GNUNET_SERVICE_client_drop (tc->client);
+    return;
+  }
+  if (CT_NONE != tc->type)
+  {
+    GNUNET_break (0);
+    GNUNET_SERVICE_client_drop (tc->client);
+    return;
+  }
+  tc->type = CT_CORE;
+#if 0
+  hello = GST_hello_get ();
+  if (NULL != hello)
+    unicast (tc,
+             hello,
+             GNUNET_NO);
+#endif
+  GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * Client sent us a HELLO.  Check the request.
+ *
+ * @param cls the client
+ * @param message the HELLO message
+ */
+static int
+check_client_hello (void *cls,
+                   const struct GNUNET_MessageHeader *message)
+{
+  (void) cls;
+  return GNUNET_OK; /* FIXME: check here? */
+}
+
+
+/**
+ * Client sent us a HELLO.  Process the request.
+ *
+ * @param cls the client
+ * @param message the HELLO message
+ */
+static void
+handle_client_hello (void *cls,
+                    const struct GNUNET_MessageHeader *message)
+{
+  struct TransportClient *tc = cls;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+             "Received HELLO message\n");
+  GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * Client asked for transmission to a peer.  Process the request.
+ *
+ * @param cls the client
+ * @param obm the send message that was sent
+ */
+static int
+check_client_send (void *cls,
+                  const struct OutboundMessage *obm)
+{
+  uint16_t size;
+  const struct GNUNET_MessageHeader *obmm;
+
+  (void) cls;
+  size = ntohs (obm->header.size) - sizeof (struct OutboundMessage);
+  if (size < sizeof (struct GNUNET_MessageHeader))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  obmm = (const struct GNUNET_MessageHeader *) &obm[1];
+  if (size != ntohs (obmm->size))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Client asked for transmission to a peer.  Process the request.
+ *
+ * @param cls the client
+ * @param obm the send message that was sent
+ */
+static void
+handle_client_send (void *cls,
+                   const struct OutboundMessage *obm)
+{
+  struct TransportClient *tc = cls;
+  const struct GNUNET_MessageHeader *obmm;
+
+  obmm = (const struct GNUNET_MessageHeader *) &obm[1];
+}
+
+
+/**
+ * Communicator started.  Test message is well-formed.
+ *
+ * @param cls the client
+ * @param cam the send message that was sent
+ */
+static int
+check_communicator_available (void *cls,
+                              const struct 
GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam)
+{
+  const char *addr;
+  uint16_t size;
+
+  (void) cls;
+  size = ntohs (cam->header.size) - sizeof (*cam);
+  if (0 == size)
+    return GNUNET_OK; /* receive-only communicator */
+  addr = (const char *) &cam[1];
+  if ('\0' != addr[size-1])
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Communicator started.  Process the request.
+ *
+ * @param cls the client
+ * @param cam the send message that was sent
+ */
+static void
+handle_communicator_available (void *cls,
+                               const struct 
GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam)
+{
+  struct TransportClient *tc = cls;
+  uint16_t size;
+
+  if (CT_NONE != tc->type)
+  {
+    GNUNET_break (0);
+    GNUNET_SERVICE_client_drop (tc->client);
+    return;
+  }
+  tc->type = CT_COMMUNICATOR;
+  size = ntohs (cam->header.size) - sizeof (*cam);
+  if (0 == size)
+    return GNUNET_OK; /* receive-only communicator */
+  tc->details.address_prefix = GNUNET_strdup ((const char *) &cam[1]);
+  GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * Address of our peer added.  Test message is well-formed.
+ *
+ * @param cls the client
+ * @param aam the send message that was sent
+ */
+static int
+check_add_address (void *cls,
+                   const struct GNUNET_TRANSPORT_AddAddressMessage *aam)
+{
+  const char *addr;
+  uint16_t size;
+
+  (void) cls;
+  size = ntohs (aam->header.size) - sizeof (*aam);
+  if (0 == size)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  addr = (const char *) &cam[1];
+  if ('\0' != addr[size-1])
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Address of our peer added.  Process the request.
+ *
+ * @param cls the client
+ * @param aam the send message that was sent
+ */
+static void
+handle_add_address (void *cls,
+                    const struct GNUNET_TRANSPORT_AddAddressMessage *aam)
+{
+  struct TransportClient *tc = cls;
+
+  GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * Address of our peer deleted.  Process the request.
+ *
+ * @param cls the client
+ * @param dam the send message that was sent
+ */
+static void
+handle_del_address (void *cls,
+                    const struct GNUNET_TRANSPORT_DelAddressMessage *dam)
+{
+  struct TransportClient *tc = cls;
+
+  GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * Client asked for transmission to a peer.  Process the request.
+ *
+ * @param cls the client
+ * @param obm the send message that was sent
+ */
+static int
+check_incoming_msg (void *cls,
+                    const struct GNUNET_TRANSPORT_IncomingMessage *im)
+{
+  uint16_t size;
+  const struct GNUNET_MessageHeader *obmm;
+
+  (void) cls;
+  size = ntohs (im->header.size) - sizeof (*im);
+  if (size < sizeof (struct GNUNET_MessageHeader))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  obmm = (const struct GNUNET_MessageHeader *) &im[1];
+  if (size != ntohs (obmm->size))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Incoming meessage.  Process the request.
+ *
+ * @param cls the client
+ * @param im the send message that was received
+ */
+static void
+handle_incoming_msg (void *cls,
+                     const struct GNUNET_TRANSPORT_IncomingMessage *im)
+{
+  struct TransportClient *tc = cls;
+
+  GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * New queue became available.  Check message.
+ *
+ * @param cls the client
+ * @param aqm the send message that was sent
+ */
+static int
+check_add_queue_message (void *cls,
+                         const struct GNUNET_TRANSPORT_AddQueueMessage *aqm)
+{
+  const char *addr;
+  uint16_t size;
+
+  (void) cls;
+  size = ntohs (aqm->header.size) - sizeof (*aqm);
+  if (0 == size)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  addr = (const char *) &aqm[1];
+  if ('\0' != addr[size-1])
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * New queue became available.  Process the request.
+ *
+ * @param cls the client
+ * @param aqm the send message that was sent
+ */
+static void
+handle_add_queue_message (void *cls,
+                          const struct GNUNET_TRANSPORT_AddQueueMessage *aqm)
+{
+  struct TransportClient *tc = cls;
+
+  GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * Queue to a peer went down.  Process the request.
+ *
+ * @param cls the client
+ * @param dqm the send message that was sent
+ */
+static void
+handle_del_queue_message (void *cls,
+                          const struct GNUNET_TRANSPORT_DelQueueMessage *dqm)
+{
+  struct TransportClient *tc = cls;
+
+  GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * Message was transmitted.  Process the request.
+ *
+ * @param cls the client
+ * @param sma the send message that was sent
+ */
+static void
+handle_send_message_ack (void *cls,
+                         const struct GNUNET_TRANSPORT_SendMessageToAck *sma)
+{
+  struct TransportClient *tc = cls;
+
+  GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * Function called when the service shuts down.  Unloads our plugins
+ * and cancels pending validations.
+ *
+ * @param cls closure, unused
+ */
+static void
+shutdown_task (void *cls)
+{
+  (void) cls;
+
+  if (NULL != GST_stats)
+  {
+    GNUNET_STATISTICS_destroy (GST_stats,
+                               GNUNET_NO);
+    GST_stats = NULL;
+  }
+  if (NULL != GST_my_private_key)
+  {
+    GNUNET_free (GST_my_private_key);
+    GST_my_private_key = NULL;
+  }
+}
+
+
+/**
+ * Initiate transport service.
+ *
+ * @param cls closure
+ * @param c configuration to use
+ * @param service the initialized service
+ */
+static void
+run (void *cls,
+     const struct GNUNET_CONFIGURATION_Handle *c,
+     struct GNUNET_SERVICE_Handle *service)
+{
+  /* setup globals */
+  GST_cfg = c;
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_time (c,
+                                           "transport",
+                                           "HELLO_EXPIRATION",
+                                           &hello_expiration))
+  {
+    hello_expiration = GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION;
+  }
+  GST_my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
+  if (NULL == GST_my_private_key)
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
+        _("Transport service is lacking key configuration settings. 
Exiting.\n"));
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  GNUNET_CRYPTO_eddsa_key_get_public (GST_my_private_key,
+                                      &GST_my_identity.public_key);
+  GNUNET_log(GNUNET_ERROR_TYPE_INFO,
+             "My identity is `%s'\n",
+             GNUNET_i2s_full (&GST_my_identity));
+
+  GST_stats = GNUNET_STATISTICS_create ("transport",
+                                        GST_cfg);
+  GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
+                                NULL);
+  /* start subsystems */
+}
+
+
+/**
+ * Define "main" method using service macro.
+ */
+GNUNET_SERVICE_MAIN
+("transport",
+ GNUNET_SERVICE_OPTION_NONE,
+ &run,
+ &client_connect_cb,
+ &client_disconnect_cb,
+ NULL,
+ /* communication with core */
+ GNUNET_MQ_hd_fixed_size (client_start,
+                         GNUNET_MESSAGE_TYPE_TRANSPORT_START,
+                         struct StartMessage,
+                         NULL),
+ GNUNET_MQ_hd_var_size (client_hello,
+                       GNUNET_MESSAGE_TYPE_HELLO,
+                       struct GNUNET_MessageHeader,
+                       NULL),
+ GNUNET_MQ_hd_var_size (client_send,
+                       GNUNET_MESSAGE_TYPE_TRANSPORT_SEND,
+                       struct OutboundMessage,
+                       NULL),
+ /* communication with communicators */
+ GNUNET_MQ_hd_var_size (communicator_available,
+                       GNUNET_MESSAGE_TYPE_TRANSPORT_NEW_COMMUNICATOR,
+                       struct GNUNET_TRANSPORT_CommunicatorAvailableMessage,
+                       NULL),
+ GNUNET_MQ_hd_var_size (add_address,
+                       GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_ADDRESS,
+                       struct GNUNET_TRANSPORT_AddAddressMessage,
+                       NULL),
+ GNUNET_MQ_hd_fixed_size (del_address,
+                          GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_ADDRESS,
+                          struct GNUNET_TRANSPORT_DelAddressMessage,
+                          NULL),
+ GNUNET_MQ_hd_var_size (incoming_msg,
+                       GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG,
+                       struct GNUNET_TRANSPORT_IncomingMessage,
+                       NULL),
+ GNUNET_MQ_hd_var_size (add_queue_message,
+                       GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_SETUP,
+                       struct GNUNET_TRANSPORT_AddQueueMessage,
+                       NULL),
+ GNUNET_MQ_hd_fixed_size (del_queue_message,
+                          GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_TEARDOWN,
+                          struct GNUNET_TRANSPORT_DelQueueMessage,
+                          NULL),
+ GNUNET_MQ_hd_fixed_size (send_message_ack,
+                          GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG_ACK,
+                          struct GNUNET_TRANSPORT_SendMessageToAck,
+                          NULL),
+ GNUNET_MQ_handler_end ());
+
+
+/* end of file gnunet-service-transport.c */
diff --git a/src/transport/transport.h b/src/transport/transport.h
index f21863aef..1b46213cf 100644
--- a/src/transport/transport.h
+++ b/src/transport/transport.h
@@ -11,7 +11,7 @@
      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/>.
 */
@@ -94,7 +94,7 @@ struct StartMessage
 
   /**
    * 0: no options
-   * 1: The 'self' field should be checked
+   * 1: The @e self field should be checked
    * 2: this client is interested in payload traffic
    */
   uint32_t options;
@@ -404,6 +404,7 @@ struct ValidationIterateResponseMessage
   struct GNUNET_TIME_AbsoluteNBO next_validation;
 };
 
+
 /**
  * Message from the library to the transport service
  * asking for binary addresses known for a peer.
@@ -667,7 +668,7 @@ struct GNUNET_TRANSPORT_CommunicatorAvailableMessage
 
   /* Followed by the address prefix of the communicator */
 };
-  
+
 
 /**
  * Add address to the list.
@@ -694,7 +695,7 @@ struct GNUNET_TRANSPORT_AddAddressMessage
    * An `enum GNUNET_ATS_Network_Type` in NBO.
    */
   uint32_t nt;
-  
+
   /* followed by UTF-8 encoded, 0-terminated human-readable address */
 };
 
@@ -733,12 +734,12 @@ struct GNUNET_TRANSPORT_IncomingMessage
    * Do we use flow control or not?
    */
   uint32_t fc_on GNUNET_PACKED;
-  
+
   /**
    * 64-bit number to identify the matching ACK.
    */
   uint64_t fc_id GNUNET_PACKED;
-  
+
   /**
    * Sender identifier.
    */
@@ -764,12 +765,12 @@ struct GNUNET_TRANSPORT_IncomingMessageAck
    * Reserved (0)
    */
   uint32_t reserved GNUNET_PACKED;
-  
+
   /**
    * Which message is being ACKed?
    */
   uint64_t fc_id GNUNET_PACKED;
-  
+
   /**
    * Sender identifier of the original message.
    */
@@ -803,7 +804,7 @@ struct GNUNET_TRANSPORT_AddQueueMessage
    * An `enum GNUNET_ATS_Network_Type` in NBO.
    */
   uint32_t nt;
-  
+
   /* followed by UTF-8 encoded, 0-terminated human-readable address */
 };
 
@@ -895,7 +896,7 @@ struct GNUNET_TRANSPORT_SendMessageTo
    * Message ID, used for flow control.
    */
   uint64_t mid GNUNET_PACKED;
-  
+
   /**
    * Receiver identifier.
    */
@@ -925,7 +926,7 @@ struct GNUNET_TRANSPORT_SendMessageToAck
    * Message ID of the original message.
    */
   uint64_t mid GNUNET_PACKED;
-  
+
   /**
    * Receiver identifier.
    */

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



reply via email to

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