From owner-freebsd-arch@FreeBSD.ORG Sat Aug 20 11:11:23 2005 Return-Path: X-Original-To: arch@FreeBSD.org Delivered-To: freebsd-arch@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E56AE16A41F for ; Sat, 20 Aug 2005 11:11:23 +0000 (GMT) (envelope-from ume@mahoroba.org) Received: from ameno.mahoroba.org (gw4.mahoroba.org [218.45.22.175]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4E81243D45 for ; Sat, 20 Aug 2005 11:11:22 +0000 (GMT) (envelope-from ume@mahoroba.org) Received: from kasuga.mahoroba.org (IDENT:9KyaRBe0nZrnDei3m94DOVna6+Mv+ACv1A/oUj+h3mJYF9JRBcah8RhBN+ZgOB2g@kasuga.mahoroba.org [IPv6:3ffe:501:185b:8010:20b:97ff:fe2e:b521]) (user=ume mech=CRAM-MD5 bits=0) by ameno.mahoroba.org (8.13.3/8.13.3) with ESMTP/inet6 id j7KBBGFB039643 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Sat, 20 Aug 2005 20:11:16 +0900 (JST) (envelope-from ume@mahoroba.org) Date: Sat, 20 Aug 2005 20:11:16 +0900 Message-ID: From: Hajimu UMEMOTO To: arch@FreeBSD.org User-Agent: Wanderlust/2.14.0 (Africa) SEMI/1.14.6 (Maruoka) FLIM/1.14.7 (=?ISO-8859-4?Q?Sanj=F2?=) APEL/10.6 Emacs/22.0.50 (i386-unknown-freebsd6.0) MULE/5.0 (SAKAKI) X-Operating-System: FreeBSD 6.0-BETA2 X-PGP-Key: http://www.imasy.or.jp/~ume/publickey.asc X-PGP-Fingerprint: 1F00 0B9E 2164 70FC 6DC5 BF5F 04E9 F086 BF90 71FE Organization: Internet Mutual Aid Society, YOKOHAMA MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII X-Greylist: Sender succeeded SMTP AUTH authentication, not delayed by milter-greylist-2.0 (ameno.mahoroba.org [IPv6:3ffe:501:185b:8010::1]); Sat, 20 Aug 2005 20:11:17 +0900 (JST) X-Virus-Scanned: by amavisd-new X-Virus-Status: Clean X-Spam-Status: No, score=-5.9 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 autolearn=ham version=3.0.4 X-Spam-Checker-Version: SpamAssassin 3.0.4 (2005-06-05) on ameno.mahoroba.org Cc: Subject: [CFR] reflect resolv.conf update to running application X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 20 Aug 2005 11:11:24 -0000 Hi, Our resolver reads resolv.conf once, and never re-read it. Recent OpenBSD changed to re-read resolv.conf when it is updated. I believe it is useful specially for mobile environment. So, I made a patch for our resolver. Please review it. Index: lib/libc/net/getaddrinfo.c diff -u -p lib/libc/net/getaddrinfo.c.orig lib/libc/net/getaddrinfo.c --- lib/libc/net/getaddrinfo.c.orig Sat May 21 22:46:37 2005 +++ lib/libc/net/getaddrinfo.c Sat May 21 23:20:27 2005 @@ -2443,7 +2443,7 @@ res_searchN(name, target) int got_nodata = 0, got_servfail = 0, tried_as_is = 0; char abuf[MAXDNAME]; - if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + if (_res_init() == -1) { h_errno = NETDB_INTERNAL; return (-1); } Index: lib/libc/net/gethostbydns.c diff -u -p lib/libc/net/gethostbydns.c.orig lib/libc/net/gethostbydns.c --- lib/libc/net/gethostbydns.c.orig Sat May 21 22:46:37 2005 +++ lib/libc/net/gethostbydns.c Sat May 21 23:20:27 2005 @@ -538,10 +538,6 @@ _dns_gethostbyaddr(void *rval, void *cb_ he = va_arg(ap, struct hostent *); hed = va_arg(ap, struct hostent_data *); - if ((_res.options & RES_INIT) == 0 && res_init() == -1) { - h_errno = NETDB_INTERNAL; - return NS_UNAVAIL; - } switch (af) { case AF_INET: (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", Index: lib/libc/net/gethostnamadr.c diff -u -p lib/libc/net/gethostnamadr.c.orig lib/libc/net/gethostnamadr.c --- lib/libc/net/gethostnamadr.c.orig Sat May 21 22:46:37 2005 +++ lib/libc/net/gethostnamadr.c Sat May 21 23:20:27 2005 @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD: src/lib/libc/net/get #include /* XXX hack for _res */ #include "un-namespace.h" #include "netdb_private.h" +#include "res_config.h" extern int _ht_gethostbyname(void *, void *, va_list); extern int _dns_gethostbyname(void *, void *, va_list); @@ -264,7 +265,7 @@ gethostbyaddr_r(const char *addr, int le { 0 } }; - if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + if (_res_init() == -1) { h_errno = NETDB_INTERNAL; return -1; } Index: lib/libc/net/getnetbydns.c diff -u -p lib/libc/net/getnetbydns.c.orig lib/libc/net/getnetbydns.c --- lib/libc/net/getnetbydns.c.orig Sat May 21 22:46:37 2005 +++ lib/libc/net/getnetbydns.c Sat May 21 23:20:27 2005 @@ -304,6 +304,10 @@ _dns_getnetbyaddr(void *rval, void *cb_d netbr[1], netbr[0]); break; } + if (_res_init() == -1) { + h_errno = NETDB_INTERNAL; + return NS_UNAVAIL; + } if ((buf = malloc(sizeof(*buf))) == NULL) { h_errno = NETDB_INTERNAL; return NS_NOTFOUND; Index: lib/libc/net/name6.c diff -u -p lib/libc/net/name6.c.orig lib/libc/net/name6.c --- lib/libc/net/name6.c.orig Sat May 21 22:46:38 2005 +++ lib/libc/net/name6.c Sat May 21 23:20:27 2005 @@ -121,6 +121,7 @@ __FBSDID("$FreeBSD: src/lib/libc/net/nam #include #include "un-namespace.h" #include "netdb_private.h" +#include "res_config.h" #ifndef _PATH_HOSTS #define _PATH_HOSTS "/etc/hosts" @@ -1810,11 +1811,9 @@ _dns_ghbyaddr(void *rval, void *cb_data, return NS_NOTFOUND; } - if ((_res.options & RES_INIT) == 0) { - if (res_init() < 0) { - *errp = h_errno; - return NS_UNAVAIL; - } + if (_res_init() < 0) { + *errp = h_errno; + return NS_UNAVAIL; } memset(&hbuf, 0, sizeof(hbuf)); hbuf.h_name = NULL; Index: lib/libc/net/res_config.h diff -u lib/libc/net/res_config.h.orig lib/libc/net/res_config.h --- lib/libc/net/res_config.h.orig Sat Mar 23 08:41:54 2002 +++ lib/libc/net/res_config.h Sat May 21 23:20:27 2005 @@ -8,3 +8,5 @@ #define MULTI_PTRS_ARE_ALIASES 1 /* fold multiple PTR records into aliases */ #define CHECK_SRVR_ADDR 1 /* confirm that the server requested sent the reply */ #define BIND_UPDATE 1 /* update support */ + +int _res_init(void); Index: lib/libc/net/res_init.c diff -u -p lib/libc/net/res_init.c.orig lib/libc/net/res_init.c --- lib/libc/net/res_init.c.orig Thu Feb 26 06:03:45 2004 +++ lib/libc/net/res_init.c Sat May 21 23:20:27 2005 @@ -78,11 +78,13 @@ __FBSDID("$FreeBSD: src/lib/libc/net/res #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -100,6 +102,7 @@ __FBSDID("$FreeBSD: src/lib/libc/net/res #undef h_errno extern int h_errno; +static void res_readconf(void); static void res_setoptions(char *, char *); #ifdef RESOLVSORT @@ -112,6 +115,18 @@ static u_int32_t net_mask(struct in_addr # define isascii(c) (!(c & 0200)) #endif +#define timespecclear(tvp) ((tvp)->tv_sec = (tvp)->tv_nsec = 0) +#define timespeccmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec == (uvp)->tv_sec) ? \ + ((tvp)->tv_nsec cmp (uvp)->tv_nsec) : \ + ((tvp)->tv_sec cmp (uvp)->tv_sec)) + +struct __res_conf_private { + struct timespec mtimespec; +}; + +static struct __res_conf_private *___res_conf_private(void); + /* * Check structure for failed per-thread allocations. */ @@ -119,6 +134,7 @@ static struct res_per_thread { struct __res_state res_state; struct __res_state_ext res_state_ext; struct __res_send_private res_send_private; + struct __res_conf_private res_conf_private; int h_errno; } _res_per_thread_bogus = { .res_send_private = { .s = -1 } }; /* socket */ @@ -146,21 +162,8 @@ static struct res_per_thread { int res_init() { - FILE *fp; struct __res_send_private *rsp; - char *cp, **pp; - int n; - char buf[MAXDNAME]; - int nserv = 0; /* number of nameserver records read from file */ - int haveenv = 0; - int havesearch = 0; -#ifdef RESOLVSORT - int nsort = 0; - char *net; -#endif -#ifndef RFC1535 - int dots; -#endif + char *cp; /* * If allocation of memory for this thread's resolver has failed, @@ -208,6 +211,37 @@ res_init() if (!_res.id) _res.id = res_randomid(); + _res.pfcode = 0; + res_readconf(); + + if (issetugid()) + _res.options |= RES_NOALIASES; + else if ((cp = getenv("RES_OPTIONS")) != NULL) + res_setoptions(cp, "env"); + _res.options |= RES_INIT; + return (0); +} + +static void +res_readconf() +{ + struct __res_conf_private *rcp; + FILE *fp; + char *cp, **pp; + int n; + char buf[MAXDNAME]; + int nserv = 0; /* number of nameserver records read from file */ + int haveenv = 0; + int havesearch = 0; +#ifdef RESOLVSORT + int nsort = 0; + char *net; +#endif +#ifndef RFC1535 + int dots; +#endif + struct stat sb; + #ifdef USELOOPBACK _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1); #else @@ -220,7 +254,6 @@ res_init() memcpy(&_res_ext.nsaddr, &_res.nsaddr, _res.nsaddr.sin_len); _res.nscount = 1; _res.ndots = 1; - _res.pfcode = 0; /* Allow user to override the local domain definition */ if (issetugid() == 0 && (cp = getenv("LOCALDOMAIN")) != NULL) { @@ -262,7 +295,10 @@ res_init() (line[sizeof(name) - 1] == ' ' || \ line[sizeof(name) - 1] == '\t')) + rcp = ___res_conf_private(); if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { + if (fstat(fileno(fp), &sb) == 0) + rcp->mtimespec = sb.st_mtimespec; /* read the config file */ while (fgets(buf, sizeof(buf), fp) != NULL) { /* skip comments */ @@ -396,11 +432,11 @@ res_init() if (inet_aton(net, &a)) { _res.sort_list[nsort].mask = a.s_addr; } else { - _res.sort_list[nsort].mask = + _res.sort_list[nsort].mask = net_mask(_res.sort_list[nsort].addr); } } else { - _res.sort_list[nsort].mask = + _res.sort_list[nsort].mask = net_mask(_res.sort_list[nsort].addr); } _res_ext.sort_list[nsort].af = AF_INET; @@ -465,13 +501,14 @@ res_init() continue; } } - if (nserv > 1) + if (nserv > 1) _res.nscount = nserv; #ifdef RESOLVSORT _res.nsort = nsort; #endif (void) fclose(fp); - } + } else + timespecclear(&rcp->mtimespec); if (_res.defdname[0] == 0 && gethostname(buf, sizeof(_res.defdname) - 1) == 0 && (cp = strchr(buf, '.')) != NULL) @@ -507,12 +544,27 @@ res_init() #endif #endif /* !RFC1535 */ } +} - if (issetugid()) - _res.options |= RES_NOALIASES; - else if ((cp = getenv("RES_OPTIONS")) != NULL) - res_setoptions(cp, "env"); - _res.options |= RES_INIT; +int +_res_init(void) +{ + struct __res_conf_private *rcp; + struct stat sb; + + if ((_res.options & RES_INIT) == 0) + return (res_init()); + + if (stat(_PATH_RESCONF, &sb) == -1) { + /* + * Lost the file, in chroot? + * Don' trash settings + */ + return (0); + } + rcp = ___res_conf_private(); + if (timespeccmp(&sb.st_mtimespec, &rcp->mtimespec, !=)) + res_readconf(); return (0); } @@ -629,6 +681,7 @@ struct __res_state _res; #endif struct __res_state_ext _res_ext; static struct __res_send_private _res_send_private = { .s = -1 }; /* socket */ +static struct __res_conf_private _res_conf_private; static thread_key_t res_key; static once_t res_init_once = ONCE_INITIALIZER; @@ -697,6 +750,14 @@ ___res_send_private(void) if (thr_main() != 0) return (&_res_send_private); return (&allocate_res()->res_send_private); +} + +struct __res_conf_private * +___res_conf_private(void) +{ + if (thr_main() != 0) + return (&_res_conf_private); + return (&allocate_res()->res_conf_private); } int * Index: lib/libc/net/res_query.c diff -u -p lib/libc/net/res_query.c.orig lib/libc/net/res_query.c --- lib/libc/net/res_query.c.orig Sat May 21 22:46:39 2005 +++ lib/libc/net/res_query.c Sat May 21 23:20:27 2005 @@ -200,7 +200,7 @@ res_search(name, class, type, answer, an int trailing_dot, ret, saved_herrno; int got_nodata = 0, got_servfail = 0, tried_as_is = 0; - if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + if (_res_init() == -1) { h_errno = NETDB_INTERNAL; return (-1); } Index: lib/libc/net/res_update.c diff -u -p lib/libc/net/res_update.c.orig lib/libc/net/res_update.c --- lib/libc/net/res_update.c.orig Mon Sep 16 01:51:09 2002 +++ lib/libc/net/res_update.c Sat May 21 23:20:27 2005 @@ -36,6 +36,8 @@ __FBSDID("$FreeBSD: src/lib/libc/net/res #include #include +#include "res_config.h" + /* * Separate a linked list of records into groups so that all records * in a group will belong to a single zone on the nameserver. @@ -84,7 +86,7 @@ res_update(ns_updrec *rrecp_in) { u_int16_t dlen, class, qclass, type, qtype; u_int32_t ttl; - if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + if (_res_init() == -1) { h_errno = NETDB_INTERNAL; return (-1); } Sincerely, -- Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan ume@mahoroba.org ume@{,jp.}FreeBSD.org http://www.imasy.org/~ume/