grub-devel.gnu.org archive mirror
 help / color / mirror / Atom feed
From: Josef Bacik <jbacik@fb.com>
To: <kernel-team@fb.com>, <grub-devel@gnu.org>
Subject: [PATCH] dns: realloc address buffer after each packet
Date: Wed, 24 Feb 2016 14:11:12 -0500	[thread overview]
Message-ID: <1456341072-13356-1-git-send-email-jbacik@fb.com> (raw)

Sometimes DNS responses come in slower than we poll for them which can lead us
to process multiple DNS packets which overflows the addresses array.  So instead
realloc the array each time to make sure we are accounting for any answers we
currently have in the address array.  We also move the caching of the addresses
outside of the recv hook so we can be sure to cache all the responses at once
instead of one packet at a time.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fb.com>
---
 grub-core/net/dns.c | 65 ++++++++++++++++++++++++++++-------------------------
 1 file changed, 34 insertions(+), 31 deletions(-)

diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
index 89741dd..d8258c6 100644
--- a/grub-core/net/dns.c
+++ b/grub-core/net/dns.c
@@ -109,11 +109,10 @@ struct recv_data
 {
   grub_size_t *naddresses;
   struct grub_net_network_level_address **addresses;
-  int cache;
   grub_uint16_t id;
+  grub_uint32_t ttl;
   int dns_err;
   char *name;
-  const char *oname;
   int stop;
 };
 
@@ -230,6 +229,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)),
 	   struct grub_net_buff *nb,
 	   void *data_)
 {
+  struct grub_net_network_level_address *addresses;
   struct dns_header *head;
   struct recv_data *data = data_;
   int i, j;
@@ -276,14 +276,17 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)),
       ptr++;
       ptr += 4;
     }
-  *data->addresses = grub_malloc (sizeof ((*data->addresses)[0])
-				 * grub_be_to_cpu16 (head->ancount));
-  if (!*data->addresses)
+  addresses = grub_realloc (*data->addresses,
+			    sizeof ((*data->addresses)[0])
+			    * (grub_be_to_cpu16 (head->ancount)
+			       + *data->naddresses));
+  if (!addresses)
     {
       grub_errno = GRUB_ERR_NONE;
       grub_netbuff_free (nb);
       return GRUB_ERR_NONE;
     }
+  *data->addresses = addresses;
   reparse_ptr = ptr;
  reparse:
   for (i = 0, ptr = reparse_ptr; i < grub_be_to_cpu16 (head->ancount); i++)
@@ -386,31 +389,6 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)),
 	}
       ptr += length;
     }
-  if (ttl_all && *data->naddresses && data->cache)
-    {
-      int h;
-      grub_dprintf ("dns", "caching for %d seconds\n", ttl_all);
-      h = hash (data->oname);
-      grub_free (dns_cache[h].name);
-      dns_cache[h].name = 0;
-      grub_free (dns_cache[h].addresses);
-      dns_cache[h].addresses = 0;
-      dns_cache[h].name = grub_strdup (data->oname);
-      dns_cache[h].naddresses = *data->naddresses;
-      dns_cache[h].addresses = grub_malloc (*data->naddresses
-					    * sizeof (dns_cache[h].addresses[0]));
-      dns_cache[h].limit_time = grub_get_time_ms () + 1000 * ttl_all;
-      if (!dns_cache[h].addresses || !dns_cache[h].name)
-	{
-	  grub_free (dns_cache[h].name);
-	  dns_cache[h].name = 0;
-	  grub_free (dns_cache[h].addresses);
-	  dns_cache[h].addresses = 0;
-	}
-      grub_memcpy (dns_cache[h].addresses, *data->addresses,
-		   *data->naddresses
-		   * sizeof (dns_cache[h].addresses[0]));
-    }
   grub_netbuff_free (nb);
   grub_free (redirect_save);
   return GRUB_ERR_NONE;
@@ -435,7 +413,7 @@ grub_net_dns_lookup (const char *name,
   grub_uint8_t *qtypeptr;
   grub_err_t err = GRUB_ERR_NONE;
   struct recv_data data = {naddresses, addresses, cache,
-			   grub_cpu_to_be16 (id++), 0, 0, name, 0};
+			   grub_cpu_to_be16 (id++), ~0U, 0, 0};
   grub_uint8_t *nbd;
   grub_size_t try_server = 0;
 
@@ -602,6 +580,31 @@ grub_net_dns_lookup (const char *name,
   
   grub_free (sockets);
 
+  if (data.ttl && *data.naddresses && cache)
+    {
+      int h;
+      grub_dprintf ("dns", "caching for %d seconds\n", data.ttl);
+      h = hash (name);
+      grub_free (dns_cache[h].name);
+      dns_cache[h].name = 0;
+      grub_free (dns_cache[h].addresses);
+      dns_cache[h].addresses = 0;
+      dns_cache[h].name = grub_strdup (name);
+      dns_cache[h].naddresses = *data.naddresses;
+      dns_cache[h].addresses = grub_malloc (*data.naddresses
+					    * sizeof (dns_cache[h].addresses[0]));
+      dns_cache[h].limit_time = grub_get_time_ms () + 1000 * data.ttl;
+      if (!dns_cache[h].addresses || !dns_cache[h].name)
+	{
+	  grub_free (dns_cache[h].name);
+	  dns_cache[h].name = 0;
+	  grub_free (dns_cache[h].addresses);
+	  dns_cache[h].addresses = 0;
+	}
+      grub_memcpy (dns_cache[h].addresses, *data.addresses,
+		   *data.naddresses
+		   * sizeof (dns_cache[h].addresses[0]));
+    }
   if (*data.naddresses)
     return GRUB_ERR_NONE;
   if (data.dns_err)
-- 
2.5.0



             reply	other threads:[~2016-02-24 19:11 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-24 19:11 Josef Bacik [this message]
2016-02-26 10:22 ` [PATCH] dns: realloc address buffer after each packet Andrei Borzenkov
2016-02-26 13:52   ` Josef Bacik
2016-02-27 17:39     ` Andrei Borzenkov
2016-03-01 16:38       ` Josef Bacik
2016-03-01 19:22         ` Andrei Borzenkov
2016-03-01 19:30           ` Josef Bacik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1456341072-13356-1-git-send-email-jbacik@fb.com \
    --to=jbacik@fb.com \
    --cc=grub-devel@gnu.org \
    --cc=kernel-team@fb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).