- avoid infinite ACK loops when creating loopback channels
[oweals/gnunet.git] / src / mesh / gnunet-service-mesh_channel.c
index 8b90938b1faff179b11ed52cf6db5250a466b82c..170ba955e4742623ea9d4a39a5d6db59306d8957 100644 (file)
@@ -603,7 +603,7 @@ rel_message_free (struct MeshReliableMessage *copy)
  * Confirm we got a channel create.
  *
  * @param ch The channel to confirm.
- * @param fwd Should we send the ACK fwd?
+ * @param fwd Should we send a FWD ACK? (going dest->root)
  */
 static void
 channel_send_ack (struct MeshChannel *ch, int fwd)
@@ -652,7 +652,10 @@ channel_confirm (struct MeshChannel *ch, int fwd)
       /* TODO return? */
     }
   }
-  channel_send_ack (ch, fwd);
+
+  /* In case of a FWD ACk (SYNACK) send a BCK ACK (ACK). */
+  if (fwd)
+    channel_send_ack (ch, !fwd);
 }
 
 
@@ -811,7 +814,8 @@ channel_destroy (struct MeshChannel *ch)
  */
 static struct MeshChannel *
 channel_new (struct MeshTunnel3 *t,
-             struct MeshClient *owner, MESH_ChannelNumber lid_root)
+             struct MeshClient *owner,
+             MESH_ChannelNumber lid_root)
 {
   struct MeshChannel *ch;
 
@@ -865,8 +869,8 @@ handle_loopback (struct MeshChannel *ch,
 
   type = ntohs (msgh->type);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Loopback %s message!\n",
-       GNUNET_MESH_DEBUG_M2S (type));
+       "Loopback %s %s message!\n",
+       fwd ? "FWD" : "BCK", GNUNET_MESH_DEBUG_M2S (type));
 
   switch (type)
   {
@@ -880,8 +884,8 @@ handle_loopback (struct MeshChannel *ch,
       break;
 
     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
-       // FIXME store channel in loopback tunnel?
-      GMCH_handle_create ((struct GNUNET_MESH_ChannelCreate *) msgh,
+      GMCH_handle_create (ch->t,
+                          (struct GNUNET_MESH_ChannelCreate *) msgh,
                           fwd);
       break;
 
@@ -1076,7 +1080,7 @@ GMCH_send_data (struct MeshChannel *ch,
  * @param fwd Is for FWD traffic? (ACK dest->owner)
  */
 void
-GMCH_send_ack (struct MeshChannel *ch, int fwd)
+GMCH_send_data_ack (struct MeshChannel *ch, int fwd)
 {
   struct GNUNET_MESH_DataACK msg;
   struct MeshChannelReliability *rel;
@@ -1329,8 +1333,7 @@ GMCH_handle_local_create (struct MeshClient *c,
   ch->root_rel->ch = ch;
   ch->root_rel->expected_delay = MESH_RETRANSMIT_TIME;
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "CREATED CHANNEL %s[%x]:%u (%x)\n",
-       GMT_2s (t), ch->gid, ch->port, ch->lid_root);
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "CREATED CHANNEL %s\n", GMCH_2s (ch));
 
   /* Send create channel */
   {
@@ -1414,7 +1417,7 @@ GMCH_handle_data (struct MeshChannel *ch,
                 mid, rel->mid_recv, rel->mid_recv + 64);
   }
 
-  GMCH_send_ack (ch, fwd);
+  GMCH_send_data_ack (ch, fwd);
 }
 
 
@@ -1505,11 +1508,13 @@ GMCH_handle_data_ack (struct MeshChannel *ch,
 /**
  * Handler for channel create messages.
  *
+ * @param t Tunnel this channel will be in.
  * @param msg Message.
  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
  */
 struct MeshChannel *
-GMCH_handle_create (const struct GNUNET_MESH_ChannelCreate *msg,
+GMCH_handle_create (struct MeshTunnel3 *t,
+                    const struct GNUNET_MESH_ChannelCreate *msg,
                     int fwd)
 {
   MESH_ChannelNumber chid;
@@ -1519,9 +1524,13 @@ GMCH_handle_create (const struct GNUNET_MESH_ChannelCreate *msg,
 
   chid = ntohl (msg->chid);
 
-  /* Create channel */
-  ch = channel_new (NULL, NULL, 0); /* FIXME pass t */
-  ch->gid = chid;
+  ch = GMT_get_channel (t, chid);
+  if (NULL == ch)
+  {
+    /* Create channel */
+    ch = channel_new (t, NULL, 0);
+    ch->gid = chid;
+  }
   channel_set_options (ch, ntohl (msg->opt));
 
   /* Find a destination client */
@@ -1541,7 +1550,8 @@ GMCH_handle_create (const struct GNUNET_MESH_ChannelCreate *msg,
     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! Reliable\n");
 
   GMCH_send_create (ch);
-  GMCH_send_ack (ch, fwd);
+  channel_send_ack (ch, fwd);
+  GMCH_send_data_ack (ch, fwd);
 
   if (GNUNET_NO == ch->dest_rel->client_ready)
   {
@@ -1616,8 +1626,8 @@ void
 GMCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
                             struct MeshChannel *ch, int fwd)
 {
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Channel %s:%X %s\n",
-       GMT_2s (ch->t), ch->gid, fwd ? "FWD" : "BCK");
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "Send %s on channel %s\n",
+       fwd ? "FWD" : "BCK", GMCH_2s (ch));
   LOG (GNUNET_ERROR_TYPE_DEBUG, "  %s\n",
        GNUNET_MESH_DEBUG_M2S (ntohs (message->type)));