Check that you are not present in trail twice
[oweals/gnunet.git] / src / transport / gnunet-service-transport_blacklist.c
index 628943a42d1d3b9e2d2a33a1c1b53410c089818b..38ef0907f623f6f5c52059604b6730be957ef92a 100644 (file)
@@ -104,6 +104,11 @@ struct Blacklisters
    */
   int waiting_for_reply;
 
+  /**
+   * GNUNET_YES if we have to call receive_done for this client
+   */
+  int call_receive_done;
+
 };
 
 
@@ -226,7 +231,6 @@ client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client)
       }
       if (bc->task == GNUNET_SCHEDULER_NO_TASK)
         bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc);
-      break;
     }
     GNUNET_CONTAINER_DLL_remove (bl_head, bl_tail, bl);
     GNUNET_SERVER_client_drop (bl->client);
@@ -244,7 +248,7 @@ client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client)
  * @param option name of the option
  * @param value value of the option
  */
-static void 
+static void
 blacklist_cfg_iter (void *cls, const char *section,
                    const char *option,
                    const char *value)
@@ -254,11 +258,11 @@ blacklist_cfg_iter (void *cls, const char *section,
   char *plugs;
   char *pos;
 
-  if (GNUNET_OK != GNUNET_CRYPTO_ecc_public_sign_key_from_string (option,
-                                                                 strlen (option), 
+  if (GNUNET_OK != GNUNET_CRYPTO_eddsa_public_key_from_string (option,
+                                                                 strlen (option),
                                                                  &peer.public_key))
     return;
-  
+
   if ((NULL == value) || (0 == strcmp(value, "")))
   {
     /* Blacklist whole peer */
@@ -295,9 +299,9 @@ read_blacklist_configuration (const struct GNUNET_CONFIGURATION_Handle *cfg,
   char cfg_sect[512];
   unsigned int res = 0;
 
-  GNUNET_snprintf (cfg_sect, 
+  GNUNET_snprintf (cfg_sect,
                   sizeof (cfg_sect),
-                  "transport-blacklist-%s", 
+                  "transport-blacklist-%s",
                   GNUNET_i2s_full (my_id));
   GNUNET_CONFIGURATION_iterate_section_values (cfg, cfg_sect, &blacklist_cfg_iter, &res);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -387,15 +391,20 @@ transmit_blacklist_message (void *cls, size_t size, void *buf)
     return 0;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Sending blacklist test for peer `%s' to client\n",
-              GNUNET_i2s (&bc->peer));
+              "Sending blacklist test for peer `%s' to client %p\n",
+              GNUNET_i2s (&bc->peer), bc->bl_pos->client);
   bl = bc->bl_pos;
   bm.header.size = htons (sizeof (struct BlacklistMessage));
   bm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_QUERY);
   bm.is_allowed = htonl (0);
   bm.peer = bc->peer;
   memcpy (buf, &bm, sizeof (bm));
-  GNUNET_SERVER_receive_done (bl->client, GNUNET_OK);
+  if (GNUNET_YES == bl->call_receive_done)
+  {
+    GNUNET_SERVER_receive_done (bl->client, GNUNET_OK);
+    bl->call_receive_done = GNUNET_NO;
+  }
+
   bl->waiting_for_reply = GNUNET_YES;
   return sizeof (bm);
 }
@@ -474,29 +483,32 @@ struct TestConnectionContext
   struct Blacklisters *bl;
 };
 
-
 /**
  * Test if an existing connection is still acceptable given a new
  * blacklisting client.
  *
  * @param cls the 'struct TestConnectionContest'
- * @param neighbour neighbour's identity
+ * @param peer neighbour's identity
  * @param address the address
- * @param bandwidth_in inbound quota in NBO
- * @param bandwidth_out outbound quota in NBO
+ * @param state current state this peer is in
+ * @param state_timeout timeout for the current state of the peer
+ * @param bandwidth_in bandwidth assigned inbound
+ * @param bandwidth_out bandwidth assigned outbound
  */
 static void
-test_connection_ok (void *cls, const struct GNUNET_PeerIdentity *neighbour,
-                    const struct GNUNET_HELLO_Address *address,
-                    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
-                    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
+test_connection_ok (void *cls, const struct GNUNET_PeerIdentity *peer,
+    const struct GNUNET_HELLO_Address *address,
+    enum GNUNET_TRANSPORT_PeerState state,
+    struct GNUNET_TIME_Absolute state_timeout,
+    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
 {
   struct TestConnectionContext *tcc = cls;
   struct GST_BlacklistCheck *bc;
 
-  bc = GNUNET_malloc (sizeof (struct GST_BlacklistCheck));
-  GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, bc);
-  bc->peer = *neighbour;
+  bc = GNUNET_new (struct GST_BlacklistCheck);
+  GNUNET_CONTAINER_DLL_insert(bc_head, bc_tail, bc);
+  bc->peer = *peer;
   bc->cont = &confirm_or_drop_neighbour;
   bc->cont_cls = NULL;
   bc->bl_pos = tcc->bl;
@@ -537,12 +549,16 @@ GST_blacklist_handle_init (void *cls, struct GNUNET_SERVER_Client *client,
     }
     bl = bl->next;
   }
+
   GNUNET_SERVER_client_mark_monitor (client);
-  bl = GNUNET_malloc (sizeof (struct Blacklisters));
+  bl = GNUNET_new (struct Blacklisters);
   bl->client = client;
+  bl->call_receive_done = GNUNET_YES;
   GNUNET_SERVER_client_keep (client);
   GNUNET_CONTAINER_DLL_insert_after (bl_head, bl_tail, bl_tail, bl);
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New blacklist client %p\n", client);
+
   /* confirm that all existing connections are OK! */
   tcc.bl = bl;
   tcc.first = GNUNET_YES;
@@ -572,13 +588,17 @@ GST_blacklist_handle_reply (void *cls, struct GNUNET_SERVER_Client *client,
   if (bl == NULL)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Blacklist client disconnected\n");
-    /* FIXME: other error handling here!? */
     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
     return;
   }
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Blacklist client %p sent reply for `%s'\n",
+      client, GNUNET_i2s(&msg->peer));
+
   bc = bl->bc;
   bl->bc = NULL;
   bl->waiting_for_reply = GNUNET_NO;
+  bl->call_receive_done = GNUNET_YES; /* Remember to call receive_done */
   if (NULL != bc)
   {
     /* only run this if the blacklist check has not been
@@ -589,7 +609,10 @@ GST_blacklist_handle_reply (void *cls, struct GNUNET_SERVER_Client *client,
                   "Blacklist check failed, peer not allowed\n");
       bc->cont (bc->cont_cls, &bc->peer, GNUNET_NO);
       GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bc);
+      GNUNET_SERVER_receive_done (bl->client, GNUNET_OK);
+      bl->call_receive_done = GNUNET_NO;
       GNUNET_free (bc);
+      return;
     }
     else
     {
@@ -599,7 +622,7 @@ GST_blacklist_handle_reply (void *cls, struct GNUNET_SERVER_Client *client,
       bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc);
     }
   }
-  /* check if any other bc's are waiting for this blacklister */
+  /* check if any other blacklist checks are waiting for this blacklister */
   for (bc = bc_head; bc != NULL; bc = bc->next)
     if ((bc->bl_pos == bl) && (GNUNET_SCHEDULER_NO_TASK == bc->task))
     {
@@ -636,7 +659,7 @@ GST_blacklist_add_peer (const struct GNUNET_PeerIdentity *peer,
     blacklist =
       GNUNET_CONTAINER_multipeermap_create (TRANSPORT_BLACKLIST_HT_SIZE,
                                            GNUNET_NO);
-  
+
   GNUNET_CONTAINER_multipeermap_put (blacklist, peer,
                                      transport,
                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
@@ -653,7 +676,7 @@ GST_blacklist_add_peer (const struct GNUNET_PeerIdentity *peer,
  * @return #GNUNET_OK if the entry does not match, #GNUNET_NO if it matches
  */
 static int
-test_blacklisted (void *cls, 
+test_blacklisted (void *cls,
                  const struct GNUNET_PeerIdentity *key,
                  void *value)
 {
@@ -739,7 +762,7 @@ GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer,
   }
 
   /* need to query blacklist clients */
-  bc = GNUNET_malloc (sizeof (struct GST_BlacklistCheck));
+  bc = GNUNET_new (struct GST_BlacklistCheck);
   GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, bc);
   bc->peer = *peer;
   bc->cont = cont;