REST/NAMESTORE: rework API
[oweals/gnunet.git] / src / cadet / gnunet-service-cadet_channel.c
index 905211e00ad2fa928969b49817bcb6da286eca67..bd95428be107b32734f8e378b95634ba8b7504d2 100644 (file)
@@ -679,9 +679,8 @@ GCCH_channel_local_new (struct CadetClient *owner,
   GCCH_hash_port (&ch->h_port,
                  port,
                  GCP_get_id (destination));
-  if (0 == memcmp (&my_full_id,
-                   GCP_get_id (destination),
-                   sizeof (struct GNUNET_PeerIdentity)))
+  if (0 == GNUNET_memcmp (&my_full_id,
+                   GCP_get_id (destination)))
   {
     struct OpenPort *op;
 
@@ -1185,9 +1184,8 @@ GCCH_handle_channel_open_ack (struct CadetChannel *ch,
       GNUNET_break_op (0);
       return;
     }
-    if (0 != memcmp (&ch->port,
-                    port,
-                    sizeof (struct GNUNET_HashCode)))
+    if (0 != GNUNET_memcmp (&ch->port,
+                    port))
     {
       /* Other peer failed to provide the right port,
         refuse connection. */
@@ -1318,9 +1316,9 @@ GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
          ((msg->mid.mid == ch->mid_recv.mid) &&
           (GNUNET_YES == ch->reliable)) ||
          ((GNUNET_NO == ch->reliable) &&
-          (msg->mid.mid >= ch->mid_recv.mid) &&
+          (ntohl (msg->mid.mid) >= ntohl (ch->mid_recv.mid)) &&
           ((NULL == ccc->head_recv) ||
-           (msg->mid.mid < ccc->head_recv->mid.mid))) )
+           (ntohl (msg->mid.mid) < ntohl (ccc->head_recv->mid.mid)))) )
     {
       LOG (GNUNET_ERROR_TYPE_DEBUG,
            "Giving %u bytes of payload with MID %u from %s to client %s\n",
@@ -1331,8 +1329,23 @@ GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
       ccc->client_ready = GNUNET_NO;
       GSC_send_to_client (ccc->c,
                           env);
-      ch->mid_recv.mid = htonl (1 + ntohl (ch->mid_recv.mid));
+      if (GNUNET_NO == ch->out_of_order)
+        ch->mid_recv.mid = htonl (1 + ntohl (msg->mid.mid));
+      else
+        ch->mid_recv.mid = htonl (1 + ntohl (ch->mid_recv.mid));
       ch->mid_futures >>= 1;
+      if ( (GNUNET_YES == ch->out_of_order) &&
+          (GNUNET_NO == ch->reliable) )
+      {
+       /* possibly shift by more if we skipped messages */
+       uint64_t delta = htonl (msg->mid.mid) - 1 - ntohl (ch->mid_recv.mid);
+       
+       if (delta > 63)
+         ch->mid_futures = 0;
+       else
+         ch->mid_futures >>= delta;
+       ch->mid_recv.mid = htonl (1 + ntohl (msg->mid.mid));
+      }
       send_channel_data_ack (ch);
       return;
     }
@@ -1398,7 +1411,8 @@ GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
      * We always send if possible in this case.
      * It is guaranteed that the queued MID < received MID
      **/
-    if (GNUNET_YES == ccc->client_ready)
+    if ((NULL != ccc->head_recv) &&
+        (GNUNET_YES == ccc->client_ready))
     {
       next_msg = ccc->head_recv;
       LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -1409,7 +1423,7 @@ GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
       ccc->client_ready = GNUNET_NO;
       GSC_send_to_client (ccc->c,
                           next_msg->env);
-      ch->mid_recv.mid = htonl (1 + ntohl (ch->mid_recv.mid));
+      ch->mid_recv.mid = htonl (1 + ntohl (next_msg->mid.mid));
       ch->mid_futures >>= 1;
       send_channel_data_ack (ch);
       GNUNET_CONTAINER_DLL_remove (ccc->head_recv,
@@ -1417,12 +1431,11 @@ GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
                                    next_msg);
       ccc->num_recv--;
       /* Do not process duplicate MID */
-      if ((msg->mid.mid == next_msg->mid.mid) || /* Duplicate */
-          (msg->mid.mid < ch->mid_recv.mid)) /* Old */
+      if (msg->mid.mid == next_msg->mid.mid) /* Duplicate */
       {
         /* Duplicate within the queue, drop */
         LOG (GNUNET_ERROR_TYPE_DEBUG,
-             "Message on %s (mid %u) dropped\n",
+             "Message on %s (mid %u) dropped, duplicate\n",
              GCCH_2s (ch),
              ntohl (msg->mid.mid));
         GNUNET_free (next_msg);
@@ -1432,6 +1445,17 @@ GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
       GNUNET_free (next_msg);
     }
 
+    if (ntohl (msg->mid.mid) < ntohl (ch->mid_recv.mid)) /* Old */
+    {
+      /* Duplicate within the queue, drop */
+      LOG (GNUNET_ERROR_TYPE_DEBUG,
+           "Message on %s (mid %u) dropped, old.\n",
+           GCCH_2s (ch),
+           ntohl (msg->mid.mid));
+      GNUNET_MQ_discard (env);
+      return;
+    }
+
     /* Channel is unreliable, so we do not ACK. But we also cannot
        allow buffering everything, so check if we have space... */
     if (ccc->num_recv >= ch->max_pending_messages)
@@ -1586,9 +1610,8 @@ handle_matching_ack (struct CadetChannel *ch,
        (NULL != cti) )
   {
     GCC_ack_observed (cti);
-    if (0 == memcmp (cti,
-                     &crm->connection_taken,
-                     sizeof (struct GNUNET_CADET_ConnectionTunnelIdentifier)))
+    if (0 == GNUNET_memcmp (cti,
+                     &crm->connection_taken))
     {
       GCC_latency_observed (cti,
                             GNUNET_TIME_absolute_get_duration (crm->first_transmission_time));