new operation queue for limiting overlay connects
[oweals/gnunet.git] / src / transport / gnunet-service-transport_blacklist.c
index 7720e467fac2401f7a448418316dc3a6a4e26668..e426b8fd20f003a0e0048f34c1d5b5469494dc66 100644 (file)
@@ -113,7 +113,7 @@ struct GST_BlacklistCheck
    * Current transmission request handle for this client, or NULL if no
    * request is pending.
    */
-  struct GNUNET_CONNECTION_TransmitHandle *th;
+  struct GNUNET_SERVER_TransmitHandle *th;
 
   /**
    * Our current position in the blacklisters list.
@@ -191,7 +191,7 @@ client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client)
       bc->bl_pos = bl->next;
       if (bc->th != NULL)
       {
-        GNUNET_CONNECTION_notify_transmit_ready_cancel (bc->th);
+        GNUNET_SERVER_notify_transmit_ready_cancel (bc->th);
         bc->th = NULL;
       }
       if (bc->task == GNUNET_SCHEDULER_NO_TASK)
@@ -221,47 +221,42 @@ read_blacklist_file ()
   size_t colon_pos;
   int tsize;
   struct GNUNET_PeerIdentity pid;
-  struct stat frstat;
+  uint64_t fsize;
   struct GNUNET_CRYPTO_HashAsciiEncoded enc;
   unsigned int entries_found;
   char *transport_name;
 
   if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (GST_cfg,
-                                               "TRANSPORT",
+      GNUNET_CONFIGURATION_get_value_filename (GST_cfg, "TRANSPORT",
                                                "BLACKLIST_FILE", &fn))
   {
-#if DEBUG_TRANSPORT
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Option `%s' in section `%s' not specified!\n",
-                "BLACKLIST_FILE", "TRANSPORT");
-#endif
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_DEBUG,
+                              "transport", "BLACKLIST_FILE");
     return;
   }
   if (GNUNET_OK != GNUNET_DISK_file_test (fn))
     GNUNET_DISK_fn_write (fn, NULL, 0,
                           GNUNET_DISK_PERM_USER_READ |
                           GNUNET_DISK_PERM_USER_WRITE);
-  if (0 != STAT (fn, &frstat))
+  if (GNUNET_OK != GNUNET_DISK_file_size (fn,
+      &fsize, GNUNET_NO, GNUNET_YES))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 _("Could not read blacklist file `%s'\n"), fn);
     GNUNET_free (fn);
     return;
   }
-  if (frstat.st_size == 0)
+  if (fsize == 0)
   {
-#if DEBUG_TRANSPORT
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                _("Blacklist file `%s' is empty.\n"), fn);
-#endif
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Blacklist file `%s' is empty.\n"),
+                fn);
     GNUNET_free (fn);
     return;
   }
   /* FIXME: use mmap */
-  data = GNUNET_malloc_large (frstat.st_size);
+  data = GNUNET_malloc_large (fsize);
   GNUNET_assert (data != NULL);
-  if (frstat.st_size != GNUNET_DISK_fn_read (fn, data, frstat.st_size))
+  if (fsize != GNUNET_DISK_fn_read (fn, data, fsize))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 _("Failed to read blacklist from `%s'\n"), fn);
@@ -271,18 +266,17 @@ read_blacklist_file ()
   }
   entries_found = 0;
   pos = 0;
-  while ((pos < frstat.st_size) && isspace ((unsigned char) data[pos]))
+  while ((pos < fsize) && isspace ((unsigned char) data[pos]))
     pos++;
-  while ((frstat.st_size >= sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) &&
+  while ((fsize >= sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) &&
          (pos <=
-          frstat.st_size - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)))
+          fsize - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)))
   {
     colon_pos = pos;
-    while ((colon_pos < frstat.st_size) &&
-           (data[colon_pos] != ':') &&
+    while ((colon_pos < fsize) && (data[colon_pos] != ':') &&
            (!isspace ((unsigned char) data[colon_pos])))
       colon_pos++;
-    if (colon_pos >= frstat.st_size)
+    if (colon_pos >= fsize)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                   _
@@ -300,12 +294,12 @@ read_blacklist_file ()
                   ("Syntax error in blacklist file at offset %llu, skipping bytes.\n"),
                   (unsigned long long) colon_pos);
       pos = colon_pos;
-      while ((pos < frstat.st_size) && isspace ((unsigned char) data[pos]))
+      while ((pos < fsize) && isspace ((unsigned char) data[pos]))
         pos++;
       continue;
     }
     tsize = colon_pos - pos;
-    if ((pos >= frstat.st_size) || (pos + tsize >= frstat.st_size) ||
+    if ((pos >= fsize) || (pos + tsize >= fsize) ||
         (tsize == 0))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -323,11 +317,9 @@ read_blacklist_file ()
     transport_name = GNUNET_malloc (tsize + 1);
     memcpy (transport_name, &data[pos], tsize);
     pos = colon_pos + 1;
-#if DEBUG_TRANSPORT
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Read transport name `%s' in blacklist file.\n",
                 transport_name);
-#endif
     memcpy (&enc, &data[pos], sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded));
     if (!isspace
         ((unsigned char)
@@ -338,7 +330,7 @@ read_blacklist_file ()
                   ("Syntax error in blacklist file at offset %llu, skipping bytes.\n"),
                   (unsigned long long) pos);
       pos++;
-      while ((pos < frstat.st_size) && (!isspace ((unsigned char) data[pos])))
+      while ((pos < fsize) && (!isspace ((unsigned char) data[pos])))
         pos++;
       GNUNET_free_non_null (transport_name);
       continue;
@@ -354,8 +346,8 @@ read_blacklist_file ()
     }
     else
     {
-      if (0 != memcmp (&pid,
-                       &GST_my_identity, sizeof (struct GNUNET_PeerIdentity)))
+      if (0 !=
+          memcmp (&pid, &GST_my_identity, sizeof (struct GNUNET_PeerIdentity)))
       {
         entries_found++;
         GST_blacklist_add_peer (&pid, transport_name);
@@ -369,11 +361,10 @@ read_blacklist_file ()
     }
     pos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded);
     GNUNET_free_non_null (transport_name);
-    while ((pos < frstat.st_size) && isspace ((unsigned char) data[pos]))
+    while ((pos < fsize) && isspace ((unsigned char) data[pos]))
       pos++;
   }
-  GNUNET_STATISTICS_update (GST_stats,
-                            "# Transport entries blacklisted",
+  GNUNET_STATISTICS_update (GST_stats, "# Transport entries blacklisted",
                             entries_found, GNUNET_NO);
   GNUNET_free (data);
   GNUNET_free (fn);
@@ -389,8 +380,8 @@ void
 GST_blacklist_start (struct GNUNET_SERVER_Handle *server)
 {
   read_blacklist_file ();
-  GNUNET_SERVER_disconnect_notify (server,
-                                   &client_disconnect_notification, NULL);
+  GNUNET_SERVER_disconnect_notify (server, &client_disconnect_notification,
+                                   NULL);
 }
 
 
@@ -403,7 +394,7 @@ GST_blacklist_start (struct GNUNET_SERVER_Handle *server)
  * @return GNUNET_OK (continue to iterate)
  */
 static int
-free_blacklist_entry (void *cls, const GNUNET_HashCode * key, void *value)
+free_blacklist_entry (void *cls, const struct GNUNET_HashCode * key, void *value)
 {
   char *be = value;
 
@@ -420,8 +411,8 @@ GST_blacklist_stop ()
 {
   if (NULL != blacklist)
   {
-    GNUNET_CONTAINER_multihashmap_iterate (blacklist,
-                                           &free_blacklist_entry, NULL);
+    GNUNET_CONTAINER_multihashmap_iterate (blacklist, &free_blacklist_entry,
+                                           NULL);
     GNUNET_CONTAINER_multihashmap_destroy (blacklist);
     blacklist = NULL;
   }
@@ -453,11 +444,9 @@ transmit_blacklist_message (void *cls, size_t size, void *buf)
                 GNUNET_i2s (&bc->peer));
     return 0;
   }
-#if DEBUG_TRANSPORT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Sending blacklist test for peer `%s' to client\n",
               GNUNET_i2s (&bc->peer));
-#endif
   bl = bc->bl_pos;
   bm.header.size = htons (sizeof (struct BlacklistMessage));
   bm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_QUERY);
@@ -486,24 +475,22 @@ do_blacklist_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   bl = bc->bl_pos;
   if (bl == NULL)
   {
-#if DEBUG_TRANSPORT
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "No other blacklist clients active, will allow neighbour `%s'\n",
                 GNUNET_i2s (&bc->peer));
-#endif
     bc->cont (bc->cont_cls, &bc->peer, GNUNET_OK);
+    GNUNET_CONTAINER_DLL_remove(bc_head, bc_tail, bc);
     GNUNET_free (bc);
     return;
   }
   if ((bl->bc != NULL) || (bl->waiting_for_reply != GNUNET_NO))
     return;                     /* someone else busy with this client */
   bl->bc = bc;
-  bc->th = GNUNET_SERVER_notify_transmit_ready (bl->client,
-                                                sizeof (struct
-                                                        BlacklistMessage),
-                                                GNUNET_TIME_UNIT_FOREVER_REL,
-                                                &transmit_blacklist_message,
-                                                bc);
+  bc->th =
+      GNUNET_SERVER_notify_transmit_ready (bl->client,
+                                           sizeof (struct BlacklistMessage),
+                                           GNUNET_TIME_UNIT_FOREVER_REL,
+                                           &transmit_blacklist_message, bc);
 }
 
 
@@ -517,14 +504,14 @@ do_blacklist_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  *                GNUNET_NO if we must shutdown the connection
  */
 static void
-confirm_or_drop_neighbour (void *cls,
-                           const struct GNUNET_PeerIdentity *peer, int allowed)
+confirm_or_drop_neighbour (void *cls, const struct GNUNET_PeerIdentity *peer,
+                           int allowed)
 {
   if (GNUNET_OK == allowed)
     return;                     /* we're done */
   GNUNET_STATISTICS_update (GST_stats,
-                            gettext_noop ("# disconnects due to blacklist"),
-                            1, GNUNET_NO);
+                            gettext_noop ("# disconnects due to blacklist"), 1,
+                            GNUNET_NO);
   GST_neighbours_force_disconnect (peer);
 }
 
@@ -551,15 +538,20 @@ struct TestConnectionContext
  * blacklisting client.
  *
  * @param cls the 'struct TestConnectionContest'
- * @param pid neighbour's identity
+ * @param neighbour neighbour's identity
  * @param ats performance data
  * @param ats_count number of entries in ats (excluding 0-termination)
+ * @param address the address
+ * @param bandwidth_in inbound quota in NBO
+ * @param bandwidth_out outbound quota in NBO
  */
 static void
-test_connection_ok (void *cls,
-                    const struct GNUNET_PeerIdentity *neighbour,
-                    const struct GNUNET_TRANSPORT_ATS_Information *ats,
-                    uint32_t ats_count)
+test_connection_ok (void *cls, const struct GNUNET_PeerIdentity *neighbour,
+                    const struct GNUNET_ATS_Information *ats,
+                    uint32_t ats_count,
+                    const struct GNUNET_HELLO_Address *address,
+                    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+                    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
 {
   struct TestConnectionContext *tcc = cls;
   struct GST_BlacklistCheck *bc;
@@ -580,7 +572,6 @@ test_connection_ok (void *cls,
 }
 
 
-
 /**
  * Initialize a blacklisting client.  We got a blacklist-init
  * message from this client, add him to the list of clients
@@ -591,8 +582,7 @@ test_connection_ok (void *cls,
  * @param message the blacklist-init message that was sent
  */
 void
-GST_blacklist_handle_init (void *cls,
-                           struct GNUNET_SERVER_Client *client,
+GST_blacklist_handle_init (void *cls, struct GNUNET_SERVER_Client *client,
                            const struct GNUNET_MessageHeader *message)
 {
   struct Blacklisters *bl;
@@ -609,6 +599,7 @@ GST_blacklist_handle_init (void *cls,
     }
     bl = bl->next;
   }
+  GNUNET_SERVER_client_mark_monitor (client);
   bl = GNUNET_malloc (sizeof (struct Blacklisters));
   bl->client = client;
   GNUNET_SERVER_client_keep (client);
@@ -629,8 +620,7 @@ GST_blacklist_handle_init (void *cls,
  * @param message the blacklist-init message that was sent
  */
 void
-GST_blacklist_handle_reply (void *cls,
-                            struct GNUNET_SERVER_Client *client,
+GST_blacklist_handle_reply (void *cls, struct GNUNET_SERVER_Client *client,
                             const struct GNUNET_MessageHeader *message)
 {
   const struct BlacklistMessage *msg =
@@ -643,9 +633,7 @@ GST_blacklist_handle_reply (void *cls,
     bl = bl->next;
   if (bl == NULL)
   {
-#if DEBUG_TRANSPORT
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Blacklist client disconnected\n");
-#endif
     /* FIXME: other error handling here!? */
     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
     return;
@@ -655,24 +643,20 @@ GST_blacklist_handle_reply (void *cls,
   bl->waiting_for_reply = GNUNET_NO;
   if (NULL != bc)
   {
-    /* only run this if the blacklist check has not been 
+    /* only run this if the blacklist check has not been
      * cancelled in the meantime... */
     if (ntohl (msg->is_allowed) == GNUNET_SYSERR)
     {
-#if DEBUG_TRANSPORT
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "Blacklist check failed, peer not allowed\n");
-#endif
       bc->cont (bc->cont_cls, &bc->peer, GNUNET_NO);
       GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bc);
       GNUNET_free (bc);
     }
     else
     {
-#if DEBUG_TRANSPORT
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "Blacklist check succeeded, continuing with checks\n");
-#endif
       bc->bl_pos = bc->bl_pos->next;
       bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc);
     }
@@ -690,7 +674,7 @@ GST_blacklist_handle_reply (void *cls,
 
 /**
  * Add the given peer to the blacklist (for the given transport).
- * 
+ *
  * @param peer peer to blacklist
  * @param transport_name transport to blacklist for this peer, NULL for all
  */
@@ -698,14 +682,13 @@ void
 GST_blacklist_add_peer (const struct GNUNET_PeerIdentity *peer,
                         const char *transport_name)
 {
-#if DEBUG_TRANSPORT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Adding peer `%s' with plugin `%s' to blacklist\n",
               GNUNET_i2s (peer), transport_name);
-#endif
   if (blacklist == NULL)
     blacklist =
-        GNUNET_CONTAINER_multihashmap_create (TRANSPORT_BLACKLIST_HT_SIZE);
+      GNUNET_CONTAINER_multihashmap_create (TRANSPORT_BLACKLIST_HT_SIZE,
+                                           GNUNET_NO);
   GNUNET_CONTAINER_multihashmap_put (blacklist, &peer->hashPubKey,
                                      GNUNET_strdup (transport_name),
                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
@@ -722,11 +705,16 @@ 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, const GNUNET_HashCode * key, void *value)
+test_blacklisted (void *cls, const struct GNUNET_HashCode * key, void *value)
 {
   const char *transport_name = cls;
   char *be = value;
 
+  /* blacklist check for specific no specific transport*/
+  if (transport_name == NULL)
+    return GNUNET_NO;
+
+  /* blacklist check for specific transport */
   if (0 == strcmp (transport_name, be))
     return GNUNET_NO;           /* abort iteration! */
   return GNUNET_OK;
@@ -750,10 +738,11 @@ GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer,
 {
   struct GST_BlacklistCheck *bc;
 
+  GNUNET_assert (peer != NULL);
+
   if ((blacklist != NULL) &&
       (GNUNET_SYSERR ==
-       GNUNET_CONTAINER_multihashmap_get_multiple (blacklist,
-                                                   &peer->hashPubKey,
+       GNUNET_CONTAINER_multihashmap_get_multiple (blacklist, &peer->hashPubKey,
                                                    &test_blacklisted,
                                                    (void *) transport_name)))
   {
@@ -788,7 +777,7 @@ GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer,
 
 /**
  * Cancel a blacklist check.
- * 
+ *
  * @param bc check to cancel
  */
 void
@@ -810,7 +799,7 @@ GST_blacklist_test_cancel (struct GST_BlacklistCheck *bc)
   }
   if (NULL != bc->th)
   {
-    GNUNET_CONNECTION_notify_transmit_ready_cancel (bc->th);
+    GNUNET_SERVER_notify_transmit_ready_cancel (bc->th);
     bc->th = NULL;
   }
   GNUNET_free (bc);