- more debug, fix ack supression
[oweals/gnunet.git] / src / mesh / gnunet-service-mesh.c
index 933ce492a9f0a8d817e8677bfdd4ca497f4e0e9e..5bb6345a66446ea6c54902d7d0376571cbbf0153 100644 (file)
@@ -42,6 +42,7 @@
  * - relay corking down to core
  * - set ttl relative to tree depth
  * - Add data ACK count in path ACK
+ * - Make common GNUNET_MESH_Data header for unicast, to_orig, multicast
  * TODO END
  */
 
@@ -3166,7 +3167,7 @@ tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c)
 
   GNUNET_array_append (t->clients, t->nclients, c);
   clinfo.fwd_ack = t->fwd_pid + 1;
-  clinfo.bck_ack = t->nobuffer ? 1 : INITIAL_WINDOW_SIZE;
+  clinfo.bck_ack = t->nobuffer ? 1 : INITIAL_WINDOW_SIZE - 1;
   clinfo.fwd_pid = t->fwd_pid;
   clinfo.bck_pid = (uint32_t) -1; // Expected next: 0
   t->nclients--;
@@ -3255,7 +3256,7 @@ tunnel_send_multicast_iterator (void *cls, GNUNET_PEER_Id neighbor_id)
 
 
 /**
- * Send a message in a tunnel in multicast, sending a copy to each child node
+ * Queue a message in a tunnel in multicast, sending a copy to each child node
  * down the local one in the tunnel tree.
  *
  * @param t Tunnel in which to send the data.
@@ -3271,6 +3272,7 @@ tunnel_send_multicast (struct MeshTunnel *t,
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               " sending a multicast packet...\n");
+
   mdata = GNUNET_malloc (sizeof (struct MeshData));
   mdata->data_len = ntohs (msg->size);
   mdata->reference_counter = GNUNET_malloc (sizeof (unsigned int));
@@ -3281,6 +3283,16 @@ tunnel_send_multicast (struct MeshTunnel *t,
   {
     struct GNUNET_MESH_Multicast *mcast;
 
+    if (t->fwd_queue_n >= t->fwd_queue_max)
+    {
+      GNUNET_break (0);
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  queue full!\n");
+      GNUNET_free (mdata->data);
+      GNUNET_free (mdata->reference_counter);
+      GNUNET_free (mdata);
+      return;
+    }
+    t->fwd_queue_n++;
     mcast = (struct GNUNET_MESH_Multicast *) mdata->data;
     mcast->ttl = htonl (ntohl (mcast->ttl) - 1);
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  data packet, ttl: %u\n",
@@ -3290,8 +3302,9 @@ tunnel_send_multicast (struct MeshTunnel *t,
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  not a data packet, no ttl\n");
   }
-  if (NULL != t->owner && GNUNET_YES != t->owner->shutting_down
-      && GNUNET_NO == internal)
+  if (NULL != t->owner &&
+      GNUNET_YES != t->owner->shutting_down &&
+      GNUNET_NO == internal)
   {
     mdata->task = GNUNET_malloc (sizeof (GNUNET_SCHEDULER_TaskIdentifier));
     (*(mdata->task)) =
@@ -3304,6 +3317,9 @@ tunnel_send_multicast (struct MeshTunnel *t,
   tree_iterate_children (t->tree, &tunnel_send_multicast_iterator, mdata);
   if (*(mdata->reference_counter) == 0)
   {
+    GNUNET_break (0);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "  no one to send data to\n");
     GNUNET_free (mdata->data);
     GNUNET_free (mdata->reference_counter);
     if (NULL != mdata->task)
@@ -3312,8 +3328,8 @@ tunnel_send_multicast (struct MeshTunnel *t,
       GNUNET_free (mdata->task);
       GNUNET_SERVER_receive_done (t->owner->handle, GNUNET_OK);
     }
-    // FIXME change order?
     GNUNET_free (mdata);
+    t->fwd_queue_n--;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               " sending a multicast packet done\n");
@@ -3378,7 +3394,7 @@ tunnel_get_neighbor_fc (const struct MeshTunnel *t,
     cinfo->id = GNUNET_PEER_intern (peer);
     cinfo->skip = t->fwd_pid;
 
-    delta = t->nobuffer ? 1 : INITIAL_WINDOW_SIZE;
+    delta = t->nobuffer ? 1 : INITIAL_WINDOW_SIZE - 1;
     cinfo->fwd_ack = t->fwd_pid + delta;
     cinfo->bck_ack = delta;
 
@@ -3706,9 +3722,16 @@ tunnel_send_fwd_ack (struct MeshTunnel *t, uint16_t type)
         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, nobuffer\n");
         return;
       }
-      if (t->fwd_queue_max > t->fwd_queue_n * 2)
+      if (t->fwd_queue_max > t->fwd_queue_n * 2 &&
+          GMC_is_pid_bigger(t->last_fwd_ack, t->fwd_pid))
       {
         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, buffer free\n");
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "  t->qmax: %u, t->qn: %u\n",
+                    t->fwd_queue_max, t->fwd_queue_n);
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "  t->pid: %u, t->ack: %u\n",
+                    t->fwd_pid, t->last_fwd_ack);
         return;
       }
       break;
@@ -4366,29 +4389,70 @@ queue_destroy (struct MeshPeerQueue *queue, int clear_cls)
  *         NULL when there are no transmittable messages.
  */
 struct MeshPeerQueue *
-queue_get_next (static struct MeshPeerInfo *peer)
+queue_get_next (const struct MeshPeerInfo *peer)
 {
   struct MeshPeerQueue *q;
   struct MeshTunnel *t;
   struct MeshTransmissionDescriptor *info;
+  struct MeshTunnelChildInfo *cinfo;
+  struct GNUNET_MESH_Unicast *ucast;
+  struct GNUNET_MESH_ToOrigin *to_orig;
+  struct GNUNET_MESH_Multicast *mcast;
+  struct GNUNET_PeerIdentity id;
+  uint32_t pid;
+  uint32_t ack;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   selecting message\n");
   for (q = peer->queue_head; NULL != q; q = q->next)
   {
     t = q->tunnel;
+    info = q->cls;
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "*********     %s\n",
+                GNUNET_MESH_DEBUG_M2S(q->type));
     switch (q->type)
     {
       case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
-        info = q->cls;
+        ucast = (struct GNUNET_MESH_Unicast *) info->mesh_data->data;
+        pid = ntohl (ucast->pid);
+        GNUNET_PEER_resolve (info->peer->id, &id);
+        cinfo = tunnel_get_neighbor_fc(t, &id);
+        ack = cinfo->fwd_ack;
         break;
       case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
+        to_orig = (struct GNUNET_MESH_ToOrigin *) info->mesh_data->data;
+        pid = ntohl (to_orig->pid);
+        ack = t->bck_ack;
         break;
       case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
+        mcast = (struct GNUNET_MESH_Multicast *) info->mesh_data->data;
+        pid = ntohl (mcast->pid);
+        GNUNET_PEER_resolve (info->peer->id, &id);
+        cinfo = tunnel_get_neighbor_fc(t, &id);
+        ack = cinfo->fwd_ack;
         break;
       default:
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "*********   OK!\n");
         return q;
+    }
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "*********     ACK: %u, PID: %u\n",
+                    ack, pid);
+    if (GNUNET_NO == GMC_is_pid_bigger(pid, ack))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "*********   OK!\n");
+      return q;
+    }
+    else
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "*********     NEXT!\n");
     }
   }
-  // FIXME fc WIP
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "*********   nothing found\n");
   return NULL;
 }
 
@@ -4412,15 +4476,17 @@ queue_send (void *cls, size_t size, void *buf)
     size_t data_size;
 
     peer->core_transmit = NULL;
-    queue = peer->queue_head;
-
+    
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* Queue send\n");
+    queue = queue_get_next(peer);
 
-    /* If queue is empty, send should have been cancelled */
+    /* Queue has no internal mesh traffic not sendable payload */
     if (NULL == queue)
     {
-        GNUNET_break(0);
-        return 0;
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   not ready, return\n");
+      if (NULL == peer->queue_head)
+        GNUNET_break(0); // Should've been canceled
+      return 0;
     }
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   not empty\n");
 
@@ -4429,6 +4495,8 @@ queue_send (void *cls, size_t size, void *buf)
     {
         struct GNUNET_PeerIdentity id;
 
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "*********   not enough room, reissue\n");
         GNUNET_PEER_resolve (peer->id, &id);
         peer->core_transmit =
             GNUNET_CORE_notify_transmit_ready(core_handle,
@@ -4448,8 +4516,8 @@ queue_send (void *cls, size_t size, void *buf)
     {
       t->fwd_queue_n--;
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                  "*********   unicast: %u\n",
-                  t->fwd_queue_n);
+                  "*********   unicast: t->q (%u/%u)\n",
+                  t->fwd_queue_n, t->fwd_queue_max);
     }
     else if (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == queue->type)
     {
@@ -4465,8 +4533,8 @@ queue_send (void *cls, size_t size, void *buf)
       case GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN:
       case GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY:
         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                    "*********   raw: %u\n",
-                    queue->type);
+                    "*********   raw: %s\n",
+                    GNUNET_MESH_DEBUG_M2S (queue->type));
         /* Fall through */
       case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
       case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
@@ -4487,6 +4555,7 @@ queue_send (void *cls, size_t size, void *buf)
       case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   multicast\n");
         data_size = send_core_data_multicast(queue->cls, size, buf);
+        // t->fwd_queue_n--; FIXME fc
         tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_MULTICAST);
         break;
       case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE:
@@ -5536,6 +5605,7 @@ path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   msg = (struct GNUNET_MESH_Multicast *) cbuf;
   msg->header.size = htons (size);
   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_MULTICAST);
+  // FIXME: change type to != MULTICAST
   msg->oid = my_full_id;
   msg->tid = htonl (t->id.tid);
   msg->ttl = htonl (default_ttl);
@@ -7594,6 +7664,9 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
   GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
                       &my_full_id.hashPubKey);
   myid = GNUNET_PEER_intern (&my_full_id);
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Mesh for peer [%s] starting\n",
+              GNUNET_i2s(&my_full_id));
 
 //   transport_handle = GNUNET_TRANSPORT_connect(c,
 //                                               &my_full_id,