slirp: Read host DNS config on demand (v2)
PATCH 1/1 slirp: Read host DNS config on demand (v2)
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 to avoid unnecessary overhead if name lookups occur in rapid succession.
v2: Cache the DNS server address for 1 second instead of 10 seconds; on non-Windows hosts, reread /etc/resolv.conf only if the file has been replaced or if its size or mtime has changed.
---
slirp/ip_icmp.c +2 -1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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; }