]> git.ipfire.org Git - thirdparty/chrony.git/blob - nameserv_async.c
conf: rework allow/deny parser
[thirdparty/chrony.git] / nameserv_async.c
1 /*
2 chronyd/chronyc - Programs for keeping computer clocks accurate.
3
4 **********************************************************************
5 * Copyright (C) Miroslav Lichvar 2014
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 **********************************************************************
21
22 =======================================================================
23
24 Functions to asynchronously convert name to IP address
25
26 */
27
28 #include "config.h"
29 #include "sysincl.h"
30
31 #include "nameserv_async.h"
32 #include "logging.h"
33 #include "memory.h"
34 #include "privops.h"
35 #include "sched.h"
36 #include "util.h"
37
38 #ifdef USE_PTHREAD_ASYNCDNS
39 #include <pthread.h>
40
41 /* ================================================== */
42
43 struct DNS_Async_Instance {
44 const char *name;
45 DNS_Status status;
46 IPAddr addresses[DNS_MAX_ADDRESSES];
47 DNS_NameResolveHandler handler;
48 void *arg;
49
50 pthread_t thread;
51 int pipe[2];
52 };
53
54 static pthread_mutex_t privops_lock = PTHREAD_MUTEX_INITIALIZER;
55
56 /* ================================================== */
57
58 static void *
59 start_resolving(void *anything)
60 {
61 struct DNS_Async_Instance *inst = (struct DNS_Async_Instance *)anything;
62
63 pthread_mutex_lock(&privops_lock);
64 inst->status = PRV_Name2IPAddress(inst->name, inst->addresses, DNS_MAX_ADDRESSES);
65 pthread_mutex_unlock(&privops_lock);
66
67 /* Notify the main thread that the result is ready */
68 if (write(inst->pipe[1], "", 1) < 0)
69 ;
70
71 return NULL;
72 }
73
74 /* ================================================== */
75
76 static void
77 end_resolving(int fd, int event, void *anything)
78 {
79 struct DNS_Async_Instance *inst = (struct DNS_Async_Instance *)anything;
80 int i;
81
82 if (pthread_join(inst->thread, NULL)) {
83 LOG_FATAL("pthread_join() failed");
84 }
85
86 SCH_RemoveFileHandler(inst->pipe[0]);
87 close(inst->pipe[0]);
88 close(inst->pipe[1]);
89
90 for (i = 0; inst->status == DNS_Success && i < DNS_MAX_ADDRESSES &&
91 inst->addresses[i].family != IPADDR_UNSPEC; i++)
92 ;
93
94 (inst->handler)(inst->status, i, inst->addresses, inst->arg);
95
96 Free(inst);
97 }
98
99 /* ================================================== */
100
101 void
102 DNS_Name2IPAddressAsync(const char *name, DNS_NameResolveHandler handler, void *anything)
103 {
104 struct DNS_Async_Instance *inst;
105
106 inst = MallocNew(struct DNS_Async_Instance);
107 inst->name = name;
108 inst->handler = handler;
109 inst->arg = anything;
110 inst->status = DNS_Failure;
111
112 if (pipe(inst->pipe)) {
113 LOG_FATAL("pipe() failed");
114 }
115
116 UTI_FdSetCloexec(inst->pipe[0]);
117 UTI_FdSetCloexec(inst->pipe[1]);
118
119 if (pthread_create(&inst->thread, NULL, start_resolving, inst)) {
120 LOG_FATAL("pthread_create() failed");
121 }
122
123 SCH_AddFileHandler(inst->pipe[0], SCH_FILE_INPUT, end_resolving, inst);
124 }
125
126 /* ================================================== */
127
128 #else
129 #error
130 #endif