fix compiler warning for format string
[oweals/gnunet.git] / src / gns / gnunet-service-gns.c
index 386e6d7449e7e3cddeebf84e4f5df1e00809f36e..3e718dac851831fced2178b0e9ef4040020319d1 100644 (file)
@@ -35,6 +35,7 @@
 #include "gnunet_statistics_service.h"
 #include "gns.h"
 #include "gnunet-service-gns_resolver.h"
+#include "gnunet-service-gns_reverser.h"
 #include "gnunet-service-gns_shorten.h"
 #include "gnunet-service-gns_interceptor.h"
 #include "gnunet_protocols.h"
@@ -108,6 +109,11 @@ struct ClientLookupHandle
    */
   struct GNS_ResolverHandle *lookup;
 
+  /**
+   * Active handle for a reverse lookup
+   */
+  struct GNS_ReverserHandle *rev_lookup;
+
   /**
    * request id
    */
@@ -295,6 +301,7 @@ shutdown_task (void *cls)
     identity_handle = NULL;
   }
   GNS_resolver_done ();
+  GNS_reverse_done ();
   GNS_shorten_done ();
   while (NULL != (ma = ma_head))
   {
@@ -367,7 +374,10 @@ client_disconnect_cb (void *cls,
               client);
   while (NULL != (clh = gc->clh_head))
   {
-    GNS_resolver_lookup_cancel (clh->lookup);
+    if (NULL != clh->lookup)
+      GNS_resolver_lookup_cancel (clh->lookup);
+    if (NULL != clh->rev_lookup)
+      GNS_reverse_lookup_cancel (clh->rev_lookup);
     GNUNET_CONTAINER_DLL_remove (gc->clh_head,
                                  gc->clh_tail,
                                  clh);
@@ -846,6 +856,47 @@ send_lookup_response (void* cls,
                             GNUNET_NO);
 }
 
+/**
+ * Reply to client with the result from our reverse lookup.
+ *
+ * @param cls the closure (our client lookup handle)
+ * @param rd_count the number of records in @a rd
+ * @param rd the record data
+ */
+static void
+send_reverse_lookup_response (void* cls,
+                              const char *name)
+{
+  struct ClientLookupHandle *clh = cls;
+  struct GNUNET_MQ_Envelope *env;
+  struct ReverseLookupResultMessage *rmsg;
+  size_t len;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Sending LOOKUP_RESULT message with %s\n",
+              name);
+
+  if (NULL == name)
+    len = 1;
+  else
+    len = strlen (name) + 1;
+  env = GNUNET_MQ_msg_extra (rmsg,
+                             len,
+                             GNUNET_MESSAGE_TYPE_GNS_REVERSE_LOOKUP_RESULT);
+  rmsg->id = clh->request_id;
+  if (1 < len)
+    GNUNET_memcpy ((char*) &rmsg[1],
+                   name,
+                   strlen (name));
+  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(clh->gc->client),
+                  env);
+  GNUNET_CONTAINER_DLL_remove (clh->gc->clh_head, clh->gc->clh_tail, clh);
+  GNUNET_free (clh);
+  GNUNET_STATISTICS_update (statistics,
+                            "Completed reverse lookups", 1,
+                            GNUNET_NO);
+}
+
 
 /**
  * Checks a #GNUNET_MESSAGE_TYPE_GNS_LOOKUP message
@@ -856,7 +907,7 @@ send_lookup_response (void* cls,
  */
 static int
 check_lookup (void *cls,
-                   const struct LookupMessage *l_msg)
+              const struct LookupMessage *l_msg)
 {
   size_t msg_size;
   const char* name;
@@ -936,6 +987,37 @@ handle_lookup (void *cls,
                             1, GNUNET_NO);
 }
 
+/**
+ * Handle reverse lookup requests from client
+ *
+ * @param cls the closure
+ * @param client the client
+ * @param message the message
+ */
+static void
+handle_rev_lookup (void *cls,
+                   const struct ReverseLookupMessage *sh_msg)
+{
+  struct GnsClient *gc = cls;
+  struct ClientLookupHandle *clh;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Received REVERSE_LOOKUP message\n");
+  GNUNET_SERVICE_client_continue (gc->client);
+
+  clh = GNUNET_new (struct ClientLookupHandle);
+  GNUNET_CONTAINER_DLL_insert (gc->clh_head, gc->clh_tail, clh);
+  clh->gc = gc;
+  clh->request_id = sh_msg->id;
+  clh->rev_lookup = GNS_reverse_lookup (&sh_msg->zone_pkey,
+                                        &sh_msg->root_pkey,
+                                        &send_reverse_lookup_response,
+                                        clh);
+  GNUNET_STATISTICS_update (statistics,
+                            "Reverse lookup attempts",
+                            1, GNUNET_NO);
+}
+
 
 /**
  * The zone monitor is now in SYNC with the current state of the
@@ -980,6 +1062,51 @@ handle_monitor_error (void *cls)
                                                 NULL);
 }
 
+/**
+ * Method called to inform about the ego to be used for the master zone
+ * for DNS interceptions.
+ *
+ * This function is only called ONCE, and 'NULL' being passed in
+ * @a ego does indicate that interception is not configured.
+ * If @a ego is non-NULL, we should start to intercept DNS queries
+ * and resolve ".gnu" queries using the given ego as the master zone.
+ *
+ * @param cls closure, our `const struct GNUNET_CONFIGURATION_Handle *c`
+ * @param ego ego handle
+ * @param ctx context for application to store data for this ego
+ *                 (during the lifetime of this process, initially NULL)
+ * @param name name assigned by the user for this ego,
+ *                   NULL if the user just deleted the ego and it
+ *                   must thus no longer be used
+ */
+static void
+identity_reverse_cb (void *cls,
+                       struct GNUNET_IDENTITY_Ego *ego,
+                       void **ctx,
+                       const char *name)
+{
+  identity_op = NULL;
+
+  if (NULL == ego)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                _("No ego configured for `%s`\n"),
+                "gns-master");
+
+    return;
+  }
+  if (GNUNET_SYSERR ==
+      GNS_reverse_init (namestore_handle,
+                        GNUNET_IDENTITY_ego_get_private_key (ego),
+                        name))
+  {
+    GNUNET_break (0);
+    GNUNET_SCHEDULER_add_now (&shutdown_task, NULL);
+    return;
+  }
+}
+
+
 
 /**
  * Method called to inform about the ego to be used for the master zone
@@ -1006,13 +1133,22 @@ identity_intercept_cb (void *cls,
 {
   const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
   struct GNUNET_CRYPTO_EcdsaPublicKey dns_root;
-
   identity_op = NULL;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Looking for gns-intercept ego\n");
+  identity_op = GNUNET_IDENTITY_get (identity_handle,
+                                     "gns-reverse",
+                                     &identity_reverse_cb,
+                                     (void*)cfg);
+
+
   if (NULL == ego)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 _("No ego configured for `%s`\n"),
                 "gns-intercept");
+
     return;
   }
   GNUNET_IDENTITY_ego_get_public_key (ego,
@@ -1149,6 +1285,10 @@ GNUNET_SERVICE_MAIN
                         GNUNET_MESSAGE_TYPE_GNS_LOOKUP,
                         struct LookupMessage,
                         NULL),
+ GNUNET_MQ_hd_fixed_size (rev_lookup,
+                          GNUNET_MESSAGE_TYPE_GNS_REVERSE_LOOKUP,
+                          struct ReverseLookupMessage,
+                          NULL),
  GNUNET_MQ_handler_end());