Skip to contentSkip to conversation

slirp: Read host DNS config on demand

PATCH New Ed Swierk 1 participant 1 message Aug 21, 2009

lore
Share & tools
lore

Ed Swierk

author
#0 lore raw

PATCH 2/2 slirp: Read host DNS config on demand

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 at most 1 second to avoid unnecessary overhead if name lookups occur in rapid succession. On non-Windows hosts, /etc/resolv.conf is re-read only if the file has been replaced or if its size or mtime has changed.

---

slirp/ip_icmp.c +2 -1
index 95a4b39..751a8e2 100644
@@ -127,7 +127,8 @@ icmp_input(struct mbuf *m, int hlen)
           slirp->vnetwork_addr.s_addr) {
 	/* It's an alias */
 	if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
-	  addr.sin_addr = dns_addr;
+	  if (get_dns_addr(&addr.sin_addr) < 0)
+	    addr.sin_addr = loopback_addr;
 	} else {
 	  addr.sin_addr = loopback_addr;
 	}
slirp/libslirp.h +2 -0
index 93087ed..67c70e3 100644
@@ -8,6 +8,8 @@
 struct Slirp;
 typedef struct Slirp Slirp;
 
+int get_dns_addr(struct in_addr *pdns_addr);
+
 Slirp *slirp_init(int restricted, struct in_addr vnetwork,
                   struct in_addr vnetmask, struct in_addr vhost,
                   const char *vhostname, const char *tftp_path,
slirp/main.h +0 -1
index 9f22fe1..8d09df9 100644
@@ -31,7 +31,6 @@ extern char *exec_shell;
 extern u_int curtime;
 extern fd_set *global_readfds, *global_writefds, *global_xfds;
 extern struct in_addr loopback_addr;
-extern struct in_addr dns_addr;
 extern char *username;
 extern char *socket_path;
 extern int towrite_max;
slirp/slirp.c +36 -10

97 lines not on this page · raw message

slirp/socket.c +2 -1
index d8fbe89..207109c 100644
@@ -552,7 +552,8 @@ sosendto(struct socket *so, struct mbuf *m)
 	    slirp->vnetwork_addr.s_addr) {
 	  /* It's an alias */
 	  if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
-	    addr.sin_addr = dns_addr;
+	    if (get_dns_addr(&addr.sin_addr) < 0)
+	      addr.sin_addr = loopback_addr;
 	  } else {
 	    addr.sin_addr = loopback_addr;
 	  }
slirp/tcp_subr.c +2 -1
index 51b3834..0417345 100644
@@ -340,7 +340,8 @@ int tcp_fconnect(struct socket *so)
         slirp->vnetwork_addr.s_addr) {
       /* It's an alias */
       if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
-	addr.sin_addr = dns_addr;
+	if (get_dns_addr(&addr.sin_addr) < 0)
+	  addr.sin_addr = loopback_addr;
       } else {
 	addr.sin_addr = loopback_addr;
       }