call GNUNET_SERVER_receive_done() also on internal error paths
[oweals/gnunet.git] / src / transport / gnunet-service-transport_neighbours.c
index 404dadb80d8eb836dcb17136b91f78632f651df1..17e30c0b790c087e1fa50710426f32b7d4b7175d 100644 (file)
@@ -826,6 +826,9 @@ set_alternative_address (struct NeighbourMapEntry *n,
   n->alternative_address.session = session;
   n->alternative_address.ats_active = GNUNET_NO;
   n->alternative_address.keep_alive_nonce = 0;
+  GNUNET_assert (GNUNET_YES ==
+                 GST_ats_is_known (n->alternative_address.address,
+                                   n->alternative_address.session));
 }
 
 
@@ -890,6 +893,9 @@ set_primary_address (struct NeighbourMapEntry *n,
   n->primary_address.bandwidth_out = bandwidth_out;
   n->primary_address.session = session;
   n->primary_address.keep_alive_nonce = 0;
+  GNUNET_assert (GNUNET_YES ==
+                 GST_ats_is_known (n->primary_address.address,
+                                   n->primary_address.session));
   /* subsystems about address use */
   GST_validation_set_address_use (n->primary_address.address,
                                   GNUNET_YES);
@@ -1508,7 +1514,7 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
   if (NULL == (n = lookup_neighbour (neighbour)))
   {
     GNUNET_STATISTICS_update (GST_stats,
-                              gettext_noop ("# KEEPALIVE_RESPONSE messages discarded (not connected)"),
+                              gettext_noop ("# KEEPALIVE_RESPONSEs discarded (not connected)"),
                               1,
                               GNUNET_NO);
     return;
@@ -1517,7 +1523,7 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
        (GNUNET_YES != n->expect_latency_response) )
   {
     GNUNET_STATISTICS_update (GST_stats,
-                              gettext_noop ("# KEEPALIVE_RESPONSE messages discarded (not expected)"),
+                              gettext_noop ("# KEEPALIVE_RESPONSEs discarded (not expected)"),
                               1,
                               GNUNET_NO);
     return;
@@ -1525,7 +1531,7 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
   if (NULL == n->primary_address.address)
   {
     GNUNET_STATISTICS_update (GST_stats,
-                              gettext_noop ("# KEEPALIVE_RESPONSE messages discarded (address changed)"),
+                              gettext_noop ("# KEEPALIVE_RESPONSEs discarded (address changed)"),
                               1,
                               GNUNET_NO);
     return;
@@ -1534,18 +1540,18 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
   {
     if (0 == n->primary_address.keep_alive_nonce)
       GNUNET_STATISTICS_update (GST_stats,
-                                gettext_noop ("# KEEPALIVE_RESPONSE messages discarded (no nonce)"),
+                                gettext_noop ("# KEEPALIVE_RESPONSEs discarded (no nonce)"),
                                 1,
                                 GNUNET_NO);
     else
       GNUNET_STATISTICS_update (GST_stats,
-                                gettext_noop ("# KEEPALIVE_RESPONSE messages discarded (wrong nonce)"),
+                                gettext_noop ("# KEEPALIVE_RESPONSEs discarded (bad nonce)"),
                                 1,
                                 GNUNET_NO);
     return;
   }
   GNUNET_STATISTICS_update (GST_stats,
-                            gettext_noop ("# KEEPALIVE_RESPONSE messages received in good order"),
+                            gettext_noop ("# KEEPALIVE_RESPONSEs received (OK)"),
                             1,
                             GNUNET_NO);
 
@@ -2141,16 +2147,6 @@ struct BlacklistCheckSwitchContext
    */
   struct GST_BlacklistCheck *blc;
 
-  /**
-   * Address we are asking the blacklist subsystem about.
-   */
-  struct GNUNET_HELLO_Address *address;
-
-  /**
-   * Session we should use in conjunction with @e address, can be NULL.
-   */
-  struct Session *session;
-
   /**
    * Inbound bandwidth that was assigned to @e address.
    */
@@ -2169,11 +2165,17 @@ struct BlacklistCheckSwitchContext
  *
  * @param cls blc_ctx bl context
  * @param peer the peer
- * @param result the result
+ * @param address address associated with the request
+ * @param session session associated with the request
+ * @param result #GNUNET_OK if the connection is allowed,
+ *               #GNUNET_NO if not,
+ *               #GNUNET_SYSERR if operation was aborted
  */
 static void
 try_connect_bl_check_cont (void *cls,
                            const struct GNUNET_PeerIdentity *peer,
+                          const struct GNUNET_HELLO_Address *address,
+                          struct Session *session,
                            int result)
 {
   struct BlacklistCheckSwitchContext *blc_ctx = cls;
@@ -2281,7 +2283,9 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target)
       (blc = GST_blacklist_test_allowed (target,
                                          NULL,
                                          &try_connect_bl_check_cont,
-                                         blc_ctx)))
+                                         blc_ctx,
+                                        NULL,
+                                        NULL)))
   {
     blc_ctx->blc = blc;
   }
@@ -2457,6 +2461,9 @@ try_run_fast_ats_update (const struct GNUNET_HELLO_Address *address,
     /* switch to a different session, but keeping same address; could
        happen if there is a 2nd inbound connection */
     n->primary_address.session = session;
+    GNUNET_assert (GNUNET_YES ==
+                   GST_ats_is_known (n->primary_address.address,
+                                     n->primary_address.session));
   }
   n->primary_address.bandwidth_in = bandwidth_in;
   n->primary_address.bandwidth_out = bandwidth_out;
@@ -2475,54 +2482,66 @@ try_run_fast_ats_update (const struct GNUNET_HELLO_Address *address,
  * @param cls the `struct BlacklistCheckSwitchContext` with
  *        the information about the future address
  * @param peer the peer we may switch addresses on
- * @param result #GNUNET_NO if we are not allowed to use the new
- *        address
+ * @param address address associated with the request
+ * @param session session associated with the request
+ * @param result #GNUNET_OK if the connection is allowed,
+ *               #GNUNET_NO if not,
+ *               #GNUNET_SYSERR if operation was aborted
  */
 static void
 switch_address_bl_check_cont (void *cls,
                               const struct GNUNET_PeerIdentity *peer,
+                             const struct GNUNET_HELLO_Address *address,
+                             struct Session *session,
                               int result)
 {
   struct BlacklistCheckSwitchContext *blc_ctx = cls;
   struct GNUNET_TRANSPORT_PluginFunctions *papi;
   struct NeighbourMapEntry *n;
 
-  if (result == GNUNET_NO)
+  if (GNUNET_SYSERR == result)
+    goto cleanup;
+
+  papi = GST_plugins_find (address->transport_name);
+  GNUNET_assert (NULL != papi);
+
+  if (GNUNET_NO == result)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Blacklist denied to switch to suggested address `%s' session %p for peer `%s'\n",
-                GST_plugins_a2s (blc_ctx->address),
-                blc_ctx->session,
-                GNUNET_i2s (&blc_ctx->address->peer));
+                GST_plugins_a2s (address),
+               session,
+                GNUNET_i2s (peer));
     GNUNET_STATISTICS_update (GST_stats,
                               "# ATS suggestions ignored (blacklist denied)",
                               1,
                               GNUNET_NO);
-    /* FIXME: tell plugin to force killing session here and now
-       (note: _proper_ plugin API for this does not yet exist) */
-    GST_ats_block_address (blc_ctx->address,
-                           blc_ctx->session);
+    papi->disconnect_session (papi->cls,
+                             session);
+    if (GNUNET_YES !=
+       GNUNET_HELLO_address_check_option (address,
+                                          GNUNET_HELLO_ADDRESS_INFO_INBOUND))
+      GST_ats_block_address (address,
+                            NULL);
     goto cleanup;
   }
 
-  papi = GST_plugins_find (blc_ctx->address->transport_name);
-  GNUNET_assert (NULL != papi);
 
-  if (NULL == blc_ctx->session)
+  if (NULL == session)
   {
     /* need to create a session, ATS only gave us an address */
-    blc_ctx->session = papi->get_session (papi->cls,
-                                          blc_ctx->address);
+    session = papi->get_session (papi->cls,
+                                address);
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Obtained new session for peer `%s' and  address '%s': %p\n",
-                GNUNET_i2s (&blc_ctx->address->peer),
-                GST_plugins_a2s (blc_ctx->address),
-                blc_ctx->session);
-    if (NULL != blc_ctx->session)
-      GST_ats_new_session (blc_ctx->address,
-                           blc_ctx->session);
+                GNUNET_i2s (&address->peer),
+                GST_plugins_a2s (address),
+                session);
+    if (NULL != session)
+      GST_ats_new_session (address,
+                           session);
   }
-  if (NULL == blc_ctx->session)
+  if (NULL == session)
   {
     /* session creation failed, bad!, fail! */
     GNUNET_STATISTICS_update (GST_stats,
@@ -2532,10 +2551,10 @@ switch_address_bl_check_cont (void *cls,
     /* No session could be obtained, remove blacklist check and clean up */
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Failed to obtain new session for peer `%s' and address '%s'\n",
-                GNUNET_i2s (&blc_ctx->address->peer),
-                GST_plugins_a2s (blc_ctx->address));
-    GST_ats_block_address (blc_ctx->address,
-                           blc_ctx->session);
+                GNUNET_i2s (&address->peer),
+                GST_plugins_a2s (address));
+    GST_ats_block_address (address,
+                           session);
     goto cleanup;
   }
 
@@ -2543,8 +2562,8 @@ switch_address_bl_check_cont (void *cls,
      it is theoretically possible that the situation changed in
      the meantime, hence we check again here */
   if (GNUNET_OK ==
-      try_run_fast_ats_update (blc_ctx->address,
-                               blc_ctx->session,
+      try_run_fast_ats_update (address,
+                               session,
                                blc_ctx->bandwidth_in,
                                blc_ctx->bandwidth_out))
     goto cleanup; /* was just a minor update, we're done */
@@ -2558,23 +2577,23 @@ switch_address_bl_check_cont (void *cls,
 
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Peer `%s' switches to address `%s'\n",
-              GNUNET_i2s (&blc_ctx->address->peer),
-              GST_plugins_a2s (blc_ctx->address));
+              GNUNET_i2s (&address->peer),
+              GST_plugins_a2s (address));
 
   switch (n->state)
   {
   case GNUNET_TRANSPORT_PS_NOT_CONNECTED:
     GNUNET_break (0);
-    GST_ats_block_address (blc_ctx->address,
-                           blc_ctx->session);
+    GST_ats_block_address (address,
+                           session);
     free_neighbour (n);
     return;
   case GNUNET_TRANSPORT_PS_INIT_ATS:
     /* We requested an address and ATS suggests one:
      * set primary address and send SYN message*/
     set_primary_address (n,
-                         blc_ctx->address,
-                         blc_ctx->session,
+                         address,
+                         session,
                          blc_ctx->bandwidth_in,
                          blc_ctx->bandwidth_out);
     if (ACK_SEND_SYN_ACK == n->ack_state)
@@ -2594,8 +2613,8 @@ switch_address_bl_check_cont (void *cls,
      * Switch and send new SYN */
     /* ATS suggests a different address, switch again */
     set_primary_address (n,
-                         blc_ctx->address,
-                         blc_ctx->session,
+                         address,
+                         session,
                          blc_ctx->bandwidth_in,
                          blc_ctx->bandwidth_out);
     if (ACK_SEND_SYN_ACK == n->ack_state)
@@ -2614,8 +2633,8 @@ switch_address_bl_check_cont (void *cls,
     /* We requested an address and ATS suggests one:
      * set primary address and send SYN_ACK message*/
     set_primary_address (n,
-                         blc_ctx->address,
-                         blc_ctx->session,
+                         address,
+                         session,
                          blc_ctx->bandwidth_in,
                          blc_ctx->bandwidth_out);
     /* Send an ACK message as a response to the SYN msg */
@@ -2638,8 +2657,8 @@ switch_address_bl_check_cont (void *cls,
                             n->connect_ack_timestamp);
     }
     set_primary_address (n,
-                         blc_ctx->address,
-                         blc_ctx->session,
+                        address,
+                         session,
                          blc_ctx->bandwidth_in,
                          blc_ctx->bandwidth_out);
     set_state_and_timeout (n,
@@ -2649,12 +2668,12 @@ switch_address_bl_check_cont (void *cls,
   case GNUNET_TRANSPORT_PS_CONNECTED:
     GNUNET_assert (NULL != n->primary_address.address);
     GNUNET_assert (NULL != n->primary_address.session);
-    GNUNET_break (n->primary_address.session != blc_ctx->session);
+    GNUNET_break (n->primary_address.session != session);
     /* ATS asks us to switch a life connection; see if we can get
        a SYN_ACK on it before we actually do this! */
     set_alternative_address (n,
-                             blc_ctx->address,
-                             blc_ctx->session,
+                             address,
+                             session,
                              blc_ctx->bandwidth_in,
                              blc_ctx->bandwidth_out);
     set_state_and_timeout (n,
@@ -2668,8 +2687,8 @@ switch_address_bl_check_cont (void *cls,
     break;
   case GNUNET_TRANSPORT_PS_RECONNECT_ATS:
     set_primary_address (n,
-                         blc_ctx->address,
-                         blc_ctx->session,
+                         address,
+                         session,
                          blc_ctx->bandwidth_in,
                          blc_ctx->bandwidth_out);
     if (ACK_SEND_SYN_ACK == n->ack_state)
@@ -2688,8 +2707,8 @@ switch_address_bl_check_cont (void *cls,
     /* ATS asks us to switch while we were trying to reconnect; switch to new
        address and send SYN again */
     set_primary_address (n,
-                         blc_ctx->address,
-                         blc_ctx->session,
+                         address,
+                         session,
                          blc_ctx->bandwidth_in,
                          blc_ctx->bandwidth_out);
     set_state_and_timeout (n,
@@ -2699,8 +2718,8 @@ switch_address_bl_check_cont (void *cls,
     break;
   case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT:
     if ( (0 == GNUNET_HELLO_address_cmp (n->primary_address.address,
-                                         blc_ctx->address)) &&
-         (n->primary_address.session == blc_ctx->session) )
+                                         address)) &&
+         (n->primary_address.session == session) )
     {
       /* ATS switches back to still-active session */
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2713,8 +2732,8 @@ switch_address_bl_check_cont (void *cls,
     }
     /* ATS asks us to switch a life connection, send */
     set_alternative_address (n,
-                             blc_ctx->address,
-                             blc_ctx->session,
+                            address,
+                             session,
                              blc_ctx->bandwidth_in,
                              blc_ctx->bandwidth_out);
     set_state_and_timeout (n,
@@ -2743,7 +2762,6 @@ switch_address_bl_check_cont (void *cls,
   GNUNET_CONTAINER_DLL_remove (pending_bc_head,
                                pending_bc_tail,
                                blc_ctx);
-  GNUNET_HELLO_address_free (blc_ctx->address);
   GNUNET_free (blc_ctx);
 }
 
@@ -2811,8 +2829,6 @@ GST_neighbours_switch_to_address (const struct GNUNET_HELLO_Address *address,
 
   /* Perform blacklist check */
   blc_ctx = GNUNET_new (struct BlacklistCheckSwitchContext);
-  blc_ctx->address = GNUNET_HELLO_address_copy (address);
-  blc_ctx->session = session;
   blc_ctx->bandwidth_in = bandwidth_in;
   blc_ctx->bandwidth_out = bandwidth_out;
   GNUNET_CONTAINER_DLL_insert (pending_bc_head,
@@ -2821,7 +2837,9 @@ GST_neighbours_switch_to_address (const struct GNUNET_HELLO_Address *address,
   if (NULL != (blc = GST_blacklist_test_allowed (&address->peer,
                                                  address->transport_name,
                                                  &switch_address_bl_check_cont,
-                                                 blc_ctx)))
+                                                 blc_ctx,
+                                                address,
+                                                session)))
   {
     blc_ctx->blc = blc;
   }
@@ -3389,6 +3407,9 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
     /* Destroy the inbound address since it cannot be used */
     free_address (&n->primary_address);
     n->primary_address = n->alternative_address;
+    GNUNET_assert (GNUNET_YES ==
+                   GST_ats_is_known (n->primary_address.address,
+                                     n->primary_address.session));
     memset (&n->alternative_address,
             0,
             sizeof (struct NeighbourAddress));
@@ -3474,7 +3495,8 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message,
                 print_ack_state (n->ack_state));
 
     GNUNET_STATISTICS_update (GST_stats,
-                              gettext_noop ("# unexpected ACK messages"), 1,
+                              gettext_noop ("# unexpected ACK messages"),
+                              1,
                               GNUNET_NO);
     return GNUNET_OK;
   }
@@ -3489,7 +3511,7 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message,
                          GNUNET_TRANSPORT_PS_CONNECTED,
                          GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
 
-  /* Reset backoff for primary address  */
+  /* Reset backoff for primary address */
   GST_ats_block_reset (n->primary_address.address,
                        n->primary_address.session);
   return GNUNET_OK;
@@ -3835,8 +3857,6 @@ GST_neighbours_stop ()
       GST_blacklist_test_cancel (cur->blc);
       cur->blc = NULL;
     }
-    if (NULL != cur->address)
-      GNUNET_HELLO_address_free (cur->address);
     GNUNET_free (cur);
   }
 }