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