gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r28904 - gnunet/src/mesh


From: gnunet
Subject: [GNUnet-SVN] r28904 - gnunet/src/mesh
Date: Fri, 30 Aug 2013 05:23:59 +0200

Author: bartpolot
Date: 2013-08-30 05:23:58 +0200 (Fri, 30 Aug 2013)
New Revision: 28904

Modified:
   gnunet/src/mesh/gnunet-service-mesh-enc.c
Log:
- avoid loopback ack nightmare: send local traffic directly to destination 
client

Modified: gnunet/src/mesh/gnunet-service-mesh-enc.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh-enc.c   2013-08-29 22:32:22 UTC (rev 
28903)
+++ gnunet/src/mesh/gnunet-service-mesh-enc.c   2013-08-30 03:23:58 UTC (rev 
28904)
@@ -1037,7 +1037,19 @@
 static struct MeshChannel *
 channel_get (struct MeshTunnel2 *t, MESH_ChannelNumber chid);
 
+/**
+ * Modify the data message ID from global to local and send to client.
+ * 
+ * @param ch Channel on which to send the message.
+ * @param msg Message to modify and send.
+ * @param fwd Forward?
+ */
+static void
+channel_send_client_data (struct MeshChannel *ch,
+                          const struct GNUNET_MESH_Data *msg,
+                          int fwd);
 
+
 /**
  * Change the tunnel state.
  *
@@ -1194,6 +1206,20 @@
 
 
 /**
+ * Demultiplex by message type and call appropriate handler for a message
+ * towards a channel of a local tunnel.
+ *
+ * @param t Tunnel this message came on.
+ * @param msgh Message header.
+ * @param fwd Is this message fwd?
+ */
+static void
+handle_decrypted (struct MeshTunnel2 *t,
+                  const struct GNUNET_MessageHeader *msgh,
+                  int fwd);
+
+
+/**
  * Dummy function to separate declarations from definitions in function list.
  */
 void
@@ -1586,8 +1612,6 @@
 }
 
 
-
-
 /**
  * Is this peer the first one on the connection?
  *
@@ -1628,6 +1652,26 @@
 
 
 /**
+ * Is the recipient client for this channel on this peer?
+ *
+ * @param ch Channel.
+ * @param fwd Is this for fwd traffic?
+ *
+ * @return GNUNET_YES in case it is.
+ */
+static int
+channel_is_terminal (struct MeshChannel *ch, int fwd)
+{
+  if (NULL == ch->t || NULL == ch->t->connection_head)
+  {
+    GNUNET_break (0);
+    return GNUNET_NO;
+  }
+  return connection_is_terminal (ch->t->connection_head, fwd);
+}
+
+
+/**
  * Get free buffer space towards the client on a specific channel.
  *
  * @param ch Channel.
@@ -1908,6 +1952,13 @@
               peer2s (ch->t->peer), ch->gid);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  %s\n",
               GNUNET_MESH_DEBUG_M2S (ntohs (message->type)));
+
+  if (channel_is_terminal (ch, fwd))
+  {
+    handle_decrypted (ch->t, message, fwd);
+    return;
+  }
+  
   type = fwd ? GNUNET_MESSAGE_TYPE_MESH_FWD : GNUNET_MESSAGE_TYPE_MESH_BCK;
   iv = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX);
 
@@ -1916,7 +1967,6 @@
   msg->header.size = htons (sizeof (struct GNUNET_MESH_Encrypted) + size);
   msg->iv = GNUNET_htonll (iv);
   tunnel_encrypt (ch->t, &msg[1], message, size, iv, fwd);
-
   send_prebuilt_message_tunnel (msg, ch->t, ch, fwd);
 }
 
@@ -2773,6 +2823,8 @@
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " *** Polling!\n");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " *** connection %s[%X]\n", 
               peer2s (c->t->peer), c->id);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ***   %s\n", 
+              fc == &c->fwd_fc ? "FWD" : "BCK");
 
   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_POLL);
   msg.header.size = htons (sizeof (msg));
@@ -2920,6 +2972,7 @@
   return GNUNET_CONTAINER_multihashmap32_get (c->own_channels, chid);
 }
 
+#if 0
 
 static void
 channel_debug (struct MeshChannel *ch)
@@ -2929,7 +2982,8 @@
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*** DEBUG NULL CHANNEL ***\n");
     return;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel %X\n", ch->gid);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel %s:%X\n",
+              peer2s (ch->t->peer), ch->gid);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  root %p/%p\n",
               ch->root, ch->root_rel);
   if (NULL != ch->root)
@@ -2948,18 +3002,39 @@
                 ch->dest_rel->client_ready ? "YES" : "NO");
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  id %X\n", ch->lid_dest);
   }
+}
 
+static void
+fc_debug (struct MeshFlowControl *fc)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    IN: %u/%u\n",
+              fc->last_pid_recv, fc->last_ack_sent);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    OUT: %u/%u\n",
+              fc->last_pid_sent, fc->last_ack_recv);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    QUEUE: %u/%u\n",
+              fc->queue_n, fc->queue_max);
 }
 
+static void
+connection_debug (struct MeshConnection *c)
+{
+  if (NULL == c)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*** DEBUG NULL CONNECTION ***\n");
+    return;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection %s:%X\n",
+              peer2s (c->t->peer), GNUNET_h2s (&c->id));
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  state: %u, pending msgs: %u\n", 
+              c->state, c->pending_messages);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  FWD FC\n");
+  fc_debug (&c->fwd_fc);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  BCK FC\n");
+  fc_debug (&c->bck_fc);
+}
 
-/**
- * Search for a tunnel by global ID using full PeerIdentities.
- *
- * @param t Tunnel containing the channel.
- * @param chid Public channel number.
- *
- * @return channel handler, NULL if doesn't exist
- */
+#endif
+
 static struct MeshChannel *
 channel_get (struct MeshTunnel2 *t, MESH_ChannelNumber chid)
 {
@@ -3399,13 +3474,6 @@
 }
 
 
-/**
- * Modify the data message ID from global to local and send to client.
- * 
- * @param ch Channel on which to send the message.
- * @param msg Message to modify and send.
- * @param fwd Forward?
- */
 static void
 channel_send_client_data (struct MeshChannel *ch,
                           const struct GNUNET_MESH_Data *msg,
@@ -3777,31 +3845,41 @@
 {
   unsigned int buffer;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "send ack %s on %p %p\n",
+              fwd ? "FWD" : "BCK", c, ch);
   if (NULL == c || connection_is_terminal (c, fwd))
   {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  getting from Channel\n");
     buffer = tunnel_get_buffer (NULL == c ? ch->t : c->t, fwd);
   }
   else
   {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  getting from Connection\n");
     GNUNET_assert (NULL != c);
     buffer = connection_get_buffer (c, fwd);
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  buffer available: %u\n", buffer);
 
   if (NULL == c)
   {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  sending on all connections\n");
     GNUNET_assert (NULL != ch);
     channel_send_connections_ack (ch, buffer, fwd);
   }
   else if (connection_is_origin (c, fwd))
   {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  sending on channel...\n");
     if (0 < buffer)
     {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  really sending!\n");
       GNUNET_assert (NULL != ch);
       send_local_ack (ch, fwd);
     }
   }
   else
   {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  sending on connection\n");
     connection_send_ack (c, buffer, fwd);
   }
 }
@@ -4921,10 +4999,11 @@
     return; /* Drop this message */
   }
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "pid %u\n", fc->last_pid_sent);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ack %u\n", fc->last_ack_recv);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "last pid %u\n", fc->last_pid_sent);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "     ack %u\n", fc->last_ack_recv);
   if (GMC_is_pid_bigger (fc->last_pid_sent + 1, fc->last_ack_recv) &&
-      GNUNET_SCHEDULER_NO_TASK == fc->poll_task)
+      GNUNET_SCHEDULER_NO_TASK == fc->poll_task &&
+      GNUNET_MESSAGE_TYPE_MESH_POLL != type)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "no buffer space (%u > %u): starting poll\n",
@@ -4991,10 +5070,8 @@
  * @param t Tunnel on which we got this message.
  * @param message Unencryted data message.
  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
- *
- * @return channel which this message was on.
  */
-static struct MeshChannel *
+static void
 handle_data (struct MeshTunnel2 *t, const struct GNUNET_MESH_Data *msg, int 
fwd)
 {
   struct MeshChannelReliability *rel;
@@ -5011,7 +5088,7 @@
       sizeof (struct GNUNET_MessageHeader))
   {
     GNUNET_break (0);
-    return NULL;
+    return;
   }
   type = ntohs (msg->header.type);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a %s message\n",
@@ -5025,7 +5102,7 @@
   {
     GNUNET_STATISTICS_update (stats, "# data on unknown channel", 1, 
GNUNET_NO);
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel unknown\n");
-    return NULL;
+    return;
   }
 
   /*  Initialize FWD/BCK data */
@@ -5035,7 +5112,7 @@
   if (NULL == c)
   {
     GNUNET_break (0);
-    return NULL;
+    return;
   }
 
   tunnel_change_state (t, MESH_TUNNEL_READY);
@@ -5082,7 +5159,6 @@
   }
 
   channel_send_data_ack (ch, fwd);
-  return ch;
 }
 
 /**
@@ -5091,10 +5167,8 @@
  * @param t Tunnel on which we got this message.
  * @param message Data message.
  * @param fwd Is this a fwd ACK? (dest->orig)
- *
- * @return channel this message was on.
  */
-static struct MeshChannel *
+static void
 handle_data_ack (struct MeshTunnel2 *t,
                  const struct GNUNET_MESH_DataACK *msg, int fwd)
 {
@@ -5113,7 +5187,7 @@
   if (NULL == ch)
   {
     GNUNET_STATISTICS_update (stats, "# ack on unknown channel", 1, GNUNET_NO);
-    return NULL;
+    return;
   }
   ack = ntohl (msg->mid);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! %s ACK %u\n",
@@ -5130,7 +5204,7 @@
   if (NULL == rel)
   {
     GNUNET_break (0);
-    return NULL;
+    return;
   }
 
   for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next)
@@ -5178,7 +5252,6 @@
     else
       GNUNET_break (0);
   }
-  return ch;
 }
 
 
@@ -5478,10 +5551,8 @@
  * @param t Tunnel this channel is to be created in.
  * @param msg Message.
  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
- *
- * @return channel this message was on.
  */
-static struct MeshChannel *
+static void
 handle_channel_create (struct MeshTunnel2 *t,
                        struct GNUNET_MESH_ChannelCreate *msg,
                        int fwd)
@@ -5496,7 +5567,7 @@
   if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelCreate))
   {
     GNUNET_break_op (0);
-    return NULL;
+    return;
   }
 
   /* Check if channel exists */
@@ -5510,7 +5581,7 @@
     {
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   duplicate CC!!\n");
       channel_send_ack (ch, !fwd);
-      return NULL;
+      return;
     }
   }
   else
@@ -5529,7 +5600,7 @@
     /* TODO send reject */
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  no client has port registered\n");
     /* TODO free ch */
-    return NULL;
+    return;
   }
 
   channel_add_client (ch, c);
@@ -5538,8 +5609,7 @@
 
   send_local_channel_create (ch);
   channel_send_ack (ch, !fwd);
-
-  return ch;
+  send_local_ack (ch, !fwd);
 }
 
 
@@ -5549,10 +5619,8 @@
  * @param t Tunnel this channel is to be created in.
  * @param msg Message.
  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
- *
- * @return channel this message was on.
  */
-static struct MeshChannel *
+static void
 handle_channel_ack (struct MeshTunnel2 *t,
                     struct GNUNET_MESH_ChannelManage *msg,
                     int fwd)
@@ -5565,7 +5633,7 @@
   if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage))
   {
     GNUNET_break_op (0);
-    return NULL;
+    return;
   }
 
   /* Check if channel exists */
@@ -5575,11 +5643,10 @@
   {
     GNUNET_break_op (0);
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   channel %u unknown!!\n", chid);
-    return NULL;
+    return;
   }
 
   channel_confirm (ch, !fwd);
-  return ch;
 }
 
 
@@ -5589,10 +5656,8 @@
  * @param t Tunnel this channel is to be destroyed of.
  * @param msg Message.
  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
- *
- * @return channel this message was on.
  */
-static struct MeshChannel *
+static void
 handle_channel_destroy (struct MeshTunnel2 *t,
                         struct GNUNET_MESH_ChannelManage *msg,
                         int fwd)
@@ -5604,7 +5669,7 @@
   if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage))
   {
     GNUNET_break_op (0);
-    return NULL;
+    return;
   }
 
   /* Check if channel exists */
@@ -5613,13 +5678,53 @@
   if (NULL == ch)
   {
     /* Probably a retransmission, safe to ignore */
-    return NULL;
+    return;
   }
 
   send_local_channel_destroy (ch, fwd);
   channel_destroy (ch);
+}
 
-  return ch;
+
+static void
+handle_decrypted (struct MeshTunnel2 *t,
+                  const struct GNUNET_MessageHeader *msgh,
+                  int fwd)
+{
+  switch (ntohs (msgh->type))
+  {
+    case GNUNET_MESSAGE_TYPE_MESH_DATA:
+      /* Don't send hop ACK, wait for client to ACK */
+      handle_data (t, (struct GNUNET_MESH_Data *) msgh, fwd);
+      break;
+
+    case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
+      handle_data_ack (t, (struct GNUNET_MESH_DataACK *) msgh, fwd);
+      break;
+
+    case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
+      handle_channel_create (t,
+                             (struct GNUNET_MESH_ChannelCreate *) msgh,
+                             fwd);
+      break;
+
+    case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
+      handle_channel_ack (t,
+                          (struct GNUNET_MESH_ChannelManage *) msgh,
+                          fwd);
+      break;
+
+    case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
+      handle_channel_destroy (t,
+                              (struct GNUNET_MESH_ChannelManage *) msgh,
+                              fwd);
+      break;
+
+    default:
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "end-to-end message not known (%u)\n",
+                  ntohs (msgh->type));
+  }
 }
 
 
@@ -5709,7 +5814,7 @@
     size_t dsize = size - sizeof (struct GNUNET_MESH_Encrypted);
     char cbuf[dsize];
     struct GNUNET_MessageHeader *msgh;
-    struct MeshChannel *ch;
+    unsigned int off;
 
     /* TODO signature verification */
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  message for us!\n");
@@ -5717,44 +5822,14 @@
 
     fc->last_pid_recv = pid;
     tunnel_decrypt (t, cbuf, &msg[1], dsize, msg->iv, fwd);
-    msgh = (struct GNUNET_MessageHeader *) cbuf;
-    switch (ntohs (msgh->type))
+    off = 0;
+    while (off < dsize)
     {
-      case GNUNET_MESSAGE_TYPE_MESH_DATA:
-        /* Don't send hop ACK, wait for client to ACK */
-        ch = handle_data (t, (struct GNUNET_MESH_Data *) msgh, fwd);
-        break;
-
-      case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
-        ch = handle_data_ack (t, (struct GNUNET_MESH_DataACK *) msgh, fwd);
-        break;
-
-      case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
-        ch = handle_channel_create (t,
-                                    (struct GNUNET_MESH_ChannelCreate *) msgh,
-                                    fwd);
-        break;
-
-      case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
-        ch = handle_channel_ack (t,
-                                 (struct GNUNET_MESH_ChannelManage *) msgh,
-                                 fwd);
-        break;
-
-      case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
-        ch = handle_channel_destroy (t,
-                                     (struct GNUNET_MESH_ChannelManage *) msgh,
-                                     fwd);
-        break;
-
-      default:
-        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                    "end-to-end message not known (%u)\n",
-                    ntohs (msgh->type));
-        ch = NULL;
+      msgh = (struct GNUNET_MessageHeader *) &cbuf[off];
+      handle_decrypted (t, msgh, fwd);
+      off += ntohs (msgh->size);
     }
-
-    send_ack (c, ch, fwd);
+    send_ack (c, NULL, fwd);
     return GNUNET_OK;
   }
 




reply via email to

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