OpenDNSSEC-signer 2.1.12
dnshandler.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 NLNet Labs. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
19 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
21 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
23 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 */
26
32#include "config.h"
33#include "daemon/dnshandler.h"
34#include "daemon/engine.h"
35#include "status.h"
36#include "wire/buffer.h"
37
38#include <errno.h>
39#include <string.h>
40
41static const char* dnsh_str = "dnshandler";
42
43static void dnshandler_handle_xfr(netio_type* netio,
44 netio_handler_type* handler, netio_events_type event_types);
45
52{
53 dnshandler_type* dnsh = NULL;
54 if (!interfaces || interfaces->count <= 0) {
55 return NULL;
56 }
57 CHECKALLOC(dnsh = (dnshandler_type*) malloc(sizeof(dnshandler_type)));
58 if (!dnsh) {
59 ods_log_error("[%s] unable to create dnshandler: "
60 "allocator_alloc() failed", dnsh_str);
61 return NULL;
62 }
63 dnsh->need_to_exit = 0;
64 dnsh->engine = NULL;
65 dnsh->interfaces = interfaces;
66 dnsh->socklist = NULL;
67 dnsh->netio = NULL;
68 dnsh->query = NULL;
69 dnsh->tcp_accept_handlers = NULL;
70 /* setup */
71 CHECKALLOC(dnsh->socklist = (socklist_type*) malloc(sizeof(socklist_type)));
72 if (!dnsh->socklist) {
73 ods_log_error("[%s] unable to create socklist: "
74 "allocator_alloc() failed", dnsh_str);
76 return NULL;
77 }
78 dnsh->netio = netio_create();
79 if (!dnsh->netio) {
80 ods_log_error("[%s] unable to create dnshandler: "
81 "netio_create() failed", dnsh_str);
83 return NULL;
84 }
85 dnsh->query = query_create();
86 if (!dnsh->query) {
87 ods_log_error("[%s] unable to create dnshandler: "
88 "query_create() failed", dnsh_str);
90 return NULL;
91 }
92 dnsh->xfrhandler.fd = -1;
93 dnsh->xfrhandler.user_data = (void*) dnsh;
94 dnsh->xfrhandler.timeout = 0;
96 dnsh->xfrhandler.event_handler = dnshandler_handle_xfr;
97 return dnsh;
98}
99
100
105ods_status
107{
108 ods_status status = ODS_STATUS_OK;
109 ods_log_assert(dnshandler);
110 status = sock_listen(dnshandler->socklist, dnshandler->interfaces);
111 if (status != ODS_STATUS_OK) {
112 ods_log_error("[%s] unable to start: sock_listen() "
113 "failed (%s)", dnsh_str, ods_status2str(status));
114 dnshandler->thread_id = 0;
115 }
116 return status;
117}
118
119
124void
126{
127 size_t i = 0;
128 engine_type* engine = NULL;
129
130 ods_log_assert(dnshandler);
131 ods_log_assert(dnshandler->engine);
132 ods_log_debug("[%s] start", dnsh_str);
133
134 engine = dnshandler->engine;
135 /* udp */
136 for (i=0; i < dnshandler->interfaces->count; i++) {
137 struct udp_data* data = NULL;
138 netio_handler_type* handler = NULL;
139 CHECKALLOC(data = (struct udp_data*) malloc(sizeof(struct udp_data)));
140 if (!data) {
141 ods_log_error("[%s] unable to start: allocator_alloc() "
142 "failed", dnsh_str);
143 dnshandler->thread_id = 0;
144 engine->need_to_exit = 1;
145 break;
146 }
147 data->query = dnshandler->query;
148 data->engine = dnshandler->engine;
149 data->socket = &dnshandler->socklist->udp[i];
150 CHECKALLOC(handler = (netio_handler_type*) malloc(sizeof(netio_handler_type)));
151 if (!handler) {
152 ods_log_error("[%s] unable to start: allocator_alloc() "
153 "failed", dnsh_str);
154 free(data);
155 dnshandler->thread_id = 0;
156 engine->need_to_exit = 1;
157 break;
158 }
159 handler->fd = dnshandler->socklist->udp[i].s;
160 handler->timeout = NULL;
161 handler->user_data = data;
162 handler->event_types = NETIO_EVENT_READ;
164 handler->free_handler = 1;
165 ods_log_debug("[%s] add udp network handler fd %u", dnsh_str,
166 (unsigned) handler->fd);
167 netio_add_handler(dnshandler->netio, handler);
168 }
169 /* tcp */
170 CHECKALLOC(dnshandler->tcp_accept_handlers = (netio_handler_type*) malloc(dnshandler->interfaces->count * sizeof(netio_handler_type)));
171 for (i=0; i < dnshandler->interfaces->count; i++) {
172 struct tcp_accept_data* data = NULL;
173 netio_handler_type* handler = NULL;
174 CHECKALLOC(data = (struct tcp_accept_data*) malloc(sizeof(struct tcp_accept_data)));
175 if (!data) {
176 ods_log_error("[%s] unable to start: allocator_alloc() "
177 "failed", dnsh_str);
178 dnshandler->thread_id = 0;
179 engine->need_to_exit = 1;
180 return;
181 }
182 data->engine = dnshandler->engine;
183 data->socket = &dnshandler->socklist->udp[i];
184 data->tcp_accept_handler_count = dnshandler->interfaces->count;
185 data->tcp_accept_handlers = dnshandler->tcp_accept_handlers;
186 handler = &dnshandler->tcp_accept_handlers[i];
187 handler->fd = dnshandler->socklist->tcp[i].s;
188 handler->timeout = NULL;
189 handler->user_data = data;
190 handler->event_types = NETIO_EVENT_READ;
192 handler->free_handler = 0;
193 ods_log_debug("[%s] add tcp network handler fd %u", dnsh_str,
194 (unsigned) handler->fd);
195 netio_add_handler(dnshandler->netio, handler);
196 }
197 /* service */
198 while (dnshandler->need_to_exit == 0) {
199 ods_log_deeebug("[%s] netio dispatch", dnsh_str);
200 if (netio_dispatch(dnshandler->netio, NULL, NULL) == -1) {
201 if (errno != EINTR) {
202 ods_log_error("[%s] unable to dispatch netio: %s", dnsh_str,
203 strerror(errno));
204 break;
205 }
206 }
207 }
208 /* shutdown */
209 ods_log_debug("[%s] shutdown", dnsh_str);
210}
211
212
217void
219{
220 if (dnshandler && dnshandler->thread_id) {
221 janitor_thread_signal(dnshandler->thread_id);
222 }
223}
224
225
230void
231dnshandler_fwd_notify(dnshandler_type* dnshandler, uint8_t* pkt, size_t len)
232{
233 ssize_t nb = 0;
234 ods_log_assert(dnshandler);
235 ods_log_assert(pkt);
236 nb = send(dnshandler->xfrhandler.fd, (const void*) pkt, len, 0);
237 if (nb < 0) {
238 ods_log_error("[%s] unable to forward notify: send() failed (%s)",
239 dnsh_str, strerror(errno));
240 } else {
241 ods_log_debug("[%s] forwarded notify: %ld bytes sent", dnsh_str, (long)nb);
242 }
243}
244
245
250static void
251dnshandler_handle_xfr(netio_type* ATTR_UNUSED(netio),
252 netio_handler_type* handler, netio_events_type event_types)
253{
254 dnshandler_type* dnshandler = NULL;
255 uint8_t buf[MAX_PACKET_SIZE];
256 ssize_t received = 0;
257 if (!handler) {
258 return;
259 }
260 dnshandler = (dnshandler_type*) handler->user_data;
261 ods_log_assert(event_types & NETIO_EVENT_READ);
262 received = read(dnshandler->xfrhandler.fd, &buf, MAX_PACKET_SIZE);
263 ods_log_debug("[%s] read forwarded xfr packet: %d bytes received",
264 dnsh_str, (int) received);
265 if (received == -1) {
266 ods_log_error("[%s] unable to forward xfr packet: %s", dnsh_str,
267 strerror(errno));
268 }
269}
270
271
276void
278{
279 size_t i = 0;
280 if (!dnshandler) {
281 return;
282 }
283 netio_cleanup(dnshandler->netio);
284 query_cleanup(dnshandler->query);
285
286
287 for (i = 0; i < dnshandler->interfaces->count; i++) {
288 if (dnshandler->tcp_accept_handlers)
289 free(dnshandler->tcp_accept_handlers[i].user_data);
290 if (dnshandler->socklist->udp[i].s != -1) {
291 close(dnshandler->socklist->udp[i].s);
292 freeaddrinfo((void*)dnshandler->socklist->udp[i].addr);
293 }
294 if (dnshandler->socklist->tcp[i].s != -1) {
295 close(dnshandler->socklist->tcp[i].s);
296 freeaddrinfo((void*)dnshandler->socklist->tcp[i].addr);
297 }
298 }
299 free(dnshandler->tcp_accept_handlers);
300 free(dnshandler->socklist);
301 free(dnshandler);
302}
#define MAX_PACKET_SIZE
Definition: buffer.h:49
void dnshandler_signal(dnshandler_type *dnshandler)
Definition: dnshandler.c:218
dnshandler_type * dnshandler_create(listener_type *interfaces)
Definition: dnshandler.c:51
ods_status dnshandler_listen(dnshandler_type *dnshandler)
Definition: dnshandler.c:106
void dnshandler_start(dnshandler_type *dnshandler)
Definition: dnshandler.c:125
void dnshandler_cleanup(dnshandler_type *dnshandler)
Definition: dnshandler.c:277
void dnshandler_fwd_notify(dnshandler_type *dnshandler, uint8_t *pkt, size_t len)
Definition: dnshandler.c:231
void netio_cleanup(netio_type *netio)
Definition: netio.c:336
int netio_dispatch(netio_type *netio, const struct timespec *timeout, const sigset_t *sigmask)
Definition: netio.c:187
void netio_add_handler(netio_type *netio, netio_handler_type *handler)
Definition: netio.c:53
netio_type * netio_create()
Definition: netio.c:39
enum netio_events_enum netio_events_type
Definition: netio.h:76
@ NETIO_EVENT_READ
Definition: netio.h:71
query_type * query_create(void)
Definition: query.c:48
void query_cleanup(query_type *q)
Definition: query.c:1098
void sock_handle_udp(netio_type *ATTR_UNUSED(netio), netio_handler_type *handler, netio_events_type event_types)
Definition: sock.c:388
void sock_handle_tcp_accept(netio_type *netio, netio_handler_type *handler, netio_events_type event_types)
Definition: sock.c:445
ods_status sock_listen(socklist_type *sockets, listener_type *listener)
Definition: sock.c:292
netio_handler_type xfrhandler
Definition: dnshandler.h:58
netio_handler_type * tcp_accept_handlers
Definition: dnshandler.h:60
janitor_thread_t thread_id
Definition: dnshandler.h:52
engine_type * engine
Definition: dnshandler.h:53
socklist_type * socklist
Definition: dnshandler.h:55
unsigned need_to_exit
Definition: dnshandler.h:59
listener_type * interfaces
Definition: dnshandler.h:54
netio_type * netio
Definition: dnshandler.h:56
query_type * query
Definition: dnshandler.h:57
int need_to_exit
Definition: engine.h:62
size_t count
Definition: listener.h:83
struct timespec * timeout
Definition: netio.h:115
netio_events_type event_types
Definition: netio.h:124
netio_event_handler_type event_handler
Definition: netio.h:131
void * user_data
Definition: netio.h:119
struct addrinfo * addr
Definition: sock.h:47
int s
Definition: sock.h:48
sock_type udp[MAX_INTERFACES]
Definition: sock.h:58
sock_type tcp[MAX_INTERFACES]
Definition: sock.h:57
netio_handler_type * tcp_accept_handlers
Definition: sock.h:79
sock_type * socket
Definition: sock.h:77
size_t tcp_accept_handler_count
Definition: sock.h:78
engine_type * engine
Definition: sock.h:76
Definition: sock.h:65
query_type * query
Definition: sock.h:68
engine_type * engine
Definition: sock.h:66
sock_type * socket
Definition: sock.h:67