- Remove deprecated code, coverity 10236
[oweals/gnunet.git] / src / mesh / mesh_api.c
index fe2dff4e50ac8e7bcc17fe1e681a21a7a02a627b..869765153bcb192e2663b6826565097fd5dd17ab 100644 (file)
@@ -41,6 +41,7 @@
 
 #define LOG(kind,...) GNUNET_log_from (kind, "mesh-api",__VA_ARGS__)
 
+#define DEBUG_ACK GNUNET_YES
 
 /******************************************************************************/
 /************************      DATA STRUCTURES     ****************************/
@@ -205,6 +206,11 @@ struct GNUNET_MESH_Handle
    * Task for trying to reconnect.
    */
   GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
+
+#if DEBUG_ACK
+  unsigned int acks_sent;
+  unsigned int acks_recv;
+#endif
 };
 
 
@@ -331,6 +337,11 @@ struct GNUNET_MESH_Tunnel
      * Last pid received from the service.
      */
   uint32_t last_recv_pid;
+
+  /**
+   * Which ACK value have we last sent to the service?
+   */
+  uint32_t max_recv_pid;
 };
 
 
@@ -454,7 +465,7 @@ create_tunnel (struct GNUNET_MESH_Handle *h, MESH_TunnelNumber tid)
   {
     t->tid = tid;
   }
-  t->max_send_pid = 0;
+  t->max_send_pid = INITIAL_WINDOW_SIZE - 1;
   t->last_recv_pid = (uint32_t) -1;
   return t;
 }
@@ -642,7 +653,7 @@ timeout_transmission (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 
 
 /**
- * Add a transmit handle to the transmission queue by priority and set the
+ * Add a transmit handle to the transmission queue and set the
  * timeout if needed.
  *
  * @param h mesh handle with the queue head and tail
@@ -652,16 +663,7 @@ static void
 add_to_queue (struct GNUNET_MESH_Handle *h,
               struct GNUNET_MESH_TransmitHandle *th)
 {
-  struct GNUNET_MESH_TransmitHandle *p;
-
-  p = h->th_head;
-  while ((NULL != p))
-    p = p->next;
-  if (NULL == p)
-    p = h->th_tail;
-  else
-    p = p->prev;
-  GNUNET_CONTAINER_DLL_insert_after (h->th_head, h->th_tail, p, th);
+  GNUNET_CONTAINER_DLL_insert_tail (h->th_head, h->th_tail, th);
   if (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value == th->timeout.abs_value)
     return;
   th->timeout_task =
@@ -695,14 +697,28 @@ static void
 send_ack (struct GNUNET_MESH_Handle *h, struct GNUNET_MESH_Tunnel *t)
 {
   struct GNUNET_MESH_LocalAck msg;
+  uint32_t delta;
 
+  delta = t->max_recv_pid - t->last_recv_pid;
+  if (delta > ACK_THRESHOLD)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Not sending ACK on tunnel %X: ACK: %u, PID: %u, buffer %u\n",
+         t->tid, t->max_recv_pid, t->last_recv_pid, delta);
+    return;
+  }
+  t->max_recv_pid = t->last_recv_pid + INITIAL_WINDOW_SIZE;
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Sending ACK on tunnel %X: %u\n",
-       t->tid, t->last_recv_pid + 1);
+       t->tid, t->max_recv_pid);
   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
   msg.header.size = htons (sizeof (msg));
   msg.tunnel_id = htonl (t->tid);
-  msg.max_pid = htonl (t->last_recv_pid + 1);
+  msg.max_pid = htonl (t->max_recv_pid);
+
+#if DEBUG_ACK
+  t->mesh->acks_sent++;
+#endif
 
   send_packet (h, &msg.header, t);
   return;
@@ -837,7 +853,7 @@ do_reconnect (struct GNUNET_MESH_Handle *h)
       continue;
     }
     t->next_send_pid = 0;
-    t->max_send_pid = 0;
+    t->max_send_pid = INITIAL_WINDOW_SIZE - 1;
     t->last_recv_pid = (uint32_t) -1;
     tmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
     tmsg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
@@ -1128,7 +1144,8 @@ process_incoming_data (struct GNUNET_MESH_Handle *h,
     LOG (GNUNET_ERROR_TYPE_DEBUG, "  ignored!\n");
     return GNUNET_YES;
   }
-  if (GMC_is_pid_bigger(pid, t->last_recv_pid + 1))
+    if (GNUNET_YES ==
+        GMC_is_pid_bigger(pid, t->max_recv_pid))
   {
     GNUNET_break (0);
     LOG (GNUNET_ERROR_TYPE_WARNING, "  unauthorized message!\n");
@@ -1137,6 +1154,7 @@ process_incoming_data (struct GNUNET_MESH_Handle *h,
   }
   t->last_recv_pid = pid;
   type = ntohs (payload->type);
+  send_ack (h, t);
   for (i = 0; i < h->n_handlers; i++)
   {
     handler = &h->message_handlers[i];
@@ -1157,7 +1175,6 @@ process_incoming_data (struct GNUNET_MESH_Handle *h,
       {
         LOG (GNUNET_ERROR_TYPE_DEBUG,
              "callback completed successfully\n");
-        send_ack (h, t);
       }
     }
   }
@@ -1181,6 +1198,7 @@ process_ack (struct GNUNET_MESH_Handle *h,
   uint32_t ack;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Got an ACK!\n");
+  h->acks_recv++;
   msg = (struct GNUNET_MESH_LocalAck *) message;
 
   t = retrieve_tunnel (h, ntohl (msg->tunnel_id));
@@ -1194,7 +1212,7 @@ process_ack (struct GNUNET_MESH_Handle *h,
   }
   ack = ntohl (msg->max_pid);
   LOG (GNUNET_ERROR_TYPE_DEBUG, "  on tunnel %X, ack %u!\n", t->tid, ack);
-  if (ack > t->max_send_pid || PID_OVERFLOW (t->max_send_pid, ack))
+  if (GNUNET_YES == GMC_is_pid_bigger(ack, t->max_send_pid))
     t->max_send_pid = ack;
   else
     return;
@@ -1345,6 +1363,7 @@ send_callback (void *cls, size_t size, void *buf)
           to.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
           to.tid = htonl (t->tid);
           to.pid = htonl (t->next_send_pid);
+          to.ttl = 0;
           memset (&to.oid, 0, sizeof (struct GNUNET_PeerIdentity));
           memset (&to.sender, 0, sizeof (struct GNUNET_PeerIdentity));
           memcpy (cbuf, &to, sizeof (to));
@@ -1564,6 +1583,11 @@ GNUNET_MESH_disconnect (struct GNUNET_MESH_Handle *handle)
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "MESH DISCONNECT\n");
 
+#if DEBUG_ACK
+  LOG (GNUNET_ERROR_TYPE_INFO, "Sent %d ACKs\n", handle->acks_sent);
+  LOG (GNUNET_ERROR_TYPE_INFO, "Recv %d ACKs\n\n", handle->acks_recv);
+#endif
+
   t = handle->tunnels_head;
   while (NULL != t)
   {