OpenDNSSEC-signer  2.0.2
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 
41 static const char* dnsh_str = "dnshandler";
42 
43 static 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  /* setup */
70  CHECKALLOC(dnsh->socklist = (socklist_type*) malloc(sizeof(socklist_type)));
71  if (!dnsh->socklist) {
72  ods_log_error("[%s] unable to create socklist: "
73  "allocator_alloc() failed", dnsh_str);
74  dnshandler_cleanup(dnsh);
75  return NULL;
76  }
77  dnsh->netio = netio_create();
78  if (!dnsh->netio) {
79  ods_log_error("[%s] unable to create dnshandler: "
80  "netio_create() failed", dnsh_str);
81  dnshandler_cleanup(dnsh);
82  return NULL;
83  }
84  dnsh->query = query_create();
85  if (!dnsh->query) {
86  ods_log_error("[%s] unable to create dnshandler: "
87  "query_create() failed", dnsh_str);
88  dnshandler_cleanup(dnsh);
89  return NULL;
90  }
91  dnsh->xfrhandler.fd = -1;
92  dnsh->xfrhandler.user_data = (void*) dnsh;
93  dnsh->xfrhandler.timeout = 0;
95  dnsh->xfrhandler.event_handler = dnshandler_handle_xfr;
96  return dnsh;
97 }
98 
99 
104 ods_status
106 {
107  ods_status status = ODS_STATUS_OK;
108  ods_log_assert(dnshandler);
109  status = sock_listen(dnshandler->socklist, dnshandler->interfaces);
110  if (status != ODS_STATUS_OK) {
111  ods_log_error("[%s] unable to start: sock_listen() "
112  "failed (%s)", dnsh_str, ods_status2str(status));
113  dnshandler->thread_id = 0;
114  }
115  return status;
116 }
117 
118 
123 void
125 {
126  size_t i = 0;
127  engine_type* engine = NULL;
128  netio_handler_type* tcp_accept_handlers = 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;
163  handler->event_handler = sock_handle_udp;
164  ods_log_debug("[%s] add udp network handler fd %u", dnsh_str,
165  (unsigned) handler->fd);
166  netio_add_handler(dnshandler->netio, handler);
167  }
168  /* tcp */
169  CHECKALLOC(tcp_accept_handlers = (netio_handler_type*) malloc(dnshandler->interfaces->count * sizeof(netio_handler_type)));
170  for (i=0; i < dnshandler->interfaces->count; i++) {
171  struct tcp_accept_data* data = NULL;
172  netio_handler_type* handler = NULL;
173  CHECKALLOC(data = (struct tcp_accept_data*) malloc(sizeof(struct tcp_accept_data)));
174  if (!data) {
175  ods_log_error("[%s] unable to start: allocator_alloc() "
176  "failed", dnsh_str);
177  dnshandler->thread_id = 0;
178  engine->need_to_exit = 1;
179  return;
180  }
181  data->engine = dnshandler->engine;
182  data->socket = &dnshandler->socklist->udp[i];
183  data->tcp_accept_handler_count = dnshandler->interfaces->count;
185  handler = &tcp_accept_handlers[i];
186  handler->fd = dnshandler->socklist->tcp[i].s;
187  handler->timeout = NULL;
188  handler->user_data = data;
189  handler->event_types = NETIO_EVENT_READ;
191  ods_log_debug("[%s] add tcp network handler fd %u", dnsh_str,
192  (unsigned) handler->fd);
193  netio_add_handler(dnshandler->netio, handler);
194  }
195  /* service */
196  while (dnshandler->need_to_exit == 0) {
197  ods_log_deeebug("[%s] netio dispatch", dnsh_str);
198  if (netio_dispatch(dnshandler->netio, NULL, NULL) == -1) {
199  if (errno != EINTR) {
200  ods_log_error("[%s] unable to dispatch netio: %s", dnsh_str,
201  strerror(errno));
202  break;
203  }
204  }
205  }
206  /* shutdown */
207  ods_log_debug("[%s] shutdown", dnsh_str);
208  free(tcp_accept_handlers);
209  /* for (i=0; i < dnshandler->interfaces->count; i++) {
210  if (dnshandler->socklist->udp[i].s != -1) {
211  close(dnshandler->socklist->udp[i].s);
212  freeaddrinfo((void*)dnshandler->socklist->udp[i].addr);
213  }
214  if (dnshandler->socklist->tcp[i].s != -1) {
215  close(dnshandler->socklist->tcp[i].s);
216  freeaddrinfo((void*)dnshandler->socklist->tcp[i].addr);
217  }
218  }*/
219 }
220 
221 
226 void
228 {
229  if (dnshandler && dnshandler->thread_id) {
230  ods_thread_kill(dnshandler->thread_id, SIGHUP);
231  }
232 }
233 
234 
239 void
240 dnshandler_fwd_notify(dnshandler_type* dnshandler, uint8_t* pkt, size_t len)
241 {
242  ssize_t nb = 0;
243  ods_log_assert(dnshandler);
244  ods_log_assert(pkt);
245  nb = send(dnshandler->xfrhandler.fd, (const void*) pkt, len, 0);
246  if (nb < 0) {
247  ods_log_error("[%s] unable to forward notify: send() failed (%s)",
248  dnsh_str, strerror(errno));
249  } else {
250  ods_log_debug("[%s] forwarded notify: %ld bytes sent", dnsh_str, (long)nb);
251  }
252 }
253 
254 
259 static void
260 dnshandler_handle_xfr(netio_type* ATTR_UNUSED(netio),
261  netio_handler_type* handler, netio_events_type event_types)
262 {
263  dnshandler_type* dnshandler = NULL;
264  uint8_t buf[MAX_PACKET_SIZE];
265  ssize_t received = 0;
266  if (!handler) {
267  return;
268  }
269  dnshandler = (dnshandler_type*) handler->user_data;
270  ods_log_assert(event_types & NETIO_EVENT_READ);
271  received = read(dnshandler->xfrhandler.fd, &buf, MAX_PACKET_SIZE);
272  ods_log_debug("[%s] read forwarded xfr packet: %d bytes received",
273  dnsh_str, (int) received);
274  if (received == -1) {
275  ods_log_error("[%s] unable to forward xfr packet: %s", dnsh_str,
276  strerror(errno));
277  }
278 }
279 
280 
285 void
287 {
288  size_t i = 0;
289  if (!dnshandler) {
290  return;
291  }
292  netio_cleanup(dnshandler->netio);
293  query_cleanup(dnshandler->query);
294 
295 
296  for (i = 0; i < dnshandler->interfaces->count; i++) {
297  if (dnshandler->socklist->udp[i].s != -1) {
298  close(dnshandler->socklist->udp[i].s);
299  freeaddrinfo((void*)dnshandler->socklist->udp[i].addr);
300  }
301  if (dnshandler->socklist->tcp[i].s != -1) {
302  close(dnshandler->socklist->tcp[i].s);
303  freeaddrinfo((void*)dnshandler->socklist->tcp[i].addr);
304  }
305  }
306  free(dnshandler->socklist);
307  free(dnshandler);
308 }
int s
Definition: sock.h:48
query_type * query_create(void)
Definition: query.c:48
socklist_type * socklist
Definition: dnshandler.h:55
query_type * query
Definition: dnshandler.h:57
void query_cleanup(query_type *q)
Definition: query.c:1094
ods_status dnshandler_listen(dnshandler_type *dnshandler)
Definition: dnshandler.c:105
listener_type * interfaces
Definition: dnshandler.h:54
query_type * query
Definition: sock.h:68
enum netio_events_enum netio_events_type
Definition: netio.h:76
engine_type * engine
Definition: dnshandler.h:53
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
sock_type udp[MAX_INTERFACES]
Definition: sock.h:58
void * user_data
Definition: netio.h:119
void netio_add_handler(netio_type *netio, netio_handler_type *handler)
Definition: netio.c:54
sock_type tcp[MAX_INTERFACES]
Definition: sock.h:57
void dnshandler_signal(dnshandler_type *dnshandler)
Definition: dnshandler.c:227
netio_handler_type * tcp_accept_handlers
Definition: sock.h:79
size_t count
Definition: listener.h:83
size_t tcp_accept_handler_count
Definition: sock.h:78
unsigned need_to_exit
Definition: dnshandler.h:59
netio_event_handler_type event_handler
Definition: netio.h:131
engine_type * engine
Definition: sock.h:76
ods_status sock_listen(socklist_type *sockets, listener_type *listener)
Definition: sock.c:292
#define MAX_PACKET_SIZE
Definition: buffer.h:49
sock_type * socket
Definition: sock.h:67
struct addrinfo * addr
Definition: sock.h:47
Definition: sock.h:65
netio_handler_type xfrhandler
Definition: dnshandler.h:58
sock_type * socket
Definition: sock.h:77
engine_type * engine
Definition: sock.h:66
netio_events_type event_types
Definition: netio.h:124
netio_type * netio_create()
Definition: netio.c:39
netio_type * netio
Definition: dnshandler.h:56
dnshandler_type * dnshandler_create(listener_type *interfaces)
Definition: dnshandler.c:51
int need_to_exit
Definition: engine.h:74
ods_thread_type thread_id
Definition: dnshandler.h:52
void dnshandler_start(dnshandler_type *dnshandler)
Definition: dnshandler.c:124
struct timespec * timeout
Definition: netio.h:115
void dnshandler_fwd_notify(dnshandler_type *dnshandler, uint8_t *pkt, size_t len)
Definition: dnshandler.c:240
int netio_dispatch(netio_type *netio, const struct timespec *timeout, const sigset_t *sigmask)
Definition: netio.c:193
void netio_cleanup(netio_type *netio)
Definition: netio.c:342
void dnshandler_cleanup(dnshandler_type *dnshandler)
Definition: dnshandler.c:286