From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MTg4L-0007DR-Ev for qemu-devel@nongnu.org; Wed, 22 Jul 2009 13:57:33 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MTg4H-0007CP-S9 for qemu-devel@nongnu.org; Wed, 22 Jul 2009 13:57:33 -0400 Received: from [199.232.76.173] (port=48443 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MTg4H-0007CF-KS for qemu-devel@nongnu.org; Wed, 22 Jul 2009 13:57:29 -0400 Received: from mail-px0-f201.google.com ([209.85.216.201]:60016) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MTg4H-000898-0x for qemu-devel@nongnu.org; Wed, 22 Jul 2009 13:57:29 -0400 Received: by pxi39 with SMTP id 39so247625pxi.4 for ; Wed, 22 Jul 2009 10:57:27 -0700 (PDT) From: Ed Swierk Content-Type: text/plain Date: Wed, 22 Jul 2009 10:57:21 -0700 Message-Id: <1248285441.30567.12.camel@localhost.localdomain> Mime-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] [PATCH] slirp: Read host DNS config on demand List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org 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 --- 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: