Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/resolv/res_state.c
39530 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2006 The FreeBSD Project. All rights reserved.
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* 2. Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
* SUCH DAMAGE.
26
*/
27
28
#include <sys/types.h>
29
#include <sys/stat.h>
30
#include <sys/time.h>
31
#include <netinet/in.h>
32
#include <arpa/nameser.h>
33
#include <resolv.h>
34
#include <stdlib.h>
35
36
#include "namespace.h"
37
#include "reentrant.h"
38
#include "un-namespace.h"
39
40
#include "res_private.h"
41
42
#undef _res
43
44
struct __res_state _res;
45
46
static thread_key_t res_key;
47
static once_t res_init_once = ONCE_INITIALIZER;
48
static int res_thr_keycreated = 0;
49
50
static void
51
free_res(void *ptr)
52
{
53
res_state statp = ptr;
54
55
if (statp->_u._ext.ext != NULL)
56
res_ndestroy(statp);
57
free(statp);
58
}
59
60
static void
61
res_keycreate(void)
62
{
63
res_thr_keycreated = thr_keycreate(&res_key, free_res) == 0;
64
}
65
66
static res_state
67
res_check_reload(res_state statp)
68
{
69
struct timespec now;
70
struct stat sb;
71
struct __res_state_ext *ext;
72
73
if ((statp->options & RES_INIT) == 0) {
74
return (statp);
75
}
76
77
ext = statp->_u._ext.ext;
78
if (ext == NULL || ext->reload_period == 0) {
79
return (statp);
80
}
81
82
if (clock_gettime(CLOCK_MONOTONIC_FAST, &now) != 0 ||
83
(now.tv_sec - ext->conf_stat) < ext->reload_period) {
84
return (statp);
85
}
86
87
ext->conf_stat = now.tv_sec;
88
if (stat(_PATH_RESCONF, &sb) == 0 &&
89
(sb.st_mtim.tv_sec != ext->conf_mtim.tv_sec ||
90
sb.st_mtim.tv_nsec != ext->conf_mtim.tv_nsec)) {
91
statp->options &= ~RES_INIT;
92
}
93
94
return (statp);
95
}
96
97
res_state
98
__res_state(void)
99
{
100
res_state statp;
101
102
if (thr_main() != 0)
103
return res_check_reload(&_res);
104
105
if (thr_once(&res_init_once, res_keycreate) != 0 ||
106
!res_thr_keycreated)
107
return (&_res);
108
109
statp = thr_getspecific(res_key);
110
if (statp != NULL)
111
return res_check_reload(statp);
112
statp = calloc(1, sizeof(*statp));
113
if (statp == NULL)
114
return (&_res);
115
#ifdef __BIND_RES_TEXT
116
statp->options = RES_TIMEOUT; /* Motorola, et al. */
117
#endif
118
if (thr_setspecific(res_key, statp) == 0)
119
return (statp);
120
free(statp);
121
return (&_res);
122
}
123
124