REST/NAMESTORE: rework API
[oweals/gnunet.git] / src / transport / transport_api_address_to_string.c
index 2220790bea9135bd86e6aed89d07c5154f946dde..006e81f29edb23a70db4f31a419475dbb6d644b8 100644 (file)
@@ -1,21 +1,21 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2009-2014 GNUnet e.V.
+     Copyright (C) 2009-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
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License,
+     or (at your option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
+     Affero General Public License for more details.
+    
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-     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., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
+     SPDX-License-Identifier: AGPL3.0-or-later
 */
 /**
  * @file transport/transport_api_address_to_string.c
@@ -48,7 +48,7 @@ struct GNUNET_TRANSPORT_AddressToStringContext
   /**
    * Connection to the service.
    */
-  struct GNUNET_CLIENT_Connection *client;
+  struct GNUNET_MQ_Handle *mq;
 
 };
 
@@ -57,46 +57,59 @@ struct GNUNET_TRANSPORT_AddressToStringContext
  * Function called with responses from the service.
  *
  * @param cls our `struct GNUNET_TRANSPORT_AddressToStringContext *`
- * @param msg NULL on timeout or error, otherwise presumably a
- *        message with the human-readable address
+ * @param msg message with the human-readable address
+ * @return #GNUNET_OK if message is well-formed
  */
-static void
-address_response_processor (void *cls,
-                            const struct GNUNET_MessageHeader *msg)
+static int
+check_reply (void *cls,
+             const struct AddressToStringResultMessage *atsm)
 {
-  struct GNUNET_TRANSPORT_AddressToStringContext *alucb = cls;
-  const struct AddressToStringResultMessage *atsm;
+  uint16_t size = ntohs (atsm->header.size) - sizeof (*atsm);
   const char *address;
-  uint16_t size;
   int result;
   uint32_t addr_len;
 
-  if (NULL == msg)
+  result = (int) ntohl (atsm->res);
+  addr_len = ntohl (atsm->addr_len);
+  if (GNUNET_SYSERR == result)
+    return GNUNET_OK;
+  if (0 == size)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Disconnected from transport, address resolution failed\n");
-    alucb->cb (alucb->cb_cls,
-               NULL,
-               GNUNET_SYSERR);
-    GNUNET_TRANSPORT_address_to_string_cancel (alucb);
-    return;
+    if (GNUNET_OK != result)
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
+    return GNUNET_OK;
   }
-  GNUNET_break (ntohs (msg->type) ==
-                GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING_REPLY);
-
-  size = ntohs (msg->size);
-  if (size < sizeof (struct AddressToStringResultMessage))
+  address = (const char *) &atsm[1];
+  if ( (addr_len > size) ||
+       (address[addr_len -1] != '\0') )
   {
+    /* invalid reply */
     GNUNET_break (0);
-    alucb->cb (alucb->cb_cls,
-               NULL,
-               GNUNET_SYSERR);
-    GNUNET_TRANSPORT_address_to_string_cancel (alucb);
-    return;
+    return GNUNET_SYSERR;
   }
-  atsm = (const struct AddressToStringResultMessage *) msg;
+  return GNUNET_OK;
+}
+
+
+/**
+ * Function called with responses from the service.
+ *
+ * @param cls our `struct GNUNET_TRANSPORT_AddressToStringContext *`
+ * @param msg message with the human-readable address
+ */
+static void
+handle_reply (void *cls,
+              const struct AddressToStringResultMessage *atsm)
+{
+  struct GNUNET_TRANSPORT_AddressToStringContext *alucb = cls;
+  uint16_t size = ntohs (atsm->header.size) - sizeof (*atsm);
+  const char *address;
+  int result;
+
   result = (int) ntohl (atsm->res);
-  addr_len = ntohl (atsm->addr_len);
   if (GNUNET_SYSERR == result)
   {
     /* expect more replies; as this is not the last
@@ -106,24 +119,10 @@ address_response_processor (void *cls,
     alucb->cb (alucb->cb_cls,
                "",
                GNUNET_NO);
-    GNUNET_CLIENT_receive (alucb->client,
-                           &address_response_processor,
-                           alucb,
-                           GNUNET_TIME_UNIT_FOREVER_REL);
     return;
   }
-  if (size == (sizeof (struct AddressToStringResultMessage)))
+  if (0 == size)
   {
-    if (GNUNET_OK != result)
-    {
-      GNUNET_break (0);
-      alucb->cb (alucb->cb_cls,
-                 NULL,
-                 GNUNET_SYSERR);
-      GNUNET_CLIENT_disconnect (alucb->client);
-      GNUNET_free (alucb);
-      return;
-    }
     /* we are done (successfully, without communication errors) */
     alucb->cb (alucb->cb_cls,
                NULL,
@@ -132,29 +131,37 @@ address_response_processor (void *cls,
     return;
   }
   address = (const char *) &atsm[1];
-  if ( (addr_len > (size - (sizeof (struct AddressToStringResultMessage)))) ||
-       (address[addr_len -1] != '\0') )
-  {
-    /* invalid reply */
-    GNUNET_break (0);
-    alucb->cb (alucb->cb_cls,
-               NULL,
-               GNUNET_SYSERR);
-    GNUNET_TRANSPORT_address_to_string_cancel (alucb);
-    return;
-  }
-  /* expect more replies */
-  GNUNET_CLIENT_receive (alucb->client,
-                         &address_response_processor,
-                         alucb,
-                         GNUNET_TIME_UNIT_FOREVER_REL);
-  /* return normal reply to caller */
+  /* return normal reply to caller, also expect more replies */
   alucb->cb (alucb->cb_cls,
              address,
              GNUNET_OK);
 }
 
 
+/**
+ * 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 cls the `struct GNUNET_TRANSPORT_AddressToStringContext *`
+ * @param error error code
+ */
+static void
+mq_error_handler (void *cls,
+                  enum GNUNET_MQ_Error error)
+{
+  struct GNUNET_TRANSPORT_AddressToStringContext *alucb = cls;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Disconnected from transport, address resolution failed\n");
+  alucb->cb (alucb->cb_cls,
+             NULL,
+             GNUNET_SYSERR);
+  GNUNET_TRANSPORT_address_to_string_cancel (alucb);
+}
+
+
 /**
  * Convert a binary address into a human readable address.
  *
@@ -175,61 +182,65 @@ GNUNET_TRANSPORT_address_to_string (const struct GNUNET_CONFIGURATION_Handle *cf
                                     GNUNET_TRANSPORT_AddressToStringCallback aluc,
                                     void *aluc_cls)
 {
-  size_t len;
+  struct GNUNET_TRANSPORT_AddressToStringContext *alc
+    = GNUNET_new (struct GNUNET_TRANSPORT_AddressToStringContext);
+  struct GNUNET_MQ_MessageHandler handlers[] = {
+    GNUNET_MQ_hd_var_size (reply,
+                           GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING_REPLY,
+                           struct AddressToStringResultMessage,
+                           alc),
+    GNUNET_MQ_handler_end ()
+  };
   size_t alen;
   size_t slen;
   struct AddressLookupMessage *msg;
-  struct GNUNET_TRANSPORT_AddressToStringContext *alc;
-  struct GNUNET_CLIENT_Connection *client;
+  struct GNUNET_MQ_Envelope *env;
   char *addrbuf;
 
-  GNUNET_assert (NULL != address);
   alen = address->address_length;
   slen = strlen (address->transport_name) + 1;
-  len = sizeof (struct AddressLookupMessage) + alen + slen;
-  if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+  if ( (alen + slen >= GNUNET_MAX_MESSAGE_SIZE
+        - sizeof (struct AddressLookupMessage)) ||
+       (alen >= GNUNET_MAX_MESSAGE_SIZE) ||
+       (slen >= GNUNET_MAX_MESSAGE_SIZE) )
   {
     GNUNET_break (0);
+    GNUNET_free (alc);
     return NULL;
   }
-  client = GNUNET_CLIENT_connect ("transport", cfg);
-  if (NULL == client)
+  alc->cb = aluc;
+  alc->cb_cls = aluc_cls;
+  alc->mq = GNUNET_CLIENT_connect (cfg,
+                                   "transport",
+                                   handlers,
+                                   &mq_error_handler,
+                                   alc);
+  if (NULL == alc->mq)
   {
     GNUNET_break (0);
+    GNUNET_free (alc);
     return NULL;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Client %p tries to resolve for peer `%s' address plugin %s len %u\n",
-              client,
+              "Client tries to resolve for peer `%s' address plugin %s len %u\n",
               GNUNET_i2s (&address->peer),
               address->transport_name,
-              address->address_length);
-
-  msg = GNUNET_malloc (len);
-  msg->header.size = htons (len);
-  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING);
+              (unsigned int) address->address_length);
+  env = GNUNET_MQ_msg_extra (msg,
+                             alen + slen,
+                             GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING);
   msg->numeric_only = htons ((int16_t) numeric);
   msg->addrlen = htons ((uint16_t) alen);
   msg->timeout = GNUNET_TIME_relative_hton (timeout);
   addrbuf = (char *) &msg[1];
-  memcpy (addrbuf,
+  GNUNET_memcpy (addrbuf,
           address->address,
           alen);
-  memcpy (&addrbuf[alen],
+  GNUNET_memcpy (&addrbuf[alen],
           address->transport_name,
           slen);
-  alc = GNUNET_new (struct GNUNET_TRANSPORT_AddressToStringContext);
-  alc->cb = aluc;
-  alc->cb_cls = aluc_cls;
-  alc->client = client;
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_CLIENT_transmit_and_get_response (client,
-                                                          &msg->header,
-                                                          GNUNET_TIME_UNIT_FOREVER_REL,
-                                                          GNUNET_YES,
-                                                          &address_response_processor,
-                                                          alc));
-  GNUNET_free (msg);
+  GNUNET_MQ_send (alc->mq,
+                  env);
   return alc;
 }
 
@@ -237,15 +248,14 @@ GNUNET_TRANSPORT_address_to_string (const struct GNUNET_CONFIGURATION_Handle *cf
 /**
  * Cancel request for address conversion.
  *
- * @param pic the context handle
+ * @param alc the context handle
  */
 void
-GNUNET_TRANSPORT_address_to_string_cancel (struct GNUNET_TRANSPORT_AddressToStringContext *pic)
+GNUNET_TRANSPORT_address_to_string_cancel (struct GNUNET_TRANSPORT_AddressToStringContext *alc)
 {
-  GNUNET_CLIENT_disconnect (pic->client);
-  GNUNET_free (pic);
+  GNUNET_MQ_destroy (alc->mq);
+  GNUNET_free (alc);
 }
 
 
-
 /* end of transport_api_address_to_string.c */