gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnunet] branch master updated: use unique 32-bit IDs for D


From: gnunet
Subject: [GNUnet-SVN] [gnunet] branch master updated: use unique 32-bit IDs for DNS requests to avoid random confusions, handle additional and authoritative records as well
Date: Thu, 18 Oct 2018 14:55:19 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new c7c6446e3 use unique 32-bit IDs for DNS requests to avoid random 
confusions, handle additional and authoritative records as well
c7c6446e3 is described below

commit c7c6446e3ea37531b67252a452937f3578570a57
Author: Christian Grothoff <address@hidden>
AuthorDate: Thu Oct 18 14:55:17 2018 +0200

    use unique 32-bit IDs for DNS requests to avoid random confusions, handle 
additional and authoritative records as well
---
 src/arm/test_gnunet_service_arm.c  |  14 +--
 src/util/gnunet-service-resolver.c | 206 +++++++++++++++++++++++++++++--------
 src/util/resolver.h                |  14 +--
 src/util/resolver_api.c            |  28 ++---
 4 files changed, 185 insertions(+), 77 deletions(-)

diff --git a/src/arm/test_gnunet_service_arm.c 
b/src/arm/test_gnunet_service_arm.c
index 8b6d09bd9..fd5244ec2 100644
--- a/src/arm/test_gnunet_service_arm.c
+++ b/src/arm/test_gnunet_service_arm.c
@@ -112,7 +112,7 @@ hostname_resolve_cb (void *cls,
   if (NULL == addr)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Name not resolved!\n");
+                "Failed to resolve our own hostname!\n");
     GNUNET_break (0);
     ret = 3;
     GNUNET_ARM_request_service_stop (arm,
@@ -200,7 +200,7 @@ main (int argc, char *av[])
     FPRINTF (stderr,
              "%s",
              "Failed to determine my own hostname, testcase not run.\n");
-    return 0;
+    return 77;
   }
   if ( (0 == strcmp (hostname,
                     "localhost")) ||
@@ -210,6 +210,8 @@ main (int argc, char *av[])
     /* we cannot use 'localhost' as this would not trigger the
        resolver service (see resolver_api.c); so in this case,
        we fall back to (ab)using gnu.org. */
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+               "Falling back to `www.gnu.org'\n");
     strcpy (hostname,
            "www.gnu.org");
   }
@@ -224,7 +226,7 @@ main (int argc, char *av[])
       FPRINTF (stderr,
                "Failed to resolve my hostname `%s', testcase not run.\n",
                hostname);
-      return 0;
+      return 77;
     }
     freeaddrinfo (ai);
   }
@@ -240,7 +242,7 @@ main (int argc, char *av[])
         FPRINTF (stderr,
                  "Failed to resolve my hostname `%s', testcase not run.\n",
                  hostname);
-        return 0;
+        return 77;
       }
   }
 #elif HAVE_GETHOSTBYNAME
@@ -253,13 +255,13 @@ main (int argc, char *av[])
         FPRINTF (stderr,
                  "Failed to resolve my hostname `%s', testcase not run.\n",
                  hostname);
-        return 0;
+        return 77;
       }
   }
 #else
   FPRINTF (stderr,
            "libc fails to have resolver function, testcase not run.\n");
-  return 0;
+  return 77;
 #endif
   GNUNET_log_setup ("test-gnunet-service-arm",
                    "WARNING",
diff --git a/src/util/gnunet-service-resolver.c 
b/src/util/gnunet-service-resolver.c
index 90ed746b6..252408466 100644
--- a/src/util/gnunet-service-resolver.c
+++ b/src/util/gnunet-service-resolver.c
@@ -143,7 +143,7 @@ struct ActiveLookup
    * Unique request ID of a client if a query for this hostname/record_type
    * is currently pending, undefined otherwise.
    */
-  uint16_t request_id;
+  uint32_t client_request_id;
 
   /**
    * Unique DNS request ID of a client if a query for this hostname/record_type
@@ -180,10 +180,16 @@ static struct ActiveLookup *lookup_tail;
 static struct GNUNET_DNSSTUB_Context *dnsstub_ctx;
 
 /**
+ * My domain, to be appended to the hostname to get a FQDN.
+ */
+static char *my_domain;
+
+/**
  * How many entries do we have in #cache_head DLL?
  */
 static unsigned int cache_size;
 
+
 /**
  * Remove @a entry from cache.
  *
@@ -262,6 +268,28 @@ extract_dns_server (const char* line,
 
 
 /**
+ * Find out if the configuration file line contains a string
+ * starting with "search ", and if so, return a copy of
+ * the machine's search domain.
+ *
+ * @param line line to parse
+ * @param line_len number of characters in @a line
+ * @return NULL if no nameserver is configured in this @a line
+ */
+static char *
+extract_search_domain (const char* line,
+                      size_t line_len)
+{
+  if (0 == strncmp (line,
+                    "search ",
+                    strlen ("search ")))
+    return GNUNET_strndup (line + strlen ("search "),
+                           line_len - strlen ("search "));
+  return NULL;
+}
+
+
+/**
  * Reads the list of nameservers from /etc/resolve.conf
  *
  * @param server_addrs[out] a list of null-terminated server address strings
@@ -306,9 +334,16 @@ lookup_dns_servers (char ***server_addrs)
     dns_server = extract_dns_server (buf + read_offset,
                                      line_len);
     if (NULL != dns_server)
+    {
       GNUNET_array_append (*server_addrs,
                           num_dns_servers,
                           dns_server);
+    }
+    else if (NULL == my_domain)
+    {
+      my_domain = extract_search_domain (buf + read_offset,
+                                        line_len);
+    }
     read_offset += line_len + 1;
   }
   GNUNET_DISK_file_close (fh);
@@ -392,7 +427,7 @@ make_reverse_hostname (const void *ip,
  *
  * @param record information to transmit
  * @param record_type requested record type from client
- * @param request_id to which request are we responding
+ * @param client_request_id to which request are we responding
  * @param client where to send @a record
  * @return #GNUNET_YES if we sent a reply,
  *         #GNUNET_NO if the record type is not understood or
@@ -401,7 +436,7 @@ make_reverse_hostname (const void *ip,
 static int
 send_reply (struct GNUNET_DNSPARSER_Record *record,
             uint16_t record_type,
-           uint16_t request_id,
+           uint32_t client_request_id,
            struct GNUNET_SERVICE_Client *client)
 {
   struct GNUNET_RESOLVER_ResponseMessage *msg;
@@ -446,7 +481,7 @@ send_reply (struct GNUNET_DNSPARSER_Record *record,
   env = GNUNET_MQ_msg_extra (msg,
                             payload_len,
                             GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
-  msg->id = request_id;
+  msg->client_id = client_request_id;
   GNUNET_memcpy (&msg[1],
                 payload,
                 payload_len);
@@ -458,13 +493,13 @@ send_reply (struct GNUNET_DNSPARSER_Record *record,
 
 /**
  * Send message to @a client that we transmitted all
- * responses for @a request_id
+ * responses for @a client_request_id
  *
- * @param request_id to which request are we responding
+ * @param client_request_id to which request are we responding
  * @param client where to send @a record
  */
 static void
-send_end_msg (uint16_t request_id,
+send_end_msg (uint32_t client_request_id,
              struct GNUNET_SERVICE_Client *client)
 {
   struct GNUNET_RESOLVER_ResponseMessage *msg;
@@ -474,7 +509,7 @@ send_end_msg (uint16_t request_id,
              "Sending END message\n");
   env = GNUNET_MQ_msg (msg,
                       GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
-  msg->id = request_id;
+  msg->client_id = client_request_id;
   GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
                  env);
 }
@@ -518,13 +553,13 @@ remove_expired (struct ResolveCache *rc)
  *
  * @param hostname DNS name to resolve
  * @param record_type desired record type
- * @param request_id client's request ID
+ * @param client_request_id client's request ID
  * @param client who should get the result?
  */
 static void
 process_get (const char *hostname,
             uint16_t record_type,
-            uint16_t request_id,
+            uint32_t client_request_id,
             struct GNUNET_SERVICE_Client *client);
 
 
@@ -536,13 +571,13 @@ process_get (const char *hostname,
  *
  * @param hostname what hostname was to be resolved
  * @param record_type what type of record was requested
- * @param request_id unique identification of the client's request
+ * @param client_request_id unique identification of the client's request
  * @param client handle to the client making the request (for sending the 
reply)
  */
 static int
 try_cache (const char *hostname,
            uint16_t record_type,
-          uint16_t request_id,
+          uint32_t client_request_id,
           struct GNUNET_SERVICE_Client *client)
 {
   struct ResolveCache *pos;
@@ -595,18 +630,18 @@ try_cache (const char *hostname,
 
       process_get (hostname,
                    record_type,
-                   request_id,
+                   client_request_id,
                    client);
       return GNUNET_YES; /* counts as a cache "hit" */
     }
     found |= send_reply (rle->record,
                          record_type,
-                         request_id,
+                         client_request_id,
                          client);
   }
   if (GNUNET_NO == found)
     return GNUNET_NO; /* had records, but none matched! */
-  send_end_msg (request_id,
+  send_end_msg (client_request_id,
                 client);
   return GNUNET_YES;
 }
@@ -693,14 +728,14 @@ handle_resolve_result (void *cls,
     GNUNET_DNSPARSER_free_packet (parsed);
     return;
   }
-  if (0 == parsed->num_answers)
+  if (0 == parsed->num_answers + parsed->num_authority_records + 
parsed->num_additional_records)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "DNS reply (hostname %s, request ID %u) contains no answers\n",
                 al->hostname,
-               al->request_id);
+               (unsigned int) al->client_request_id);
     GNUNET_DNSPARSER_free_packet (parsed);
-    send_end_msg (al->request_id,
+    send_end_msg (al->client_request_id,
                   al->client);
     free_active_lookup (al);
     return;
@@ -712,7 +747,7 @@ handle_resolve_result (void *cls,
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Got reply for hostname %s and request ID %u\n",
               al->hostname,
-              al->request_id);
+              (unsigned int) al->client_request_id);
   /* add to cache */
   for (unsigned int i = 0; i != parsed->num_answers; i++)
   {
@@ -740,6 +775,58 @@ handle_resolve_result (void *cls,
                                  rc->records_tail,
                                  rle);
   }
+  for (unsigned int i = 0; i != parsed->num_authority_records; i++)
+  {
+    struct GNUNET_DNSPARSER_Record *record = &parsed->authority_records[i];
+    struct RecordListEntry *rle;
+
+    for (rc = cache_head; NULL != rc; rc = rc->next)
+      if (0 == strcasecmp (rc->hostname,
+                           record->name))
+        break;
+    if (NULL == rc)
+    {
+      rc = GNUNET_new (struct ResolveCache);
+      rc->hostname = GNUNET_strdup (record->name);
+      GNUNET_CONTAINER_DLL_insert (cache_head,
+                                   cache_tail,
+                                   rc);
+      cache_size++;
+    }
+    /* TODO: ought to check first if we have this exact record
+       already in the cache! */
+    rle = GNUNET_new (struct RecordListEntry);
+    rle->record = GNUNET_DNSPARSER_duplicate_record (record);
+    GNUNET_CONTAINER_DLL_insert (rc->records_head,
+                                 rc->records_tail,
+                                 rle);
+  }
+  for (unsigned int i = 0; i != parsed->num_additional_records; i++)
+  {
+    struct GNUNET_DNSPARSER_Record *record = &parsed->additional_records[i];
+    struct RecordListEntry *rle;
+
+    for (rc = cache_head; NULL != rc; rc = rc->next)
+      if (0 == strcasecmp (rc->hostname,
+                           record->name))
+        break;
+    if (NULL == rc)
+    {
+      rc = GNUNET_new (struct ResolveCache);
+      rc->hostname = GNUNET_strdup (record->name);
+      GNUNET_CONTAINER_DLL_insert (cache_head,
+                                   cache_tail,
+                                   rc);
+      cache_size++;
+    }
+    /* TODO: ought to check first if we have this exact record
+       already in the cache! */
+    rle = GNUNET_new (struct RecordListEntry);
+    rle->record = GNUNET_DNSPARSER_duplicate_record (record);
+    GNUNET_CONTAINER_DLL_insert (rc->records_head,
+                                 rc->records_tail,
+                                 rle);
+  }
   /* see if we need to do the 2nd request for AAAA records */
   if ( (GNUNET_DNSPARSER_TYPE_ALL == al->record_type) &&
        (GNUNET_NO == al->did_aaaa) )
@@ -774,11 +861,13 @@ handle_resolve_result (void *cls,
   if (GNUNET_NO ==
       try_cache (al->hostname,
                  al->record_type,
-                 al->request_id,
+                 al->client_request_id,
                  al->client))
     /* cache failed, tell client we could not get an answer */
-    send_end_msg (al->request_id,
+  {
+    send_end_msg (al->client_request_id,
                   al->client);
+  }
   free_active_lookup (al);
   GNUNET_DNSPARSER_free_packet (parsed);
 }
@@ -798,7 +887,7 @@ handle_resolve_timeout (void *cls)
   al->timeout_task = NULL;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "DNS lookup timeout!\n");
-  send_end_msg (al->request_id,
+  send_end_msg (al->client_request_id,
                 al->client);
   free_active_lookup (al);
 }
@@ -810,14 +899,14 @@ handle_resolve_timeout (void *cls)
  *
  * @param hostname DNS name to resolve
  * @param record_type record type to locate
- * @param request_id client request ID
+ * @param client_request_id client request ID
  * @param client handle to the client
  * @return #GNUNET_OK if the DNS query is now pending
  */
 static int
 resolve_and_cache (const char* hostname,
                   uint16_t record_type,
-                  uint16_t request_id,
+                  uint32_t client_request_id,
                   struct GNUNET_SERVICE_Client *client)
 {
   char *packet_buf;
@@ -827,7 +916,8 @@ resolve_and_cache (const char* hostname,
   uint16_t type;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "resolve_and_cache\n");
+             "resolve_and_cache `%s'\n",
+             hostname);
   dns_id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
                                                 UINT16_MAX);
 
@@ -851,7 +941,7 @@ resolve_and_cache (const char* hostname,
   al = GNUNET_new (struct ActiveLookup);
   al->hostname = GNUNET_strdup (hostname);
   al->record_type = record_type;
-  al->request_id = request_id;
+  al->client_request_id = client_request_id;
   al->dns_id = dns_id;
   al->client = client;
   al->timeout_task = GNUNET_SCHEDULER_add_delayed (DNS_TIMEOUT,
@@ -868,42 +958,68 @@ resolve_and_cache (const char* hostname,
                               lookup_tail,
                               al);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Resolving %s, request_id = %u, dns_id = %u\n",
+             "Resolving %s, client_request_id = %u, dns_id = %u\n",
              hostname,
-              (unsigned int) request_id,
+              (unsigned int) client_request_id,
              (unsigned int) dns_id);
   return GNUNET_OK;
 }
 
 
 /**
- * Process DNS request for @a hostname with request ID @a request_id
+ * Process DNS request for @a hostname with request ID @a client_request_id
  * from @a client demanding records of type @a record_type.
  *
  * @param hostname DNS name to resolve
  * @param record_type desired record type
- * @param request_id client's request ID
+ * @param client_request_id client's request ID
  * @param client who should get the result?
  */
 static void
 process_get (const char *hostname,
             uint16_t record_type,
-            uint16_t request_id,
+            uint32_t client_request_id,
             struct GNUNET_SERVICE_Client *client)
 {
+  char fqdn[255];
+  
+  if (  (NULL != my_domain) &&
+       (NULL == strchr (hostname,
+                        (unsigned char) '.')) &&
+       (strlen (hostname) + strlen (my_domain) <= 253) )
+  {
+    GNUNET_snprintf (fqdn,
+                    sizeof (fqdn),
+                    "%s.%s",
+                    hostname,
+                    my_domain);                     
+  }
+  else if (strlen (hostname) < 255)
+  {
+    GNUNET_snprintf (fqdn,
+                    sizeof (fqdn),
+                    "%s",
+                    hostname);
+  }
+  else
+  {
+    GNUNET_break (0);
+    GNUNET_SERVICE_client_drop (client);
+    return;
+  }
   if (GNUNET_NO ==
-      try_cache (hostname,
+      try_cache (fqdn,
                  record_type,
-                 request_id,
+                 client_request_id,
                  client))
   {
     if (GNUNET_OK !=
-        resolve_and_cache (hostname,
+        resolve_and_cache (fqdn,
                            record_type,
-                           request_id,
+                           client_request_id,
                            client))
     {
-      send_end_msg (request_id,
+      send_end_msg (client_request_id,
                     client);
     }
   }
@@ -979,12 +1095,13 @@ handle_get (void *cls,
   struct GNUNET_SERVICE_Client *client = cls;
   int direction;
   int af;
-  uint16_t request_id;
+  uint32_t client_request_id;
   char *hostname;
 
   direction = ntohl (msg->direction);
   af = ntohl (msg->af);
-  request_id = ntohs (msg->id);
+  client_request_id = msg->client_id;
+  GNUNET_SERVICE_client_continue (client);
   if (GNUNET_NO == direction)
   {
     /* IP from hostname */
@@ -995,7 +1112,7 @@ handle_get (void *cls,
       {
        process_get (hostname,
                      GNUNET_DNSPARSER_TYPE_ALL,
-                     request_id,
+                     client_request_id,
                      client);
        break;
       }
@@ -1003,7 +1120,7 @@ handle_get (void *cls,
       {
        process_get (hostname,
                      GNUNET_DNSPARSER_TYPE_A,
-                     request_id,
+                     client_request_id,
                      client);
         break;
       }
@@ -1011,15 +1128,15 @@ handle_get (void *cls,
       {
        process_get (hostname,
                      GNUNET_DNSPARSER_TYPE_AAAA,
-                     request_id,
+                     client_request_id,
                      client);
         break;
       }
       default:
       {
         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                 "got invalid af: %d\n",
-                 af);
+                   "got invalid af: %d\n",
+                   af);
         GNUNET_assert (0);
       }
     }
@@ -1031,11 +1148,10 @@ handle_get (void *cls,
                                       af);
     process_get (hostname,
                  GNUNET_DNSPARSER_TYPE_PTR,
-                 request_id,
+                 client_request_id,
                  client);
   }
   GNUNET_free_non_null (hostname);
-  GNUNET_SERVICE_client_continue (client);
 }
 
 
diff --git a/src/util/resolver.h b/src/util/resolver.h
index 07851d052..54a1cf5fd 100644
--- a/src/util/resolver.h
+++ b/src/util/resolver.h
@@ -41,7 +41,7 @@ GNUNET_NETWORK_STRUCT_BEGIN
 struct GNUNET_RESOLVER_GetMessage
 {
   /**
-   * Type:  GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST
+   * Type:  #GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST
    */
   struct GNUNET_MessageHeader header;
 
@@ -60,7 +60,7 @@ struct GNUNET_RESOLVER_GetMessage
    * identifies the request and is contained in the response message. The
    * client has to match response to request by this identifier.
    */
-  uint16_t id GNUNET_PACKED;
+  uint32_t client_id GNUNET_PACKED;
 
   /* followed by 0-terminated string for A/AAAA-lookup or
      by 'struct in_addr' / 'struct in6_addr' for reverse lookup */
@@ -71,15 +71,15 @@ struct GNUNET_RESOLVER_GetMessage
 struct GNUNET_RESOLVER_ResponseMessage
 {
   /**
-   * Type: GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE
+   * Type: #GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE
    */
   struct GNUNET_MessageHeader header;
 
   /**
-  * identifies the request this message responds to. The client
-  * has to match response to request by this identifier.
-  */
-  uint16_t id GNUNET_PACKED;
+   * identifies the request this message responds to. The client
+   * has to match response to request by this identifier.
+   */
+  uint32_t client_id GNUNET_PACKED;
 
   /* followed by 0-terminated string for response to a reverse lookup
    * or by 'struct in_addr' / 'struct in6_addr' for response to
diff --git a/src/util/resolver_api.c b/src/util/resolver_api.c
index 8a054327b..871eeb4bf 100644
--- a/src/util/resolver_api.c
+++ b/src/util/resolver_api.c
@@ -68,10 +68,10 @@ static struct GNUNET_RESOLVER_RequestHandle *req_head;
  */
 static struct GNUNET_RESOLVER_RequestHandle *req_tail;
 
-///**
-// * ID of the last request we sent to the service
-// */
-//static uint16_t last_request_id;
+/**
+ * ID of the last request we sent to the service
+ */
+static uint32_t last_request_id;
 
 /**
  * How long should we wait to reconnect?
@@ -445,7 +445,7 @@ process_requests ()
                              GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST);
   msg->direction = htonl (rh->direction);
   msg->af = htonl (rh->af);
-  msg->id = htons (rh->id);
+  msg->client_id = rh->id;
   GNUNET_memcpy (&msg[1],
                 &rh[1],
                 rh->data_len);
@@ -491,11 +491,11 @@ handle_response (void *cls,
   struct GNUNET_RESOLVER_RequestHandle *rh = req_head;
   uint16_t size;
   char *nret;
-  uint16_t request_id = msg->id;
+  uint32_t client_request_id = msg->client_id;
 
   for (; rh != NULL; rh = rh->next)
   {
-    if (rh->id == request_id)
+    if (rh->id == client_request_id)
       break;
   }
 
@@ -911,14 +911,6 @@ handle_lookup_timeout (void *cls)
 }
 
 
-static uint16_t
-get_request_id ()
-{
-  return (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
-                                              UINT16_MAX);
-}
-
-
 /**
  * Convert a string to one or more IP addresses.
  *
@@ -953,8 +945,7 @@ GNUNET_RESOLVER_ip_get (const char *hostname,
        hostname);
   rh = GNUNET_malloc (sizeof (struct GNUNET_RESOLVER_RequestHandle) + slen);
   rh->af = af;
-  //rh->id = ++last_request_id;
-  rh->id = get_request_id ();
+  rh->id = ++last_request_id;
   rh->addr_callback = callback;
   rh->cls = callback_cls;
   GNUNET_memcpy (&rh[1],
@@ -1101,8 +1092,7 @@ GNUNET_RESOLVER_hostname_get (const struct sockaddr *sa,
   rh->name_callback = callback;
   rh->cls = cls;
   rh->af = sa->sa_family;
-  //rh->id = ++last_request_id;
-  rh->id = get_request_id ();
+  rh->id = ++last_request_id;
   rh->timeout = GNUNET_TIME_relative_to_absolute (timeout);
   GNUNET_memcpy (&rh[1],
                 ip,

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]