-fix time assertion introduce in last patch
[oweals/gnunet.git] / src / transport / gnunet-service-transport_neighbours.c
index ac4a44658604ff7975085626ab1ef91d05640cf1..6c51d20d838ac530f1bd82bbeb877f73780610b5 100644 (file)
@@ -413,7 +413,7 @@ struct NeighbourMapEntry
    * Flag to set if we still need to send a CONNECT_ACK message to the other peer
    * (once we have an address to use and the peer has been allowed by our
    * blacklist).  Initially set to #ACK_UNDEFINED. Set to #ACK_SEND_CONNECT_ACK
-   * if we need to send a CONNECT_ACK.  Set to #SESSION_ACK if we did
+   * if we need to send a CONNECT_ACK.  Set to #ACK_SEND_SESSION_ACK if we did
    * send a CONNECT_ACK and should go to 'S_CONNECTED' upon receiving a
    * 'SESSION_ACK' (regardless of what our own state machine might say).
    */
@@ -447,7 +447,7 @@ struct NeighbourMapEntry
 
 
 /**
- * Context for blacklist checks and the #handle_test_blacklist_cont()
+ * Context for blacklist checks and the #try_connect_bl_check_cont()
  * function.  Stores information about ongoing blacklist checks.
  */
 struct BlackListCheckContext
@@ -1230,9 +1230,10 @@ transmit_send_continuation (void *cls,
                              ("# transmission failures for messages to other peers"),
                              1, GNUNET_NO);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Sending message to `%s' of type %u was a %s\n",
+             "Sending message to `%s' of type %u with %u bytes was a %s\n",
              GNUNET_i2s (receiver),
               ntohs (((struct GNUNET_MessageHeader *) mq->message_buf)->type),
+              mq->message_buf_size,
               (success == GNUNET_OK) ? "success" : "FAILURE");
   if (NULL != mq->cont)
     mq->cont (mq->cont_cls, success, size_payload, physical);
@@ -1296,6 +1297,11 @@ try_transmission_to_peer (struct NeighbourMapEntry *n)
     return;                     /* no more messages */
   GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq);
   n->is_active = mq;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+      "Giving message with %u bytes to plugin session %p\n",
+      mq->message_buf_size, n->primary_address.session);
+
   (void) send_with_session (n,
                            mq->message_buf, mq->message_buf_size,
                            0 /* priority */, timeout, GNUNET_NO,
@@ -1635,10 +1641,11 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg,
   mq->message_buf = (const char *) &mq[1];
   mq->message_buf_size = msg_size;
   mq->timeout = GNUNET_TIME_relative_to_absolute (timeout);
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Enqueueing %u bytes to send to peer %s\n",
+      msg_size, GNUNET_i2s (target));
+
   GNUNET_CONTAINER_DLL_insert_tail (n->messages_head, n->messages_tail, mq);
-  if ( (NULL != n->is_active) ||
-       ( (NULL == n->primary_address.session) && (NULL == n->primary_address.address)) )
-    return;
   if (GNUNET_SCHEDULER_NO_TASK != n->task)
     GNUNET_SCHEDULER_cancel (n->task);
   n->task = GNUNET_SCHEDULER_add_now (&master_task, n);
@@ -1701,6 +1708,8 @@ send_session_connect_cont (void *cls,
     break;
   case GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_CONNECT_SENT:
     /* Remove address and request and go back to primary address */
+    GNUNET_STATISTICS_update (GST_stats, gettext_noop
+        ("# Failed attempts to switch addresses (failed to send CONNECT CONT)"), 1, GNUNET_NO);
     GNUNET_ATS_address_destroyed (GST_ats, n->alternative_address.address,
         n->alternative_address.session);
     GNUNET_ATS_address_destroyed (GST_ats, n->alternative_address.address,
@@ -1710,7 +1719,6 @@ send_session_connect_cont (void *cls,
         GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
     break;
   default:
-    GNUNET_break(0);
     disconnect_neighbour (n);
     break;
   }
@@ -1788,13 +1796,14 @@ send_session_connect (struct NeighbourAddress *na)
           GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
         break;
       case GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_CONNECT_SENT:
+        GNUNET_STATISTICS_update (GST_stats, gettext_noop
+            ("# Failed attempts to switch addresses (failed to send CONNECT)"), 1, GNUNET_NO);
         /* Remove address and request and additional one */
         unset_alternative_address (n);
         set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED,
           GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
         break;
       default:
-        GNUNET_break (0);
         disconnect_neighbour (n);
         break;
     }
@@ -2069,16 +2078,15 @@ notification_cb(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
   return GNUNET_OK;
 }
 
-static
-int
+static int
 free_notification_cb(void *cls, const struct GNUNET_PeerIdentity *key,
     void *value)
 {
   /* struct NeighbourMapEntry *n = cls; */
   struct QuotaNotificationRequest *qnr = value;
 
-  GNUNET_CONTAINER_multipeermap_remove (registered_quota_notifications, key,
-      qnr);
+  GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (registered_quota_notifications, key,
+      qnr));
   GNUNET_free(qnr->plugin);
   GNUNET_free(qnr);
 
@@ -2328,7 +2336,7 @@ GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message,
   n->ack_state = ACK_SEND_CONNECT_ACK;
   n->connect_ack_timestamp = ts;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Received CONNECT for peer `%s' in state %s/%s\n",
               GNUNET_i2s (peer),
               GNUNET_TRANSPORT_ps2s (n->state),
@@ -2421,8 +2429,10 @@ switch_address_bl_check_cont (void *cls,
   struct GNUNET_TRANSPORT_PluginFunctions *papi;
   struct NeighbourMapEntry *n;
 
+  papi = GST_plugins_find (blc_ctx->address->transport_name);
+
   if ( (NULL == (n = lookup_neighbour (peer))) || (result == GNUNET_NO) ||
-       (NULL == (papi = GST_plugins_find (blc_ctx->address->transport_name))) )
+       (NULL == (papi)) )
   {
     if (NULL == n)
     {
@@ -2438,7 +2448,7 @@ switch_address_bl_check_cont (void *cls,
           blc_ctx->session,
           GNUNET_i2s (&blc_ctx->address->peer));
     }
-    if (NULL == (papi = GST_plugins_find (blc_ctx->address->transport_name)))
+    if (NULL == papi)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
           "Plugin `%s' for suggested address `%s' session %p for peer `%s' is not available\n",
@@ -2580,6 +2590,8 @@ switch_address_bl_check_cont (void *cls,
         blc_ctx->bandwidth_in, blc_ctx->bandwidth_out);
     set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_CONNECT_SENT,
         GNUNET_TIME_relative_to_absolute (SETUP_CONNECTION_TIMEOUT));
+    GNUNET_STATISTICS_update (GST_stats, gettext_noop
+        ("# Attempts to switch addresses"), 1, GNUNET_NO);
     send_session_connect (&n->alternative_address);
     break;
   case GNUNET_TRANSPORT_PS_RECONNECT_ATS:
@@ -2606,7 +2618,8 @@ switch_address_bl_check_cont (void *cls,
     send_session_connect (&n->primary_address);
     break;
   case GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_CONNECT_SENT:
-    if (n->primary_address.session == blc_ctx->session)
+    if ( (0 == GNUNET_HELLO_address_cmp(n->primary_address.address,
+        blc_ctx->address) && n->primary_address.session == blc_ctx->session) )
     {
       /* ATS switches back to still-active session */
       free_address (&n->alternative_address);
@@ -2669,7 +2682,6 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
 {
   struct NeighbourMapEntry *n;
   struct GST_BlacklistCheck *blc;
-  struct GNUNET_TRANSPORT_PluginFunctions *papi;
   struct BlacklistCheckSwitchContext *blc_ctx;
   int c;
 
@@ -2686,7 +2698,7 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
   }
 
   /* Check if plugin is available */
-  if (NULL == (papi = GST_plugins_find (address->transport_name)))
+  if (NULL == (GST_plugins_find (address->transport_name)))
   {
     /* we don't have the plugin for this address */
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -3000,6 +3012,8 @@ master_task (void *cls,
       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                  "Connection to `%s' timed out, missing KEEPALIVE_RESPONSEs (after trying to CONNECT on alternative address)\n",
                  GNUNET_i2s (&n->id));
+      GNUNET_STATISTICS_update (GST_stats, gettext_noop
+          ("# Failed attempts to switch addresses (no response)"), 1, GNUNET_NO);
       disconnect_neighbour (n);
       return;
     }
@@ -3178,12 +3192,15 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
         GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
     GNUNET_break (GNUNET_NO == n->alternative_address.ats_active);
 
+    /* Notify about session... perhaps we obtained it */
     GST_ats_add_address (n->alternative_address.address,
-                         n->alternative_address.session,
-                         NULL, 0);
+        n->alternative_address.session, NULL, 0);
+    /* Set primary addresses */
     set_primary_address (n, n->alternative_address.address,
         n->alternative_address.session, n->alternative_address.bandwidth_in,
         n->alternative_address.bandwidth_out, GNUNET_YES);
+    GNUNET_STATISTICS_update (GST_stats, gettext_noop
+        ("# Successful attempts to switch addresses"), 1, GNUNET_NO);
 
     free_address (&n->alternative_address);
     send_session_ack_message (n);
@@ -3250,8 +3267,7 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
       if ( (GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_CONNECT_SENT == n->state) )
         set_state (n, GNUNET_TRANSPORT_PS_CONNECTED);
       else
-       GNUNET_break (0);
-      free_address (&n->alternative_address);
+        free_address (&n->alternative_address);
     }
     return GNUNET_NO; /* doesn't affect us further */
   }
@@ -3318,12 +3334,14 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
     /* primary went down while we were waiting for CONNECT_ACK on secondary;
        secondary as primary */
 
-    /* Destroy the address since it cannot be used */
-    GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL);
+    /* Destroy the inbound address since it cannot be used */
+    if (GNUNET_YES
+        == GNUNET_HELLO_address_check_option (n->primary_address.address,
+            GNUNET_HELLO_ADDRESS_INFO_INBOUND))
+      GNUNET_ATS_address_destroyed (GST_ats, n->primary_address.address, NULL);
     free_address (&n->primary_address);
     n->primary_address = n->alternative_address;
     memset (&n->alternative_address, 0, sizeof (struct NeighbourAddress));
-    /* FIXME: Why GNUNET_TRANSPORT_PS_RECONNECT_ATS ?*/
     set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS,
         GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT));
     break;
@@ -3368,7 +3386,7 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message,
 {
   struct NeighbourMapEntry *n;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Received SESSION_ACK message from peer `%s'\n",
               GNUNET_i2s (peer));
   if (ntohs (message->size) != sizeof (struct GNUNET_MessageHeader))
@@ -3385,6 +3403,14 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message,
     GNUNET_break_op (0);
     return GNUNET_SYSERR;
   }
+
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Received %s for peer `%s' in state %s/%s\n",
+              "SESSION_ACK",
+              GNUNET_i2s (peer),
+              GNUNET_TRANSPORT_ps2s (n->state),
+              print_ack_state (n->ack_state));
+
   /* Check if we are in a plausible state for having sent
      a CONNECT_ACK.  If not, return, otherwise break.
 
@@ -3396,10 +3422,10 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message,
      now wait for the ACK to finally be connected
      - If we sent a CONNECT_ACK to this peer before */
 
-  if (   (GNUNET_TRANSPORT_PS_CONNECT_RECV_ACK != n->state) ||
+  if (   (GNUNET_TRANSPORT_PS_CONNECT_RECV_ACK != n->state) &&
          (ACK_SEND_SESSION_ACK != n->ack_state))
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Received unexpected SESSION_ACK message from peer `%s' in state %s/%s\n",
                 GNUNET_i2s (peer),
                 GNUNET_TRANSPORT_ps2s (n->state),
@@ -3412,16 +3438,29 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message,
   }
 
   /* We are connected */
-  set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED, GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
-  GNUNET_STATISTICS_set (GST_stats,
-                        gettext_noop ("# peers connected"),
-                        ++neighbours_connected,
-                        GNUNET_NO);
-
-  /* Notify about connection */
-  connect_notify_cb (callback_cls, &n->id,
+  if (GNUNET_NO == GST_neighbours_test_connected(&n->id))
+  {
+    /* Notify about connection */
+    connect_notify_cb (callback_cls, &n->id,
                      n->primary_address.bandwidth_in,
-                     n->primary_address.bandwidth_out);
+                     n->primary_address.bandwidth_out);\
+
+     GNUNET_STATISTICS_set (GST_stats,
+                            gettext_noop ("# peers connected"),
+                            ++neighbours_connected,
+                            GNUNET_NO);
+  }
+
+  if (GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_CONNECT_SENT == n->state)
+  {
+    /* We tried to switch addresses while being connect. We explicitly wait
+     * for a CONNECT_ACK before going to GNUNET_TRANSPORT_PS_CONNECTED,
+     * so we do not want to set the address as in use! */
+    return GNUNET_OK;
+  }
+
+  set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED,
+    GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
 
   /* Add session to ATS since no session was given (NULL) and we may have
    * obtained a new session */
@@ -3493,7 +3532,7 @@ void delayed_disconnect (void *cls,
   struct NeighbourMapEntry *n = cls;
 
   n->delayed_disconnect_task = GNUNET_SCHEDULER_NO_TASK;
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Disconnecting by request from peer %s\n",
               GNUNET_i2s (&n->id));
   free_neighbour (n, GNUNET_NO);