Merge branch 'master' of ssh://gnunet.org/gnunet
[oweals/gnunet.git] / src / cadet / gnunet-service-cadet-new_tunnels.c
index 1b7e4d9d31709886a8775178095f8191a2761cb9..d50860629312b54edd47d843109a8bee3a97927d 100644 (file)
@@ -603,7 +603,11 @@ GCT_count_any_connections (const struct CadetTunnel *t)
 static struct CadetTConnection *
 get_ready_connection (struct CadetTunnel *t)
 {
-  return t->connection_ready_head;
+  struct CadetTConnection *hd = t->connection_ready_head;
+
+  GNUNET_assert ( (NULL == hd) ||
+                  (GNUNET_YES == hd->is_ready) );
+  return hd;
 }
 
 
@@ -1315,7 +1319,8 @@ send_kx (struct CadetTunnel *t,
   struct GNUNET_CADET_TunnelKeyExchangeMessage *msg;
   enum GNUNET_CADET_KX_Flags flags;
 
-  if (NULL == ct)
+  if ( (NULL == ct) ||
+       (GNUNET_NO == ct->is_ready) )
     ct = get_ready_connection (t);
   if (NULL == ct)
   {
@@ -1328,7 +1333,7 @@ send_kx (struct CadetTunnel *t,
   }
   cc = ct->cc;
   LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Sending KX on %s via %s using %s in state %s\n",
+       "Sending KX on %s via %s in state %s\n",
        GCT_2s (t),
        GCC_2s (cc),
        estate2s (t->estate));
@@ -1820,9 +1825,12 @@ GCT_handle_kx_auth (struct CadetTConnection *ct,
   {
     /* This KX_AUTH is not using the latest KX/KX_AUTH data
        we transmitted to the sender, refuse it, try KX again. */
-    GNUNET_break_op (0);
+    GNUNET_STATISTICS_update (stats,
+                              "# KX_AUTH not using our last KX received (auth failure)",
+                              1,
+                              GNUNET_NO);
     send_kx (t,
-             NULL,
+             ct,
              &t->ax);
     return;
   }
@@ -1888,12 +1896,12 @@ get_next_free_ctn (struct CadetTunnel *t)
   ctn = ntohl (t->next_ctn.cn);
   while (NULL !=
          GNUNET_CONTAINER_multihashmap32_get (t->channels,
-                                              ctn))
+                                              ctn | highbit))
   {
-    ctn = ((ctn + 1) & (~ HIGH_BIT)) | highbit;
+    ctn = ((ctn + 1) & (~ HIGH_BIT));
   }
-  t->next_ctn.cn = htonl (((ctn + 1) & (~ HIGH_BIT)) | highbit);
-  ret.cn = htonl (ctn);
+  t->next_ctn.cn = htonl ((ctn + 1) & (~ HIGH_BIT));
+  ret.cn = htonl (ctn | highbit);
   return ret;
 }
 
@@ -1968,13 +1976,19 @@ GCT_connection_lost (struct CadetTConnection *ct)
   struct CadetTunnel *t = ct->t;
 
   if (GNUNET_YES == ct->is_ready)
+  {
     GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
                                  t->connection_ready_tail,
                                  ct);
+    t->num_ready_connections--;
+  }
   else
+  {
     GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
                                  t->connection_busy_tail,
                                  ct);
+    t->num_busy_connections--;
+  }
   GNUNET_free (ct);
 }
 
@@ -2576,6 +2590,10 @@ GCT_consider_path (struct CadetTunnel *t,
                    struct CadetPeerPath *p,
                    unsigned int off)
 {
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Considering %s for %s\n",
+       GCPP_2s (p),
+       GCT_2s (t));
   (void) consider_path_cb (t,
                            p,
                            off);
@@ -3008,8 +3026,21 @@ GCT_handle_encrypted (struct CadetTConnection *ct,
   case CADET_TUNNEL_KEY_UNINITIALIZED:
   case CADET_TUNNEL_KEY_AX_RECV:
     /* We did not even SEND our KX, how can the other peer
-       send us encrypted data? */
-    GNUNET_break_op (0);
+       send us encrypted data? Must have been that we went
+       down and the other peer still things we are up.
+       Let's send it KX back. */
+    GNUNET_STATISTICS_update (stats,
+                              "# received encrypted without any KX",
+                              1,
+                              GNUNET_NO);
+    if (NULL != t->kx_task)
+    {
+      GNUNET_SCHEDULER_cancel (t->kx_task);
+      t->kx_task = NULL;
+    }
+    send_kx (t,
+             ct,
+             &t->ax);
     return;
   case CADET_TUNNEL_KEY_AX_SENT_AND_RECV:
     /* We send KX, and other peer send KX to us at the same time.
@@ -3051,10 +3082,6 @@ GCT_handle_encrypted (struct CadetTConnection *ct,
     break;
   }
 
-  GNUNET_STATISTICS_update (stats,
-                            "# received encrypted",
-                            1,
-                            GNUNET_NO);
   decrypted_size = -1;
   if (CADET_TUNNEL_KEY_OK == t->estate)
   {
@@ -3118,16 +3145,27 @@ GCT_handle_encrypted (struct CadetTConnection *ct,
   if (-1 == decrypted_size)
   {
     /* Decryption failed for good, complain. */
-    GNUNET_break_op (0);
     LOG (GNUNET_ERROR_TYPE_WARNING,
-         "%s failed to decrypt and validate encrypted data\n",
+         "%s failed to decrypt and validate encrypted data, retrying KX\n",
          GCT_2s (t));
     GNUNET_STATISTICS_update (stats,
                               "# unable to decrypt",
                               1,
                               GNUNET_NO);
+    if (NULL != t->kx_task)
+    {
+      GNUNET_SCHEDULER_cancel (t->kx_task);
+      t->kx_task = NULL;
+    }
+    send_kx (t,
+             ct,
+             &t->ax);
     return;
   }
+  GNUNET_STATISTICS_update (stats,
+                            "# decrypted bytes",
+                            decrypted_size,
+                            GNUNET_NO);
 
   /* The MST will ultimately call #handle_decrypted() on each message. */
   t->current_ct = ct;
@@ -3179,6 +3217,10 @@ GCT_send (struct CadetTunnel *t,
                 &ax_msg[1],
                 message,
                 payload_size);
+  GNUNET_STATISTICS_update (stats,
+                            "# encrypted bytes",
+                            payload_size,
+                            GNUNET_NO);
   ax_msg->ax_header.Ns = htonl (t->ax.Ns++);
   ax_msg->ax_header.PNs = htonl (t->ax.PNs);
   /* FIXME: we should do this once, not once per message;