version 1.15, 2008/06/21 23:37:53 |
version 1.15.12.1, 2011/01/09 20:43:29 |
|
|
#if defined(LIBC_SCCS) && !defined(lint) |
#if defined(LIBC_SCCS) && !defined(lint) |
#ifdef notdef |
#ifdef notdef |
static const char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; |
static const char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; |
static const char rcsid[] = "Id: res_init.c,v 1.23 2007/07/09 01:43:23 marka Exp"; |
static const char rcsid[] = "Id: res_init.c,v 1.26 2008/12/11 09:59:00 marka Exp"; |
#else |
#else |
__RCSID("$NetBSD$"); |
__RCSID("$NetBSD$"); |
#endif |
#endif |
Line 86 __RCSID("$NetBSD$"); |
|
Line 86 __RCSID("$NetBSD$"); |
|
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/param.h> |
#include <sys/param.h> |
#include <sys/socket.h> |
#include <sys/socket.h> |
|
#include <sys/stat.h> |
#include <sys/time.h> |
#include <sys/time.h> |
|
#include <sys/event.h> |
|
|
#include <netinet/in.h> |
#include <netinet/in.h> |
#include <arpa/inet.h> |
#include <arpa/inet.h> |
Line 97 __RCSID("$NetBSD$"); |
|
Line 99 __RCSID("$NetBSD$"); |
|
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
#include <unistd.h> |
#include <unistd.h> |
|
#include <fcntl.h> |
#include <netdb.h> |
#include <netdb.h> |
|
|
|
#define HAVE_MD5 |
|
#include <md5.h> |
|
|
|
#ifndef HAVE_MD5 |
|
# include "../dst/md5.h" |
|
#else |
|
# ifdef SOLARIS2 |
|
# include <sys/md5.h> |
|
# endif |
|
#endif |
|
#ifndef _MD5_H_ |
|
# define _MD5_H_ 1 /*%< make sure we do not include rsaref md5.h file */ |
|
#endif |
|
|
#include "port_after.h" |
#include "port_after.h" |
|
|
#if 0 |
#if 0 |
Line 142 static u_int32_t net_mask __P((struct in |
|
Line 159 static u_int32_t net_mask __P((struct in |
|
# define isascii(c) (!(c & 0200)) |
# define isascii(c) (!(c & 0200)) |
#endif |
#endif |
|
|
|
static struct timespec __res_conf_time; |
|
static const struct timespec ts = { 0, 0 }; |
|
|
/* |
/* |
* Resolver state default settings. |
* Resolver state default settings. |
*/ |
*/ |
Line 169 static u_int32_t net_mask __P((struct in |
|
Line 189 static u_int32_t net_mask __P((struct in |
|
*/ |
*/ |
int |
int |
res_ninit(res_state statp) { |
res_ninit(res_state statp) { |
extern int __res_vinit(res_state, int); |
|
|
|
return (__res_vinit(statp, 0)); |
return (__res_vinit(statp, 0)); |
} |
} |
|
|
Line 190 __res_vinit(res_state statp, int preinit |
|
Line 208 __res_vinit(res_state statp, int preinit |
|
#endif |
#endif |
int dots; |
int dots; |
union res_sockaddr_union u[2]; |
union res_sockaddr_union u[2]; |
|
|
int maxns = MAXNS; |
int maxns = MAXNS; |
|
|
RES_SET_H_ERRNO(statp, 0); |
RES_SET_H_ERRNO(statp, 0); |
|
|
|
if ((statp->options & RES_INIT) != 0U) |
|
res_ndestroy(statp); |
|
|
if (!preinit) { |
if (!preinit) { |
statp->retrans = RES_TIMEOUT; |
statp->retrans = RES_TIMEOUT; |
statp->retry = RES_DFLRETRY; |
statp->retry = RES_DFLRETRY; |
statp->options = RES_DEFAULT; |
statp->options = RES_DEFAULT; |
statp->id = res_randomid(); |
|
} |
} |
|
statp->_rnd = malloc(16); |
if ((statp->options & RES_INIT) != 0U) |
res_rndinit(statp); |
res_ndestroy(statp); |
statp->id = res_nrandomid(statp); |
|
|
memset(u, 0, sizeof(u)); |
memset(u, 0, sizeof(u)); |
#ifdef USELOOPBACK |
#ifdef USELOOPBACK |
Line 328 __res_vinit(res_state statp, int preinit |
|
Line 347 __res_vinit(res_state statp, int preinit |
|
|
|
nserv = 0; |
nserv = 0; |
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { |
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { |
|
struct stat st; |
|
struct kevent kc; |
|
|
/* read the config file */ |
/* read the config file */ |
while (fgets(buf, sizeof(buf), fp) != NULL) { |
while (fgets(buf, sizeof(buf), fp) != NULL) { |
/* skip comments */ |
/* skip comments */ |
Line 475 __res_vinit(res_state statp, int preinit |
|
Line 497 __res_vinit(res_state statp, int preinit |
|
#ifdef RESOLVSORT |
#ifdef RESOLVSORT |
statp->nsort = nsort; |
statp->nsort = nsort; |
#endif |
#endif |
|
statp->_u._ext.ext->resfd = dup(fileno(fp)); |
(void) fclose(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 |
* Last chance to get a nameserver. This should not normally |
Line 523 __res_vinit(res_state statp, int preinit |
|
Line 559 __res_vinit(res_state statp, int preinit |
|
if ((cp = getenv("RES_OPTIONS")) != NULL) |
if ((cp = getenv("RES_OPTIONS")) != NULL) |
res_setoptions(statp, cp, "env"); |
res_setoptions(statp, cp, "env"); |
statp->options |= RES_INIT; |
statp->options |= RES_INIT; |
|
|
return (statp->res_h_errno); |
return (statp->res_h_errno); |
} |
} |
|
|
|
int |
|
res_check(res_state statp, struct timespec *mtime) |
|
{ |
|
/* |
|
* 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) |
|
goto out; |
|
|
|
switch (kevent(statp->_u._ext.ext->kq, NULL, 0, &ke, 1, &ts)) { |
|
case 0: |
|
case -1: |
|
out: |
|
if (mtime) |
|
*mtime = __res_conf_time; |
|
return 0; |
|
default: |
|
break; |
|
} |
|
} |
|
(void)__res_vinit(statp, 0); |
|
if (mtime) |
|
*mtime = __res_conf_time; |
|
return 1; |
|
} |
|
|
static void |
static void |
res_setoptions(res_state statp, const char *options, const char *source) |
res_setoptions(res_state statp, const char *options, const char *source) |
{ |
{ |
Line 672 net_mask(in) /*!< XXX - should really u |
|
Line 740 net_mask(in) /*!< XXX - should really u |
|
} |
} |
#endif |
#endif |
|
|
|
static u_char srnd[16]; |
|
|
|
void |
|
res_rndinit(res_state statp) |
|
{ |
|
struct timeval now; |
|
u_int32_t u32; |
|
u_int16_t u16; |
|
u_char *rnd = statp->_rnd == NULL ? srnd : statp->_rnd; |
|
|
|
gettimeofday(&now, NULL); |
|
u32 = (u_int32_t)now.tv_sec; |
|
memcpy(rnd, &u32, 4); |
|
u32 = now.tv_usec; |
|
memcpy(rnd + 4, &u32, 4); |
|
u32 += (u_int32_t)now.tv_sec; |
|
memcpy(rnd + 8, &u32, 4); |
|
u16 = getpid(); |
|
memcpy(rnd + 12, &u16, 2); |
|
} |
|
|
u_int |
u_int |
res_randomid(void) { |
res_nrandomid(res_state statp) { |
struct timeval now; |
struct timeval now; |
|
u_int16_t u16; |
|
MD5_CTX ctx; |
|
u_char *rnd = statp->_rnd == NULL ? srnd : statp->_rnd; |
|
|
gettimeofday(&now, NULL); |
gettimeofday(&now, NULL); |
return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid())); |
u16 = (u_int16_t) (now.tv_sec ^ now.tv_usec); |
|
memcpy(rnd + 14, &u16, 2); |
|
#ifndef HAVE_MD5 |
|
MD5_Init(&ctx); |
|
MD5_Update(&ctx, rnd, 16); |
|
MD5_Final(rnd, &ctx); |
|
#else |
|
MD5Init(&ctx); |
|
MD5Update(&ctx, rnd, 16); |
|
MD5Final(rnd, &ctx); |
|
#endif |
|
memcpy(&u16, rnd + 14, 2); |
|
return ((u_int) u16); |
} |
} |
|
|
/*% |
/*% |
Line 707 res_nclose(res_state statp) { |
|
Line 811 res_nclose(res_state statp) { |
|
void |
void |
res_ndestroy(res_state statp) { |
res_ndestroy(res_state statp) { |
res_nclose(statp); |
res_nclose(statp); |
if (statp->_u._ext.ext != NULL) |
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); |
free(statp->_u._ext.ext); |
|
statp->_u._ext.ext = NULL; |
|
} |
|
if (statp->_rnd != NULL) { |
|
free(statp->_rnd); |
|
statp->_rnd = NULL; |
|
} |
statp->options &= ~RES_INIT; |
statp->options &= ~RES_INIT; |
statp->_u._ext.ext = NULL; |
|
} |
} |
|
|
const char * |
const char * |