From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MTs5k-0005Re-3a for qemu-devel@nongnu.org; Thu, 23 Jul 2009 02:47:48 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MTs5e-0005QE-Rb for qemu-devel@nongnu.org; Thu, 23 Jul 2009 02:47:46 -0400 Received: from [199.232.76.173] (port=55088 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MTs5e-0005Q5-Cj for qemu-devel@nongnu.org; Thu, 23 Jul 2009 02:47:42 -0400 Received: from mx20.gnu.org ([199.232.41.8]:18717) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MTs5d-0006Wb-9X for qemu-devel@nongnu.org; Thu, 23 Jul 2009 02:47:41 -0400 Received: from fmmailgate02.web.de ([217.72.192.227]) by mx20.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MTs5b-0002RY-OT for qemu-devel@nongnu.org; Thu, 23 Jul 2009 02:47:40 -0400 Message-ID: <4A680789.6010909@web.de> Date: Thu, 23 Jul 2009 08:47:37 +0200 From: Jan Kiszka MIME-Version: 1.0 References: <1248285441.30567.12.camel@localhost.localdomain> <4A67610F.5090204@web.de> <1248291957.3841.10.camel@localhost.localdomain> In-Reply-To: <1248291957.3841.10.camel@localhost.localdomain> Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enig3B9458D472D14562DB9C9967" Sender: jan.kiszka@web.de Subject: [Qemu-devel] Re: [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: Ed Swierk Cc: qemu-devel@nongnu.org This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enig3B9458D472D14562DB9C9967 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: quoted-printable Ed Swierk wrote: > On Wed, 2009-07-22 at 20:57 +0200, Jan Kiszka wrote: >> Nice. I noticed this, too, and shortly thought about some possible >> fixes. Don't know why I dropped it again. Anyway, your approach looks >> straightforward. Please rebase over git head, and I will happily test >> and ack it! >=20 > FYI there are two other things that tend to break on laptops especially= : >=20 > - If the system clock jumps backwards, functions that rely on > gettimeofday() for computing a time interval get confused. > gettimeofday() should be replaced with clock_gettime(CLOCK_MONOTONIC). > Hopefully all Unixy platforms support it? >=20 > - Storing the address of some random host interface in our_addr is bad > for the same reason as storing the address of the DNS server. > Fortunately most references to our_addr are in dead code, and the > remaining ones are questionable. >=20 > Anyway, here's the updated patch for the DNS issue. >=20 > - >=20 > 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 server= s > are unreachable, a common occurrence when the host is a laptop. >=20 > This patch changes the slirp code to read the host DNS configuration on= > demand, caching the results for 10 seconds to avoid unnecessary overhea= d > if name lookups occur in rapid succession. >=20 > Signed-off-by: Ed Swierk Works as expected. Acked-by: Jan Kiszka >=20 > --- > diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c > index 95a4b39..751a8e2 100644 > --- a/slirp/ip_icmp.c > +++ b/slirp/ip_icmp.c > @@ -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 =3D=3D slirp->vnameserver_addr.s_addr) { > - addr.sin_addr =3D dns_addr; > + if (get_dns_addr(&addr.sin_addr) < 0) > + addr.sin_addr =3D loopback_addr; > } else { > addr.sin_addr =3D loopback_addr; > } > diff --git a/slirp/libslirp.h b/slirp/libslirp.h > index 3bcc392..4b00a97 100644 > --- a/slirp/libslirp.h > +++ b/slirp/libslirp.h > @@ -8,6 +8,8 @@ > struct Slirp; > typedef struct Slirp Slirp; > =20 > +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, > diff --git a/slirp/main.h b/slirp/main.h > index 28d92d8..e87b068 100644 > --- a/slirp/main.h > +++ b/slirp/main.h > @@ -32,7 +32,6 @@ extern u_int curtime; > extern fd_set *global_readfds, *global_writefds, *global_xfds; > 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; > diff --git a/slirp/slirp.c b/slirp/slirp.c > index 0ce62a3..4bc8a9d 100644 > --- a/slirp/slirp.c > +++ b/slirp/slirp.c > @@ -28,8 +28,6 @@ > =20 > /* host address */ > struct in_addr our_addr; > -/* host dns address */ > -struct in_addr dns_addr; > /* host loopback address */ > struct in_addr loopback_addr; > =20 > @@ -50,9 +48,12 @@ static int do_slowtimo; > TAILQ_HEAD(slirp_instances, Slirp) slirp_instances =3D > TAILQ_HEAD_INITIALIZER(slirp_instances); > =20 > +struct in_addr dns_addr =3D { 0 }; > +u_int dns_addr_time =3D 0; > + > #ifdef _WIN32 > =20 > -static int get_dns_addr(struct in_addr *pdns_addr) > +int get_dns_addr(struct in_addr *pdns_addr) > { > FIXED_INFO *FixedInfo=3DNULL; > ULONG BufLen; > @@ -60,6 +61,11 @@ static int get_dns_addr(struct in_addr *pdns_addr) > IP_ADDR_STRING *pIPAddr; > struct in_addr tmp_addr; > =20 > + if (dns_addr.s_addr !=3D 0 && (curtime - dns_addr_time) < 10000) {= > + *pdns_addr =3D dns_addr; > + return 0; > + } > + > FixedInfo =3D (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));= > BufLen =3D sizeof(FIXED_INFO); > =20 > @@ -83,6 +89,8 @@ static int get_dns_addr(struct in_addr *pdns_addr) > pIPAddr =3D &(FixedInfo->DnsServerList); > inet_aton(pIPAddr->IpAddress.String, &tmp_addr); > *pdns_addr =3D tmp_addr; > + dns_addr =3D tmp_addr; > + dns_addr_time =3D curtime; > if (FixedInfo) { > GlobalFree(FixedInfo); > FixedInfo =3D NULL; > @@ -97,7 +105,7 @@ static void winsock_cleanup(void) > =20 > #else > =20 > -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]; > @@ -105,6 +113,11 @@ static int get_dns_addr(struct in_addr *pdns_addr)= > int found =3D 0; > struct in_addr tmp_addr; > =20 > + if (dns_addr.s_addr !=3D 0 && (curtime - dns_addr_time) < 10000) {= > + *pdns_addr =3D dns_addr; > + return 0; > + } > + > f =3D fopen("/etc/resolv.conf", "r"); > if (!f) > return -1; > @@ -119,8 +132,11 @@ static int get_dns_addr(struct in_addr *pdns_addr)= > if (tmp_addr.s_addr =3D=3D loopback_addr.s_addr) > tmp_addr =3D our_addr; > /* If it's the first one, set it to dns_addr */ > - if (!found) > + if (!found) { > *pdns_addr =3D tmp_addr; > + dns_addr =3D tmp_addr; > + dns_addr_time =3D curtime; > + } > #ifdef DEBUG > else > lprint(", "); > @@ -176,11 +192,6 @@ static void slirp_init_once(void) > if (our_addr.s_addr =3D=3D 0) { > our_addr =3D loopback_addr; > } > - > - /* FIXME: This address may change during runtime */ > - if (get_dns_addr(&dns_addr) < 0) { > - dns_addr =3D loopback_addr; > - } > } > =20 > static void slirp_state_save(QEMUFile *f, void *opaque); > diff --git a/slirp/socket.c b/slirp/socket.c > index d8fbe89..207109c 100644 > --- a/slirp/socket.c > +++ b/slirp/socket.c > @@ -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 =3D=3D slirp->vnameserver_addr.s_addr) { > - addr.sin_addr =3D dns_addr; > + if (get_dns_addr(&addr.sin_addr) < 0) > + addr.sin_addr =3D loopback_addr; > } else { > addr.sin_addr =3D loopback_addr; > } > diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c > index 51b3834..0417345 100644 > --- a/slirp/tcp_subr.c > +++ b/slirp/tcp_subr.c > @@ -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 =3D=3D slirp->vnameserver_addr.s_addr) {= > - addr.sin_addr =3D dns_addr; > + if (get_dns_addr(&addr.sin_addr) < 0) > + addr.sin_addr =3D loopback_addr; > } else { > addr.sin_addr =3D loopback_addr; > } >=20 >=20 --------------enig3B9458D472D14562DB9C9967 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.9 (GNU/Linux) Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org iEYEARECAAYFAkpoB4kACgkQniDOoMHTA+mFBACeOF99pVDDMsr8oo6ym+qIP0rn eboAn12I+0k1zual/SdBRYc/a6bzmsrl =XCBt -----END PGP SIGNATURE----- --------------enig3B9458D472D14562DB9C9967--