[transport] Fix EBADF in select()
[oweals/gnunet.git] / src / transport / transport_api_blacklist.c
index 5d2d616e81c9c3fad38ecc22e97ed3b1017ef074..7b1bf526e1931b646911cdc229dbd716b9235f89 100644 (file)
@@ -1,10 +1,10 @@
 /*
      This file is part of GNUnet.
 /*
      This file is part of GNUnet.
-     (C) 2010 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2010-2014, 2016 GNUnet e.V.
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 2, or (at your
+     by the Free Software Foundation; either version 3, or (at your
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
@@ -14,8 +14,8 @@
 
      You should have received a copy of the GNU General Public License
      along with GNUnet; see the file COPYING.  If not, write to the
 
      You should have received a copy of the GNU General Public License
      along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
 */
 
 /**
 */
 
 /**
  * @author Christian Grothoff
  */
 #include "platform.h"
  * @author Christian Grothoff
  */
 #include "platform.h"
-#include "gnunet_client_lib.h"
+#include "gnunet_util_lib.h"
 #include "gnunet_arm_service.h"
 #include "gnunet_hello_lib.h"
 #include "gnunet_protocols.h"
 #include "gnunet_arm_service.h"
 #include "gnunet_hello_lib.h"
 #include "gnunet_protocols.h"
-#include "gnunet_server_lib.h"
-#include "gnunet_time_lib.h"
 #include "gnunet_transport_service.h"
 #include "transport.h"
 
 #include "gnunet_transport_service.h"
 #include "transport.h"
 
@@ -42,23 +40,13 @@ struct GNUNET_TRANSPORT_Blacklist
   /**
    * Connection to transport service.
    */
   /**
    * Connection to transport service.
    */
-  struct GNUNET_CLIENT_Connection * client;
-
-  /**
-   * Scheduler to use.
-   */
-  struct GNUNET_SCHEDULER_Handle *sched;
+  struct GNUNET_MQ_Handle *mq;
 
   /**
    * Configuration to use.
    */
   const struct GNUNET_CONFIGURATION_Handle *cfg;
 
 
   /**
    * Configuration to use.
    */
   const struct GNUNET_CONFIGURATION_Handle *cfg;
 
-  /**
-   * Pending handle for the current request.
-   */ 
-  struct GNUNET_CLIENT_TransmitHandle *th;
-
   /**
    * Function to call for determining if a peer is allowed
    * to communicate with us.
   /**
    * Function to call for determining if a peer is allowed
    * to communicate with us.
@@ -66,14 +54,9 @@ struct GNUNET_TRANSPORT_Blacklist
   GNUNET_TRANSPORT_BlacklistCallback cb;
 
   /**
   GNUNET_TRANSPORT_BlacklistCallback cb;
 
   /**
-   * Closure for 'cb'.
+   * Closure for @e cb.
    */
    */
-  void *cb_cls;  
-
-  /**
-   * Peer currently under consideration.
-   */
-  struct GNUNET_PeerIdentity peer;
+  void *cb_cls;
 
 };
 
 
 };
 
@@ -87,81 +70,45 @@ static void
 reconnect (struct GNUNET_TRANSPORT_Blacklist *br);
 
 
 reconnect (struct GNUNET_TRANSPORT_Blacklist *br);
 
 
-/**
- * Send our reply to a blacklisting request.
- *
- * @param br our overall context
- */
-static void
-reply (struct GNUNET_TRANSPORT_Blacklist *br);
-
-
 /**
  * Handle blacklist queries.
  *
  * @param cls our overall handle
 /**
  * Handle blacklist queries.
  *
  * @param cls our overall handle
- * @param msg query
+ * @param bm query
  */
 static void
  */
 static void
-query_handler (void *cls,
-              const struct GNUNET_MessageHeader *msg)
+handle_query (void *cls,
+              const struct BlacklistMessage *bm)
 {
   struct GNUNET_TRANSPORT_Blacklist *br = cls;
 {
   struct GNUNET_TRANSPORT_Blacklist *br = cls;
-  const struct BlacklistMessage *bm;
-  
-  if ( (ntohs(msg->size) != sizeof (struct BlacklistMessage)) ||
-       (ntohs(msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_QUERY) )
-    {
-      reconnect (br);
-      return;
-    }
-  bm = (const struct BlacklistMessage *)msg;
+  struct GNUNET_MQ_Envelope *env;
+  struct BlacklistMessage *res;
+
   GNUNET_break (0 == ntohl (bm->is_allowed));
   GNUNET_break (0 == ntohl (bm->is_allowed));
-  br->peer = bm->peer;
-  reply (br);  
+  env = GNUNET_MQ_msg (res,
+                       GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY);
+  res->is_allowed = htonl (br->cb (br->cb_cls,
+                                   &bm->peer));
+  res->peer = bm->peer;
+  GNUNET_MQ_send (br->mq,
+                  env);
 }
 
 }
 
-
 /**
 /**
- * Receive blacklist queries from transport service.
+ * Generic error handler, called with the appropriate error code and
+ * the same closure specified at the creation of the message queue.
+ * Not every message queue implementation supports an error handler.
  *
  *
- * @param br overall handle
+ * @param cls closure with the `struct GNUNET_TRANSPORT_Blacklist *`
+ * @param error error code
  */
 static void
  */
 static void
-receive (struct GNUNET_TRANSPORT_Blacklist *br)
-{
-  GNUNET_CLIENT_receive (br->client,
-                        &query_handler,
-                        br,
-                        GNUNET_TIME_UNIT_FOREVER_REL);
-}
-
-
-/**
- * Transmit the blacklist initialization request to the service.
- *
- * @param cls closure (struct GNUNET_TRANSPORT_Blacklist*)
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
- */
-static size_t
-transmit_blacklist_init (void *cls,
-                        size_t size, void *buf)
+mq_error_handler (void *cls,
+                  enum GNUNET_MQ_Error error)
 {
   struct GNUNET_TRANSPORT_Blacklist *br = cls;
 {
   struct GNUNET_TRANSPORT_Blacklist *br = cls;
-  struct GNUNET_MessageHeader req;
 
 
-  if (buf == NULL)
-    {
-      reconnect (br);
-      return 0;
-    }
-  req.size = htons (sizeof (struct GNUNET_MessageHeader));
-  req.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT);
-  memcpy (buf, &req, sizeof (req));
-  receive (br);
-  return sizeof (req);
+  reconnect (br);
 }
 
 
 }
 
 
@@ -173,69 +120,29 @@ transmit_blacklist_init (void *cls,
 static void
 reconnect (struct GNUNET_TRANSPORT_Blacklist *br)
 {
 static void
 reconnect (struct GNUNET_TRANSPORT_Blacklist *br)
 {
-  if (br->client != NULL)
-    GNUNET_CLIENT_disconnect (br->client, GNUNET_NO);
-  br->client = GNUNET_CLIENT_connect (br->sched,
-                                     "transport",
-                                     br->cfg);
-  br->th = GNUNET_CLIENT_notify_transmit_ready (br->client,
-                                               sizeof (struct GNUNET_MessageHeader),
-                                               GNUNET_TIME_UNIT_FOREVER_REL,
-                                               GNUNET_YES,
-                                               &transmit_blacklist_init,
-                                               br);
-}
-
-
-/**
- * Transmit the blacklist response to the service.
- *
- * @param cls closure (struct GNUNET_TRANSPORT_Blacklist*)
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
- */
-static size_t
-transmit_blacklist_reply (void *cls,
-                         size_t size, void *buf)
-{
-  struct GNUNET_TRANSPORT_Blacklist *br = cls;
-  struct BlacklistMessage req;
-
-  if (buf == NULL)
-    {
-      reconnect (br);
-      return 0;
-    }
-  req.header.size = htons (sizeof (req));
-  req.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY);
-  req.is_allowed = htonl (br->cb (br->cb_cls, &br->peer));
-  req.peer = br->peer;
-  memcpy (buf, &req, sizeof (req));
-  receive (br);
-  return sizeof (req);
-}
-
-
-/**
- * Send our reply to a blacklisting request.
- *
- * @param br our overall context
- */
-static void
-reply (struct GNUNET_TRANSPORT_Blacklist *br)
-{
-  br->th = GNUNET_CLIENT_notify_transmit_ready (br->client,
-                                               sizeof (struct BlacklistMessage),
-                                               GNUNET_TIME_UNIT_FOREVER_REL,
-                                               GNUNET_NO,
-                                               &transmit_blacklist_reply,
-                                               br);
-  if (br->th == NULL)
-    {
-      reconnect (br);
-      return;
-    }
+  struct GNUNET_MQ_MessageHandler handlers[] = {
+    GNUNET_MQ_hd_fixed_size (query,
+                             GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_QUERY,
+                             struct BlacklistMessage,
+                             br),
+    GNUNET_MQ_handler_end ()
+  };
+  struct GNUNET_MQ_Envelope *env;
+  struct GNUNET_MessageHeader *req;
+
+  if (NULL != br->mq)
+    GNUNET_MQ_destroy (br->mq);
+  br->mq = GNUNET_CLIENT_connect (br->cfg,
+                                  "transport",
+                                  handlers,
+                                  &mq_error_handler,
+                                  br);
+  if (NULL == br->mq)
+    return;
+  env = GNUNET_MQ_msg (req,
+                       GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT);
+  GNUNET_MQ_send (br->mq,
+                  env);
 }
 
 
 }
 
 
@@ -248,35 +155,29 @@ reply (struct GNUNET_TRANSPORT_Blacklist *br)
  * only way to re-enable connections from peers that were previously
  * blacklisted.
  *
  * only way to re-enable connections from peers that were previously
  * blacklisted.
  *
- * @param sched scheduler to use
  * @param cfg configuration to use
  * @param cb callback to invoke to check if connections are allowed
  * @param cfg configuration to use
  * @param cb callback to invoke to check if connections are allowed
- * @param cb_cls closure for cb
+ * @param cb_cls closure for @a cb
  * @return NULL on error, otherwise handle for cancellation
  */
 struct GNUNET_TRANSPORT_Blacklist *
  * @return NULL on error, otherwise handle for cancellation
  */
 struct GNUNET_TRANSPORT_Blacklist *
-GNUNET_TRANSPORT_blacklist (struct GNUNET_SCHEDULER_Handle *sched,
-                           const struct GNUNET_CONFIGURATION_Handle *cfg,
-                           GNUNET_TRANSPORT_BlacklistCallback cb,
-                           void *cb_cls)
+GNUNET_TRANSPORT_blacklist (const struct GNUNET_CONFIGURATION_Handle *cfg,
+                            GNUNET_TRANSPORT_BlacklistCallback cb,
+                            void *cb_cls)
 {
 {
-  struct GNUNET_CLIENT_Connection * client;
-  struct GNUNET_TRANSPORT_Blacklist *ret;
-
-  client = GNUNET_CLIENT_connect (sched, "transport", cfg);
-  if (NULL == client)
+  struct GNUNET_TRANSPORT_Blacklist *br;
+
+  br = GNUNET_new (struct GNUNET_TRANSPORT_Blacklist);
+  br->cfg = cfg;
+  br->cb = cb;
+  br->cb_cls = cb_cls;
+  reconnect (br);
+  if (NULL == br->mq)
+  {
+    GNUNET_free (br);
     return NULL;
     return NULL;
-  ret = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_Blacklist));
-  ret->client = client;
-  ret->sched = sched;
-  ret->cfg = cfg;
-  ret->th = GNUNET_CLIENT_notify_transmit_ready (client,
-                                                sizeof (struct GNUNET_MessageHeader),
-                                                GNUNET_TIME_UNIT_FOREVER_REL,
-                                                GNUNET_YES,
-                                                &transmit_blacklist_init,
-                                                ret);  
-  return ret;
+  }
+  return br;
 }
 
 
 }
 
 
@@ -289,9 +190,7 @@ GNUNET_TRANSPORT_blacklist (struct GNUNET_SCHEDULER_Handle *sched,
 void
 GNUNET_TRANSPORT_blacklist_cancel (struct GNUNET_TRANSPORT_Blacklist *br)
 {
 void
 GNUNET_TRANSPORT_blacklist_cancel (struct GNUNET_TRANSPORT_Blacklist *br)
 {
-  if (br->th != NULL)
-    GNUNET_CLIENT_notify_transmit_ready_cancel (br->th);
-  GNUNET_CLIENT_disconnect (br->client, GNUNET_NO);
+  GNUNET_MQ_destroy (br->mq);
   GNUNET_free (br);
 }
 
   GNUNET_free (br);
 }