qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Ed Swierk <eswierk@aristanetworks.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] slirp: Read host DNS config on demand
Date: Wed, 22 Jul 2009 10:57:21 -0700	[thread overview]
Message-ID: <1248285441.30567.12.camel@localhost.localdomain> (raw)

Currently the qemu user-mode networking stack reads the host DNS
configuration (/etc/resolv.conf or the Windows equivalent) only once
when qemu starts.  This causes name lookups in the guest to fail if the
host is moved to a different network from which the original DNS servers
are unreachable, a common occurrence when the host is a laptop.

This patch changes the slirp code to read the host DNS configuration on
demand, caching the results for 10 seconds to avoid unnecessary overhead
if name lookups occur in rapid succession.

Signed-off-by: Ed Swierk <eswierk@aristanetworks.com>

---
Index: qemu-kvm-0.10.5/slirp/ip_icmp.c
===================================================================
--- qemu-kvm-0.10.5.orig/slirp/ip_icmp.c
+++ qemu-kvm-0.10.5/slirp/ip_icmp.c
@@ -140,7 +140,8 @@ icmp_input(m, hlen)
 	/* It's an alias */
 	switch(ntohl(so->so_faddr.s_addr) & 0xff) {
 	case CTL_DNS:
-	  addr.sin_addr = dns_addr;
+	  if (get_dns_addr(&addr.sin_addr) < 0)
+	    addr.sin_addr = loopback_addr;
 	  break;
 	case CTL_ALIAS:
 	default:
Index: qemu-kvm-0.10.5/slirp/libslirp.h
===================================================================
--- qemu-kvm-0.10.5.orig/slirp/libslirp.h
+++ qemu-kvm-0.10.5/slirp/libslirp.h
@@ -5,6 +5,8 @@
 extern "C" {
 #endif
 
+int get_dns_addr(struct in_addr *pdns_addr);
+
 void slirp_init(int restrict, char *special_ip);
 
 void slirp_select_fill(int *pnfds,
Index: qemu-kvm-0.10.5/slirp/main.h
===================================================================
--- qemu-kvm-0.10.5.orig/slirp/main.h
+++ qemu-kvm-0.10.5/slirp/main.h
@@ -37,7 +37,6 @@ extern struct in_addr special_addr;
 extern struct in_addr alias_addr;
 extern struct in_addr our_addr;
 extern struct in_addr loopback_addr;
-extern struct in_addr dns_addr;
 extern char *username;
 extern char *socket_path;
 extern int towrite_max;
Index: qemu-kvm-0.10.5/slirp/slirp.c
===================================================================
--- qemu-kvm-0.10.5.orig/slirp/slirp.c
+++ qemu-kvm-0.10.5/slirp/slirp.c
@@ -28,8 +28,6 @@
 
 /* host address */
 struct in_addr our_addr;
-/* host dns address */
-struct in_addr dns_addr;
 /* host loopback address */
 struct in_addr loopback_addr;
 
@@ -61,9 +59,12 @@ fd_set *global_readfds, *global_writefds
 
 char slirp_hostname[33];
 
+struct in_addr dns_addr = { 0 };
+u_int dns_addr_time = 0;
+
 #ifdef _WIN32
 
-static int get_dns_addr(struct in_addr *pdns_addr)
+int get_dns_addr(struct in_addr *pdns_addr)
 {
     FIXED_INFO *FixedInfo=NULL;
     ULONG    BufLen;
@@ -71,6 +72,11 @@ static int get_dns_addr(struct in_addr *
     IP_ADDR_STRING *pIPAddr;
     struct in_addr tmp_addr;
 
+    if (dns_addr.s_addr != 0 && (curtime - dns_addr_time) < 10000) {
+        *pdns_addr = dns_addr;
+        return 0;
+    }
+
     FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
     BufLen = sizeof(FIXED_INFO);
 
@@ -94,6 +100,8 @@ static int get_dns_addr(struct in_addr *
     pIPAddr = &(FixedInfo->DnsServerList);
     inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
     *pdns_addr = tmp_addr;
+    dns_addr = tmp_addr;
+    dns_addr_time = curtime;
 #if 0
     printf( "DNS Servers:\n" );
     printf( "DNS Addr:%s\n", pIPAddr->IpAddress.String );
@@ -113,7 +121,7 @@ static int get_dns_addr(struct in_addr *
 
 #else
 
-static int get_dns_addr(struct in_addr *pdns_addr)
+int get_dns_addr(struct in_addr *pdns_addr)
 {
     char buff[512];
     char buff2[257];
@@ -121,6 +129,11 @@ static int get_dns_addr(struct in_addr *
     int found = 0;
     struct in_addr tmp_addr;
 
+    if (dns_addr.s_addr != 0 && (curtime - dns_addr_time) < 10000) {
+        *pdns_addr = dns_addr;
+        return 0;
+    }
+
     f = fopen("/etc/resolv.conf", "r");
     if (!f)
         return -1;
@@ -135,8 +148,11 @@ static int get_dns_addr(struct in_addr *
             if (tmp_addr.s_addr == loopback_addr.s_addr)
                 tmp_addr = our_addr;
             /* If it's the first one, set it to dns_addr */
-            if (!found)
+            if (!found) {
                 *pdns_addr = tmp_addr;
+                dns_addr = tmp_addr;
+                dns_addr_time = curtime;
+            }
 #ifdef DEBUG
             else
                 lprint(", ");
@@ -195,11 +211,6 @@ void slirp_init(int restrict, char *spec
     /* set default addresses */
     inet_aton("127.0.0.1", &loopback_addr);
 
-    if (get_dns_addr(&dns_addr) < 0) {
-        dns_addr = loopback_addr;
-        fprintf (stderr, "Warning: No DNS servers found\n");
-    }
-
     if (special_ip)
         slirp_special_ip = special_ip;
 
Index: qemu-kvm-0.10.5/slirp/socket.c
===================================================================
--- qemu-kvm-0.10.5.orig/slirp/socket.c
+++ qemu-kvm-0.10.5/slirp/socket.c
@@ -567,7 +567,8 @@ sosendto(so, m)
 	  /* It's an alias */
 	  switch(ntohl(so->so_faddr.s_addr) & 0xff) {
 	  case CTL_DNS:
-	    addr.sin_addr = dns_addr;
+	    if (get_dns_addr(&addr.sin_addr) < 0)
+	      addr.sin_addr = loopback_addr;
 	    break;
 	  case CTL_ALIAS:
 	  default:
Index: qemu-kvm-0.10.5/slirp/tcp_subr.c
===================================================================
--- qemu-kvm-0.10.5.orig/slirp/tcp_subr.c
+++ qemu-kvm-0.10.5/slirp/tcp_subr.c
@@ -398,7 +398,8 @@ int tcp_fconnect(so)
       /* It's an alias */
       switch(ntohl(so->so_faddr.s_addr) & 0xff) {
       case CTL_DNS:
-	addr.sin_addr = dns_addr;
+	if (get_dns_addr(&addr.sin_addr) < 0)
+	  addr.sin_addr = loopback_addr;
 	break;
       case CTL_ALIAS:
       default:

             reply	other threads:[~2009-07-22 17:57 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-22 17:57 Ed Swierk [this message]
2009-07-22 18:57 ` [Qemu-devel] Re: [PATCH] slirp: Read host DNS config on demand Jan Kiszka
2009-07-22 19:45   ` Ed Swierk
2009-07-22 20:04     ` Jan Kiszka
2009-07-22 23:27     ` malc
2009-07-23  6:47     ` Jan Kiszka
  -- strict thread matches above, loose matches on Subject: below --
2009-08-01  1:10 [Qemu-devel] " Ed Swierk
2009-08-02  7:43 ` Michael S. Tsirkin
2009-08-02  8:03   ` Jan Kiszka
2009-08-02  8:20     ` Michael S. Tsirkin
2009-08-03  2:08     ` Ed Swierk
2009-08-03 13:30       ` Jamie Lokier

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=1248285441.30567.12.camel@localhost.localdomain \
    --to=eswierk@aristanetworks.com \
    --cc=qemu-devel@nongnu.org \
    /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).