Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libc/resolv Add a knote to keep track when resolv.conf g...



details:   https://anonhg.NetBSD.org/src/rev/6769610be5ff
branches:  trunk
changeset: 748439:6769610be5ff
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Oct 24 05:35:37 2009 +0000

description:
Add a knote to keep track when resolv.conf gets changed and re-initialize.
While here fix a memory leak when calling res_vinit with an already inited
res_state.

diffstat:

 lib/libc/resolv/res_data.c    |   7 ++-
 lib/libc/resolv/res_init.c    |  72 +++++++++++++++++++++++++++++++++++++-----
 lib/libc/resolv/res_private.h |   9 +++-
 lib/libc/resolv/res_send.c    |   6 ++-
 4 files changed, 76 insertions(+), 18 deletions(-)

diffs (243 lines):

diff -r 1fd98537eb2d -r 6769610be5ff lib/libc/resolv/res_data.c
--- a/lib/libc/resolv/res_data.c        Sat Oct 24 04:56:42 2009 +0000
+++ b/lib/libc/resolv/res_data.c        Sat Oct 24 05:35:37 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: res_data.c,v 1.13 2009/04/12 19:43:37 christos Exp $   */
+/*     $NetBSD: res_data.c,v 1.14 2009/10/24 05:35:37 christos Exp $   */
 
 /*
  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
@@ -22,7 +22,7 @@
 #ifdef notdef
 static const char rcsid[] = "Id: res_data.c,v 1.7 2008/12/11 09:59:00 marka Exp";
 #else
-__RCSID("$NetBSD: res_data.c,v 1.13 2009/04/12 19:43:37 christos Exp $");
+__RCSID("$NetBSD: res_data.c,v 1.14 2009/10/24 05:35:37 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -49,6 +49,8 @@
 
 #include "port_after.h"
 
+#include "res_private.h"
+
 #ifdef __weak_alias
 __weak_alias(res_init,_res_init)
 __weak_alias(res_mkquery,_res_mkquery)
@@ -108,7 +110,6 @@
 int
 res_init(void) {
        int rv;
-       extern int __res_vinit(res_state, int);
 #ifdef COMPAT__RES
        /*
         * Compatibility with program that were accessing _res directly
diff -r 1fd98537eb2d -r 6769610be5ff lib/libc/resolv/res_init.c
--- a/lib/libc/resolv/res_init.c        Sat Oct 24 04:56:42 2009 +0000
+++ b/lib/libc/resolv/res_init.c        Sat Oct 24 05:35:37 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: res_init.c,v 1.20 2009/04/20 14:42:12 christos Exp $   */
+/*     $NetBSD: res_init.c,v 1.21 2009/10/24 05:35:37 christos Exp $   */
 
 /*
  * Copyright (c) 1985, 1989, 1993
@@ -76,7 +76,7 @@
 static const char sccsid[] = "@(#)res_init.c   8.1 (Berkeley) 6/7/93";
 static const char rcsid[] = "Id: res_init.c,v 1.26 2008/12/11 09:59:00 marka Exp";
 #else
-__RCSID("$NetBSD: res_init.c,v 1.20 2009/04/20 14:42:12 christos Exp $");
+__RCSID("$NetBSD: res_init.c,v 1.21 2009/10/24 05:35:37 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -86,7 +86,9 @@
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/socket.h>
+#include <sys/stat.h>
 #include <sys/time.h>
+#include <sys/event.h>
 
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -97,6 +99,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include <netdb.h>
 
 #define HAVE_MD5
@@ -156,6 +159,9 @@
 # define isascii(c) (!(c & 0200))
 #endif
 
+static struct timespec __res_conf_time;
+static const struct timespec ts = { 0, 0 };
+
 /*
  * Resolver state default settings.
  */
@@ -183,8 +189,6 @@
  */
 int
 res_ninit(res_state statp) {
-       extern int __res_vinit(res_state, int);
-
        return (__res_vinit(statp, 0));
 }
 
@@ -208,17 +212,17 @@
 
        RES_SET_H_ERRNO(statp, 0);
 
+       if ((statp->options & RES_INIT) != 0U)
+               res_ndestroy(statp);
+
        if (!preinit) {
                statp->retrans = RES_TIMEOUT;
                statp->retry = RES_DFLRETRY;
                statp->options = RES_DEFAULT;
-               statp->_rnd = malloc(16);
-               res_rndinit(statp);
-               statp->id = res_nrandomid(statp);
        }
-
-       if ((statp->options & RES_INIT) != 0U)
-               res_ndestroy(statp);
+       statp->_rnd = malloc(16);
+       res_rndinit(statp);
+       statp->id = res_nrandomid(statp);
 
        memset(u, 0, sizeof(u));
 #ifdef USELOOPBACK
@@ -343,6 +347,9 @@
 
        nserv = 0;
        if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
+           struct stat st;
+           struct kevent kc;
+
            /* read the config file */
            while (fgets(buf, sizeof(buf), fp) != NULL) {
                /* skip comments */
@@ -490,7 +497,21 @@
 #ifdef RESOLVSORT
            statp->nsort = nsort;
 #endif
+           statp->_u._ext.ext->resfd = dup(fileno(fp));
            (void) fclose(fp);
+           if (fstat(statp->_u._ext.ext->resfd, &st) != -1)
+                   __res_conf_time = statp->_u._ext.ext->res_conf_time =
+                       st.st_mtimespec;
+           statp->_u._ext.ext->kq = kqueue();
+           (void)fcntl(statp->_u._ext.ext->kq, F_SETFD, FD_CLOEXEC);
+           (void)fcntl(statp->_u._ext.ext->resfd, F_SETFD, FD_CLOEXEC);
+           EV_SET(&kc, statp->_u._ext.ext->resfd, EVFILT_VNODE,
+               EV_ADD|EV_ENABLE|EV_CLEAR, NOTE_DELETE|NOTE_WRITE| NOTE_EXTEND|
+               NOTE_ATTRIB|NOTE_LINK|NOTE_RENAME|NOTE_REVOKE, 0, 0);
+           (void)kevent(statp->_u._ext.ext->kq, &kc, 1, NULL, 0, &ts);
+       } else {
+           statp->_u._ext.ext->kq = -1;
+           statp->_u._ext.ext->resfd = -1;
        }
 /*
  * Last chance to get a nameserver.  This should not normally
@@ -541,6 +562,33 @@
        return (statp->res_h_errno);
 }
 
+void
+__res_check(res_state statp)
+{
+       /*
+        * If the times are equal, then we check if there
+        * was a kevent related to resolv.conf and reload.
+        * If the times are not equal, then we don't bother
+        * to check the kevent, because another thread already
+        * did, loaded and changed the time.
+        */
+       if (timespeccmp(&statp->_u._ext.ext->res_conf_time,
+           &__res_conf_time, ==)) {
+               struct kevent ke;
+               if (statp->_u._ext.ext->kq == -1)
+                       return;
+
+               switch (kevent(statp->_u._ext.ext->kq, NULL, 0, &ke, 1, &ts)) {
+               case 0:
+               case -1:
+                       return;
+               default:
+                       break;
+               }
+       }
+       (void)__res_vinit(statp, 0);
+}
+
 static void
 res_setoptions(res_state statp, const char *options, const char *source)
 {
@@ -758,6 +806,10 @@
 res_ndestroy(res_state statp) {
        res_nclose(statp);
        if (statp->_u._ext.ext != NULL) {
+               if (statp->_u._ext.ext->kq != -1)
+                       (void)close(statp->_u._ext.ext->kq);
+               if (statp->_u._ext.ext->resfd != -1)
+                       (void)close(statp->_u._ext.ext->resfd);
                free(statp->_u._ext.ext);
                statp->_u._ext.ext = NULL;
        }
diff -r 1fd98537eb2d -r 6769610be5ff lib/libc/resolv/res_private.h
--- a/lib/libc/resolv/res_private.h     Sat Oct 24 04:56:42 2009 +0000
+++ b/lib/libc/resolv/res_private.h     Sat Oct 24 05:35:37 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: res_private.h,v 1.1.1.4 2009/04/12 16:35:48 christos Exp $     */
+/*     $NetBSD: res_private.h,v 1.2 2009/10/24 05:35:37 christos Exp $ */
 
 #ifndef res_private_h
 #define res_private_h
@@ -14,10 +14,13 @@
        } sort_list[MAXRESOLVSORT];
        char nsuffix[64];
        char nsuffix2[64];
+       struct timespec res_conf_time;
+       int kq, resfd;
 };
 
-extern int
-res_ourserver_p(const res_state statp, const struct sockaddr *sa);
+extern int res_ourserver_p(const res_state, const struct sockaddr *);
+extern int __res_vinit(res_state, int);
+extern void __res_check(res_state);
 
 #endif
 
diff -r 1fd98537eb2d -r 6769610be5ff lib/libc/resolv/res_send.c
--- a/lib/libc/resolv/res_send.c        Sat Oct 24 04:56:42 2009 +0000
+++ b/lib/libc/resolv/res_send.c        Sat Oct 24 05:35:37 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: res_send.c,v 1.18 2009/04/12 17:07:17 christos Exp $   */
+/*     $NetBSD: res_send.c,v 1.19 2009/10/24 05:35:37 christos Exp $   */
 
 /*
  * Portions Copyright (C) 2004-2009  Internet Systems Consortium, Inc. ("ISC")
@@ -93,7 +93,7 @@
 static const char sccsid[] = "@(#)res_send.c   8.1 (Berkeley) 6/4/93";
 static const char rcsid[] = "Id: res_send.c,v 1.22 2009/01/22 23:49:23 tbox Exp";
 #else
-__RCSID("$NetBSD: res_send.c,v 1.18 2009/04/12 17:07:17 christos Exp $");
+__RCSID("$NetBSD: res_send.c,v 1.19 2009/10/24 05:35:37 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -337,6 +337,8 @@
        highestFD = sysconf(_SC_OPEN_MAX) - 1;
 #endif
 
+       __res_check(statp);
+
        /* No name servers or res_init() failure */
        if (statp->nscount == 0 || EXT(statp).ext == NULL) {
                errno = ESRCH;



Home | Main Index | Thread Index | Old Index