]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - util/netevent.c
Vendor import of Unbound 1.6.2.
[FreeBSD/FreeBSD.git] / util / netevent.c
1 /*
2  * util/netevent.c - event notification
3  *
4  * Copyright (c) 2007, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
7  * 
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  * 
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  * 
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  * 
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35
36 /**
37  * \file
38  *
39  * This file contains event notification functions.
40  */
41 #include "config.h"
42 #include "util/netevent.h"
43 #include "util/ub_event.h"
44 #include "util/log.h"
45 #include "util/net_help.h"
46 #include "util/fptr_wlist.h"
47 #include "sldns/pkthdr.h"
48 #include "sldns/sbuffer.h"
49 #include "dnstap/dnstap.h"
50 #include "dnscrypt/dnscrypt.h"
51 #ifdef HAVE_OPENSSL_SSL_H
52 #include <openssl/ssl.h>
53 #endif
54 #ifdef HAVE_OPENSSL_ERR_H
55 #include <openssl/err.h>
56 #endif
57
58 /* -------- Start of local definitions -------- */
59 /** if CMSG_ALIGN is not defined on this platform, a workaround */
60 #ifndef CMSG_ALIGN
61 #  ifdef __CMSG_ALIGN
62 #    define CMSG_ALIGN(n) __CMSG_ALIGN(n)
63 #  elif defined(CMSG_DATA_ALIGN)
64 #    define CMSG_ALIGN _CMSG_DATA_ALIGN
65 #  else
66 #    define CMSG_ALIGN(len) (((len)+sizeof(long)-1) & ~(sizeof(long)-1))
67 #  endif
68 #endif
69
70 /** if CMSG_LEN is not defined on this platform, a workaround */
71 #ifndef CMSG_LEN
72 #  define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr))+(len))
73 #endif
74
75 /** if CMSG_SPACE is not defined on this platform, a workaround */
76 #ifndef CMSG_SPACE
77 #  ifdef _CMSG_HDR_ALIGN
78 #    define CMSG_SPACE(l) (CMSG_ALIGN(l)+_CMSG_HDR_ALIGN(sizeof(struct cmsghdr)))
79 #  else
80 #    define CMSG_SPACE(l) (CMSG_ALIGN(l)+CMSG_ALIGN(sizeof(struct cmsghdr)))
81 #  endif
82 #endif
83
84 /** The TCP reading or writing query timeout in milliseconds */
85 #define TCP_QUERY_TIMEOUT 120000
86 /** The TCP timeout in msec for fast queries, above half are used */
87 #define TCP_QUERY_TIMEOUT_FAST 200
88
89 #ifndef NONBLOCKING_IS_BROKEN
90 /** number of UDP reads to perform per read indication from select */
91 #define NUM_UDP_PER_SELECT 100
92 #else
93 #define NUM_UDP_PER_SELECT 1
94 #endif
95
96 /**
97  * The internal event structure for keeping ub_event info for the event.
98  * Possibly other structures (list, tree) this is part of.
99  */
100 struct internal_event {
101         /** the comm base */
102         struct comm_base* base;
103         /** ub_event event type */
104         struct ub_event* ev;
105 };
106
107 /**
108  * Internal base structure, so that every thread has its own events.
109  */
110 struct internal_base {
111         /** ub_event event_base type. */
112         struct ub_event_base* base;
113         /** seconds time pointer points here */
114         time_t secs;
115         /** timeval with current time */
116         struct timeval now;
117         /** the event used for slow_accept timeouts */
118         struct ub_event* slow_accept;
119         /** true if slow_accept is enabled */
120         int slow_accept_enabled;
121 };
122
123 /**
124  * Internal timer structure, to store timer event in.
125  */
126 struct internal_timer {
127         /** the super struct from which derived */
128         struct comm_timer super;
129         /** the comm base */
130         struct comm_base* base;
131         /** ub_event event type */
132         struct ub_event* ev;
133         /** is timer enabled */
134         uint8_t enabled;
135 };
136
137 /**
138  * Internal signal structure, to store signal event in.
139  */
140 struct internal_signal {
141         /** ub_event event type */
142         struct ub_event* ev;
143         /** next in signal list */
144         struct internal_signal* next;
145 };
146
147 /** create a tcp handler with a parent */
148 static struct comm_point* comm_point_create_tcp_handler(
149         struct comm_base *base, struct comm_point* parent, size_t bufsize,
150         comm_point_callback_type* callback, void* callback_arg);
151
152 /* -------- End of local definitions -------- */
153
154 struct comm_base* 
155 comm_base_create(int sigs)
156 {
157         struct comm_base* b = (struct comm_base*)calloc(1,
158                 sizeof(struct comm_base));
159         const char *evnm="event", *evsys="", *evmethod="";
160
161         if(!b)
162                 return NULL;
163         b->eb = (struct internal_base*)calloc(1, sizeof(struct internal_base));
164         if(!b->eb) {
165                 free(b);
166                 return NULL;
167         }
168         b->eb->base = ub_default_event_base(sigs, &b->eb->secs, &b->eb->now);
169         if(!b->eb->base) {
170                 free(b->eb);
171                 free(b);
172                 return NULL;
173         }
174         ub_comm_base_now(b);
175         ub_get_event_sys(b->eb->base, &evnm, &evsys, &evmethod);
176         verbose(VERB_ALGO, "%s %s user %s method.", evnm, evsys, evmethod);
177         return b;
178 }
179
180 struct comm_base*
181 comm_base_create_event(struct ub_event_base* base)
182 {
183         struct comm_base* b = (struct comm_base*)calloc(1,
184                 sizeof(struct comm_base));
185         if(!b)
186                 return NULL;
187         b->eb = (struct internal_base*)calloc(1, sizeof(struct internal_base));
188         if(!b->eb) {
189                 free(b);
190                 return NULL;
191         }
192         b->eb->base = base;
193         ub_comm_base_now(b);
194         return b;
195 }
196
197 void 
198 comm_base_delete(struct comm_base* b)
199 {
200         if(!b)
201                 return;
202         if(b->eb->slow_accept_enabled) {
203                 if(ub_event_del(b->eb->slow_accept) != 0) {
204                         log_err("could not event_del slow_accept");
205                 }
206                 ub_event_free(b->eb->slow_accept);
207         }
208         ub_event_base_free(b->eb->base);
209         b->eb->base = NULL;
210         free(b->eb);
211         free(b);
212 }
213
214 void 
215 comm_base_delete_no_base(struct comm_base* b)
216 {
217         if(!b)
218                 return;
219         if(b->eb->slow_accept_enabled) {
220                 if(ub_event_del(b->eb->slow_accept) != 0) {
221                         log_err("could not event_del slow_accept");
222                 }
223                 ub_event_free(b->eb->slow_accept);
224         }
225         b->eb->base = NULL;
226         free(b->eb);
227         free(b);
228 }
229
230 void 
231 comm_base_timept(struct comm_base* b, time_t** tt, struct timeval** tv)
232 {
233         *tt = &b->eb->secs;
234         *tv = &b->eb->now;
235 }
236
237 void 
238 comm_base_dispatch(struct comm_base* b)
239 {
240         int retval;
241         retval = ub_event_base_dispatch(b->eb->base);
242         if(retval < 0) {
243                 fatal_exit("event_dispatch returned error %d, "
244                         "errno is %s", retval, strerror(errno));
245         }
246 }
247
248 void comm_base_exit(struct comm_base* b)
249 {
250         if(ub_event_base_loopexit(b->eb->base) != 0) {
251                 log_err("Could not loopexit");
252         }
253 }
254
255 void comm_base_set_slow_accept_handlers(struct comm_base* b,
256         void (*stop_acc)(void*), void (*start_acc)(void*), void* arg)
257 {
258         b->stop_accept = stop_acc;
259         b->start_accept = start_acc;
260         b->cb_arg = arg;
261 }
262
263 struct ub_event_base* comm_base_internal(struct comm_base* b)
264 {
265         return b->eb->base;
266 }
267
268 /** see if errno for udp has to be logged or not uses globals */
269 static int
270 udp_send_errno_needs_log(struct sockaddr* addr, socklen_t addrlen)
271 {
272         /* do not log transient errors (unless high verbosity) */
273 #if defined(ENETUNREACH) || defined(EHOSTDOWN) || defined(EHOSTUNREACH) || defined(ENETDOWN)
274         switch(errno) {
275 #  ifdef ENETUNREACH
276                 case ENETUNREACH:
277 #  endif
278 #  ifdef EHOSTDOWN
279                 case EHOSTDOWN:
280 #  endif
281 #  ifdef EHOSTUNREACH
282                 case EHOSTUNREACH:
283 #  endif
284 #  ifdef ENETDOWN
285                 case ENETDOWN:
286 #  endif
287                         if(verbosity < VERB_ALGO)
288                                 return 0;
289                 default:
290                         break;
291         }
292 #endif
293         /* permission denied is gotten for every send if the
294          * network is disconnected (on some OS), squelch it */
295         if( ((errno == EPERM)
296 #  ifdef EADDRNOTAVAIL
297                 /* 'Cannot assign requested address' also when disconnected */
298                 || (errno == EADDRNOTAVAIL)
299 #  endif
300                 ) && verbosity < VERB_DETAIL)
301                 return 0;
302         /* squelch errors where people deploy AAAA ::ffff:bla for
303          * authority servers, which we try for intranets. */
304         if(errno == EINVAL && addr_is_ip4mapped(
305                 (struct sockaddr_storage*)addr, addrlen) &&
306                 verbosity < VERB_DETAIL)
307                 return 0;
308         /* SO_BROADCAST sockopt can give access to 255.255.255.255,
309          * but a dns cache does not need it. */
310         if(errno == EACCES && addr_is_broadcast(
311                 (struct sockaddr_storage*)addr, addrlen) &&
312                 verbosity < VERB_DETAIL)
313                 return 0;
314         return 1;
315 }
316
317 int tcp_connect_errno_needs_log(struct sockaddr* addr, socklen_t addrlen)
318 {
319         return udp_send_errno_needs_log(addr, addrlen);
320 }
321
322 /* send a UDP reply */
323 int
324 comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
325         struct sockaddr* addr, socklen_t addrlen) 
326 {
327         ssize_t sent;
328         log_assert(c->fd != -1);
329 #ifdef UNBOUND_DEBUG
330         if(sldns_buffer_remaining(packet) == 0)
331                 log_err("error: send empty UDP packet");
332 #endif
333         log_assert(addr && addrlen > 0);
334         sent = sendto(c->fd, (void*)sldns_buffer_begin(packet), 
335                 sldns_buffer_remaining(packet), 0,
336                 addr, addrlen);
337         if(sent == -1) {
338                 /* try again and block, waiting for IO to complete,
339                  * we want to send the answer, and we will wait for
340                  * the ethernet interface buffer to have space. */
341 #ifndef USE_WINSOCK
342                 if(errno == EAGAIN || 
343 #  ifdef EWOULDBLOCK
344                         errno == EWOULDBLOCK ||
345 #  endif
346                         errno == ENOBUFS) {
347 #else
348                 if(WSAGetLastError() == WSAEINPROGRESS ||
349                         WSAGetLastError() == WSAENOBUFS ||
350                         WSAGetLastError() == WSAEWOULDBLOCK) {
351 #endif
352                         int e;
353                         fd_set_block(c->fd);
354                         sent = sendto(c->fd, (void*)sldns_buffer_begin(packet), 
355                                 sldns_buffer_remaining(packet), 0,
356                                 addr, addrlen);
357                         e = errno;
358                         fd_set_nonblock(c->fd);
359                         errno = e;
360                 }
361         }
362         if(sent == -1) {
363                 if(!udp_send_errno_needs_log(addr, addrlen))
364                         return 0;
365 #ifndef USE_WINSOCK
366                 verbose(VERB_OPS, "sendto failed: %s", strerror(errno));
367 #else
368                 verbose(VERB_OPS, "sendto failed: %s", 
369                         wsa_strerror(WSAGetLastError()));
370 #endif
371                 log_addr(VERB_OPS, "remote address is", 
372                         (struct sockaddr_storage*)addr, addrlen);
373                 return 0;
374         } else if((size_t)sent != sldns_buffer_remaining(packet)) {
375                 log_err("sent %d in place of %d bytes", 
376                         (int)sent, (int)sldns_buffer_remaining(packet));
377                 return 0;
378         }
379         return 1;
380 }
381
382 #if defined(AF_INET6) && defined(IPV6_PKTINFO) && (defined(HAVE_RECVMSG) || defined(HAVE_SENDMSG))
383 /** print debug ancillary info */
384 static void p_ancil(const char* str, struct comm_reply* r)
385 {
386         if(r->srctype != 4 && r->srctype != 6) {
387                 log_info("%s: unknown srctype %d", str, r->srctype);
388                 return;
389         }
390         if(r->srctype == 6) {
391                 char buf[1024];
392                 if(inet_ntop(AF_INET6, &r->pktinfo.v6info.ipi6_addr, 
393                         buf, (socklen_t)sizeof(buf)) == 0) {
394                         (void)strlcpy(buf, "(inet_ntop error)", sizeof(buf));
395                 }
396                 buf[sizeof(buf)-1]=0;
397                 log_info("%s: %s %d", str, buf, r->pktinfo.v6info.ipi6_ifindex);
398         } else if(r->srctype == 4) {
399 #ifdef IP_PKTINFO
400                 char buf1[1024], buf2[1024];
401                 if(inet_ntop(AF_INET, &r->pktinfo.v4info.ipi_addr, 
402                         buf1, (socklen_t)sizeof(buf1)) == 0) {
403                         (void)strlcpy(buf1, "(inet_ntop error)", sizeof(buf1));
404                 }
405                 buf1[sizeof(buf1)-1]=0;
406 #ifdef HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST
407                 if(inet_ntop(AF_INET, &r->pktinfo.v4info.ipi_spec_dst, 
408                         buf2, (socklen_t)sizeof(buf2)) == 0) {
409                         (void)strlcpy(buf2, "(inet_ntop error)", sizeof(buf2));
410                 }
411                 buf2[sizeof(buf2)-1]=0;
412 #else
413                 buf2[0]=0;
414 #endif
415                 log_info("%s: %d %s %s", str, r->pktinfo.v4info.ipi_ifindex,
416                         buf1, buf2);
417 #elif defined(IP_RECVDSTADDR)
418                 char buf1[1024];
419                 if(inet_ntop(AF_INET, &r->pktinfo.v4addr, 
420                         buf1, (socklen_t)sizeof(buf1)) == 0) {
421                         (void)strlcpy(buf1, "(inet_ntop error)", sizeof(buf1));
422                 }
423                 buf1[sizeof(buf1)-1]=0;
424                 log_info("%s: %s", str, buf1);
425 #endif /* IP_PKTINFO or PI_RECVDSTDADDR */
426         }
427 }
428 #endif /* AF_INET6 && IPV6_PKTINFO && HAVE_RECVMSG||HAVE_SENDMSG */
429
430 /** send a UDP reply over specified interface*/
431 static int
432 comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet,
433         struct sockaddr* addr, socklen_t addrlen, struct comm_reply* r) 
434 {
435 #if defined(AF_INET6) && defined(IPV6_PKTINFO) && defined(HAVE_SENDMSG)
436         ssize_t sent;
437         struct msghdr msg;
438         struct iovec iov[1];
439         char control[256];
440 #ifndef S_SPLINT_S
441         struct cmsghdr *cmsg;
442 #endif /* S_SPLINT_S */
443
444         log_assert(c->fd != -1);
445 #ifdef UNBOUND_DEBUG
446         if(sldns_buffer_remaining(packet) == 0)
447                 log_err("error: send empty UDP packet");
448 #endif
449         log_assert(addr && addrlen > 0);
450
451         msg.msg_name = addr;
452         msg.msg_namelen = addrlen;
453         iov[0].iov_base = sldns_buffer_begin(packet);
454         iov[0].iov_len = sldns_buffer_remaining(packet);
455         msg.msg_iov = iov;
456         msg.msg_iovlen = 1;
457         msg.msg_control = control;
458 #ifndef S_SPLINT_S
459         msg.msg_controllen = sizeof(control);
460 #endif /* S_SPLINT_S */
461         msg.msg_flags = 0;
462
463 #ifndef S_SPLINT_S
464         cmsg = CMSG_FIRSTHDR(&msg);
465         if(r->srctype == 4) {
466 #ifdef IP_PKTINFO
467                 void* cmsg_data;
468                 msg.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
469                 log_assert(msg.msg_controllen <= sizeof(control));
470                 cmsg->cmsg_level = IPPROTO_IP;
471                 cmsg->cmsg_type = IP_PKTINFO;
472                 memmove(CMSG_DATA(cmsg), &r->pktinfo.v4info,
473                         sizeof(struct in_pktinfo));
474                 /* unset the ifindex to not bypass the routing tables */
475                 cmsg_data = CMSG_DATA(cmsg);
476                 ((struct in_pktinfo *) cmsg_data)->ipi_ifindex = 0;
477                 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
478 #elif defined(IP_SENDSRCADDR)
479                 msg.msg_controllen = CMSG_SPACE(sizeof(struct in_addr));
480                 log_assert(msg.msg_controllen <= sizeof(control));
481                 cmsg->cmsg_level = IPPROTO_IP;
482                 cmsg->cmsg_type = IP_SENDSRCADDR;
483                 memmove(CMSG_DATA(cmsg), &r->pktinfo.v4addr,
484                         sizeof(struct in_addr));
485                 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
486 #else
487                 verbose(VERB_ALGO, "no IP_PKTINFO or IP_SENDSRCADDR");
488                 msg.msg_control = NULL;
489 #endif /* IP_PKTINFO or IP_SENDSRCADDR */
490         } else if(r->srctype == 6) {
491                 void* cmsg_data;
492                 msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
493                 log_assert(msg.msg_controllen <= sizeof(control));
494                 cmsg->cmsg_level = IPPROTO_IPV6;
495                 cmsg->cmsg_type = IPV6_PKTINFO;
496                 memmove(CMSG_DATA(cmsg), &r->pktinfo.v6info,
497                         sizeof(struct in6_pktinfo));
498                 /* unset the ifindex to not bypass the routing tables */
499                 cmsg_data = CMSG_DATA(cmsg);
500                 ((struct in6_pktinfo *) cmsg_data)->ipi6_ifindex = 0;
501                 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
502         } else {
503                 /* try to pass all 0 to use default route */
504                 msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
505                 log_assert(msg.msg_controllen <= sizeof(control));
506                 cmsg->cmsg_level = IPPROTO_IPV6;
507                 cmsg->cmsg_type = IPV6_PKTINFO;
508                 memset(CMSG_DATA(cmsg), 0, sizeof(struct in6_pktinfo));
509                 cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
510         }
511 #endif /* S_SPLINT_S */
512         if(verbosity >= VERB_ALGO)
513                 p_ancil("send_udp over interface", r);
514         sent = sendmsg(c->fd, &msg, 0);
515         if(sent == -1) {
516                 /* try again and block, waiting for IO to complete,
517                  * we want to send the answer, and we will wait for
518                  * the ethernet interface buffer to have space. */
519 #ifndef USE_WINSOCK
520                 if(errno == EAGAIN || 
521 #  ifdef EWOULDBLOCK
522                         errno == EWOULDBLOCK ||
523 #  endif
524                         errno == ENOBUFS) {
525 #else
526                 if(WSAGetLastError() == WSAEINPROGRESS ||
527                         WSAGetLastError() == WSAENOBUFS ||
528                         WSAGetLastError() == WSAEWOULDBLOCK) {
529 #endif
530                         int e;
531                         fd_set_block(c->fd);
532                         sent = sendmsg(c->fd, &msg, 0);
533                         e = errno;
534                         fd_set_nonblock(c->fd);
535                         errno = e;
536                 }
537         }
538         if(sent == -1) {
539                 if(!udp_send_errno_needs_log(addr, addrlen))
540                         return 0;
541                 verbose(VERB_OPS, "sendmsg failed: %s", strerror(errno));
542                 log_addr(VERB_OPS, "remote address is", 
543                         (struct sockaddr_storage*)addr, addrlen);
544 #ifdef __NetBSD__
545                 /* netbsd 7 has IP_PKTINFO for recv but not send */
546                 if(errno == EINVAL && r->srctype == 4)
547                         log_err("sendmsg: No support for sendmsg(IP_PKTINFO). "
548                                 "Please disable interface-automatic");
549 #endif
550                 return 0;
551         } else if((size_t)sent != sldns_buffer_remaining(packet)) {
552                 log_err("sent %d in place of %d bytes", 
553                         (int)sent, (int)sldns_buffer_remaining(packet));
554                 return 0;
555         }
556         return 1;
557 #else
558         (void)c;
559         (void)packet;
560         (void)addr;
561         (void)addrlen;
562         (void)r;
563         log_err("sendmsg: IPV6_PKTINFO not supported");
564         return 0;
565 #endif /* AF_INET6 && IPV6_PKTINFO && HAVE_SENDMSG */
566 }
567
568 void 
569 comm_point_udp_ancil_callback(int fd, short event, void* arg)
570 {
571 #if defined(AF_INET6) && defined(IPV6_PKTINFO) && defined(HAVE_RECVMSG)
572         struct comm_reply rep;
573         struct msghdr msg;
574         struct iovec iov[1];
575         ssize_t rcv;
576         char ancil[256];
577         int i;
578 #ifndef S_SPLINT_S
579         struct cmsghdr* cmsg;
580 #endif /* S_SPLINT_S */
581
582         rep.c = (struct comm_point*)arg;
583         log_assert(rep.c->type == comm_udp);
584
585         if(!(event&UB_EV_READ))
586                 return;
587         log_assert(rep.c && rep.c->buffer && rep.c->fd == fd);
588         ub_comm_base_now(rep.c->ev->base);
589         for(i=0; i<NUM_UDP_PER_SELECT; i++) {
590                 sldns_buffer_clear(rep.c->buffer);
591                 rep.addrlen = (socklen_t)sizeof(rep.addr);
592                 log_assert(fd != -1);
593                 log_assert(sldns_buffer_remaining(rep.c->buffer) > 0);
594                 msg.msg_name = &rep.addr;
595                 msg.msg_namelen = (socklen_t)sizeof(rep.addr);
596                 iov[0].iov_base = sldns_buffer_begin(rep.c->buffer);
597                 iov[0].iov_len = sldns_buffer_remaining(rep.c->buffer);
598                 msg.msg_iov = iov;
599                 msg.msg_iovlen = 1;
600                 msg.msg_control = ancil;
601 #ifndef S_SPLINT_S
602                 msg.msg_controllen = sizeof(ancil);
603 #endif /* S_SPLINT_S */
604                 msg.msg_flags = 0;
605                 rcv = recvmsg(fd, &msg, 0);
606                 if(rcv == -1) {
607                         if(errno != EAGAIN && errno != EINTR) {
608                                 log_err("recvmsg failed: %s", strerror(errno));
609                         }
610                         return;
611                 }
612                 rep.addrlen = msg.msg_namelen;
613                 sldns_buffer_skip(rep.c->buffer, rcv);
614                 sldns_buffer_flip(rep.c->buffer);
615                 rep.srctype = 0;
616 #ifndef S_SPLINT_S
617                 for(cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
618                         cmsg = CMSG_NXTHDR(&msg, cmsg)) {
619                         if( cmsg->cmsg_level == IPPROTO_IPV6 &&
620                                 cmsg->cmsg_type == IPV6_PKTINFO) {
621                                 rep.srctype = 6;
622                                 memmove(&rep.pktinfo.v6info, CMSG_DATA(cmsg),
623                                         sizeof(struct in6_pktinfo));
624                                 break;
625 #ifdef IP_PKTINFO
626                         } else if( cmsg->cmsg_level == IPPROTO_IP &&
627                                 cmsg->cmsg_type == IP_PKTINFO) {
628                                 rep.srctype = 4;
629                                 memmove(&rep.pktinfo.v4info, CMSG_DATA(cmsg),
630                                         sizeof(struct in_pktinfo));
631                                 break;
632 #elif defined(IP_RECVDSTADDR)
633                         } else if( cmsg->cmsg_level == IPPROTO_IP &&
634                                 cmsg->cmsg_type == IP_RECVDSTADDR) {
635                                 rep.srctype = 4;
636                                 memmove(&rep.pktinfo.v4addr, CMSG_DATA(cmsg),
637                                         sizeof(struct in_addr));
638                                 break;
639 #endif /* IP_PKTINFO or IP_RECVDSTADDR */
640                         }
641                 }
642                 if(verbosity >= VERB_ALGO)
643                         p_ancil("receive_udp on interface", &rep);
644 #endif /* S_SPLINT_S */
645                 fptr_ok(fptr_whitelist_comm_point(rep.c->callback));
646                 if((*rep.c->callback)(rep.c, rep.c->cb_arg, NETEVENT_NOERROR, &rep)) {
647                         /* send back immediate reply */
648                         (void)comm_point_send_udp_msg_if(rep.c, rep.c->buffer,
649                                 (struct sockaddr*)&rep.addr, rep.addrlen, &rep);
650                 }
651                 if(rep.c->fd == -1) /* commpoint closed */
652                         break;
653         }
654 #else
655         (void)fd;
656         (void)event;
657         (void)arg;
658         fatal_exit("recvmsg: No support for IPV6_PKTINFO; IP_PKTINFO or IP_RECVDSTADDR. "
659                 "Please disable interface-automatic");
660 #endif /* AF_INET6 && IPV6_PKTINFO && HAVE_RECVMSG */
661 }
662
663 void 
664 comm_point_udp_callback(int fd, short event, void* arg)
665 {
666         struct comm_reply rep;
667         ssize_t rcv;
668         int i;
669     struct sldns_buffer *buffer;
670
671         rep.c = (struct comm_point*)arg;
672         log_assert(rep.c->type == comm_udp);
673
674         if(!(event&UB_EV_READ))
675                 return;
676         log_assert(rep.c && rep.c->buffer && rep.c->fd == fd);
677         ub_comm_base_now(rep.c->ev->base);
678         for(i=0; i<NUM_UDP_PER_SELECT; i++) {
679                 sldns_buffer_clear(rep.c->buffer);
680                 rep.addrlen = (socklen_t)sizeof(rep.addr);
681                 log_assert(fd != -1);
682                 log_assert(sldns_buffer_remaining(rep.c->buffer) > 0);
683                 rcv = recvfrom(fd, (void*)sldns_buffer_begin(rep.c->buffer), 
684                         sldns_buffer_remaining(rep.c->buffer), 0, 
685                         (struct sockaddr*)&rep.addr, &rep.addrlen);
686                 if(rcv == -1) {
687 #ifndef USE_WINSOCK
688                         if(errno != EAGAIN && errno != EINTR)
689                                 log_err("recvfrom %d failed: %s", 
690                                         fd, strerror(errno));
691 #else
692                         if(WSAGetLastError() != WSAEINPROGRESS &&
693                                 WSAGetLastError() != WSAECONNRESET &&
694                                 WSAGetLastError()!= WSAEWOULDBLOCK)
695                                 log_err("recvfrom failed: %s",
696                                         wsa_strerror(WSAGetLastError()));
697 #endif
698                         return;
699                 }
700                 sldns_buffer_skip(rep.c->buffer, rcv);
701                 sldns_buffer_flip(rep.c->buffer);
702                 rep.srctype = 0;
703                 fptr_ok(fptr_whitelist_comm_point(rep.c->callback));
704                 if((*rep.c->callback)(rep.c, rep.c->cb_arg, NETEVENT_NOERROR, &rep)) {
705                         /* send back immediate reply */
706 #ifdef USE_DNSCRYPT
707             buffer = rep.c->dnscrypt_buffer;
708 #else
709             buffer = rep.c->buffer;
710 #endif
711                         (void)comm_point_send_udp_msg(rep.c, buffer,
712                                 (struct sockaddr*)&rep.addr, rep.addrlen);
713                 }
714                 if(rep.c->fd != fd) /* commpoint closed to -1 or reused for
715                 another UDP port. Note rep.c cannot be reused with TCP fd. */
716                         break;
717         }
718 }
719
720 /** Use a new tcp handler for new query fd, set to read query */
721 static void
722 setup_tcp_handler(struct comm_point* c, int fd, int cur, int max) 
723 {
724         log_assert(c->type == comm_tcp);
725         log_assert(c->fd == -1);
726         sldns_buffer_clear(c->buffer);
727 #ifdef USE_DNSCRYPT
728     if (c->dnscrypt)
729         sldns_buffer_clear(c->dnscrypt_buffer);
730 #endif
731         c->tcp_is_reading = 1;
732         c->tcp_byte_count = 0;
733         c->tcp_timeout_msec = TCP_QUERY_TIMEOUT;
734         /* if more than half the tcp handlers are in use, use a shorter
735          * timeout for this TCP connection, we need to make space for
736          * other connections to be able to get attention */
737         if(cur > max/2)
738                 c->tcp_timeout_msec = TCP_QUERY_TIMEOUT_FAST;
739         comm_point_start_listening(c, fd, c->tcp_timeout_msec);
740 }
741
742 void comm_base_handle_slow_accept(int ATTR_UNUSED(fd),
743         short ATTR_UNUSED(event), void* arg)
744 {
745         struct comm_base* b = (struct comm_base*)arg;
746         /* timeout for the slow accept, re-enable accepts again */
747         if(b->start_accept) {
748                 verbose(VERB_ALGO, "wait is over, slow accept disabled");
749                 fptr_ok(fptr_whitelist_start_accept(b->start_accept));
750                 (*b->start_accept)(b->cb_arg);
751                 b->eb->slow_accept_enabled = 0;
752         }
753 }
754
755 int comm_point_perform_accept(struct comm_point* c,
756         struct sockaddr_storage* addr, socklen_t* addrlen)
757 {
758         int new_fd;
759         *addrlen = (socklen_t)sizeof(*addr);
760         new_fd = accept(c->fd, (struct sockaddr*)addr, addrlen);
761         if(new_fd == -1) {
762 #ifndef USE_WINSOCK
763                 /* EINTR is signal interrupt. others are closed connection. */
764                 if(     errno == EINTR || errno == EAGAIN
765 #ifdef EWOULDBLOCK
766                         || errno == EWOULDBLOCK 
767 #endif
768 #ifdef ECONNABORTED
769                         || errno == ECONNABORTED 
770 #endif
771 #ifdef EPROTO
772                         || errno == EPROTO
773 #endif /* EPROTO */
774                         )
775                         return -1;
776 #if defined(ENFILE) && defined(EMFILE)
777                 if(errno == ENFILE || errno == EMFILE) {
778                         /* out of file descriptors, likely outside of our
779                          * control. stop accept() calls for some time */
780                         if(c->ev->base->stop_accept) {
781                                 struct comm_base* b = c->ev->base;
782                                 struct timeval tv;
783                                 verbose(VERB_ALGO, "out of file descriptors: "
784                                         "slow accept");
785                                 b->eb->slow_accept_enabled = 1;
786                                 fptr_ok(fptr_whitelist_stop_accept(
787                                         b->stop_accept));
788                                 (*b->stop_accept)(b->cb_arg);
789                                 /* set timeout, no mallocs */
790                                 tv.tv_sec = NETEVENT_SLOW_ACCEPT_TIME/1000;
791                                 tv.tv_usec = (NETEVENT_SLOW_ACCEPT_TIME%1000)*1000;
792                                 b->eb->slow_accept = ub_event_new(b->eb->base,
793                                         -1, UB_EV_TIMEOUT,
794                                         comm_base_handle_slow_accept, b);
795                                 if(b->eb->slow_accept == NULL) {
796                                         /* we do not want to log here, because
797                                          * that would spam the logfiles.
798                                          * error: "event_base_set failed." */
799                                 }
800                                 else if(ub_event_add(b->eb->slow_accept, &tv)
801                                         != 0) {
802                                         /* we do not want to log here,
803                                          * error: "event_add failed." */
804                                 }
805                         }
806                         return -1;
807                 }
808 #endif
809                 log_err_addr("accept failed", strerror(errno), addr, *addrlen);
810 #else /* USE_WINSOCK */
811                 if(WSAGetLastError() == WSAEINPROGRESS ||
812                         WSAGetLastError() == WSAECONNRESET)
813                         return -1;
814                 if(WSAGetLastError() == WSAEWOULDBLOCK) {
815                         ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
816                         return -1;
817                 }
818                 log_err_addr("accept failed", wsa_strerror(WSAGetLastError()),
819                         addr, *addrlen);
820 #endif
821                 return -1;
822         }
823         fd_set_nonblock(new_fd);
824         return new_fd;
825 }
826
827 #ifdef USE_WINSOCK
828 static long win_bio_cb(BIO *b, int oper, const char* ATTR_UNUSED(argp),
829         int ATTR_UNUSED(argi), long argl, long retvalue)
830 {
831         verbose(VERB_ALGO, "bio_cb %d, %s %s %s", oper,
832                 (oper&BIO_CB_RETURN)?"return":"before",
833                 (oper&BIO_CB_READ)?"read":((oper&BIO_CB_WRITE)?"write":"other"),
834                 WSAGetLastError()==WSAEWOULDBLOCK?"wsawb":"");
835         /* on windows, check if previous operation caused EWOULDBLOCK */
836         if( (oper == (BIO_CB_READ|BIO_CB_RETURN) && argl == 0) ||
837                 (oper == (BIO_CB_GETS|BIO_CB_RETURN) && argl == 0)) {
838                 if(WSAGetLastError() == WSAEWOULDBLOCK)
839                         ub_winsock_tcp_wouldblock((struct ub_event*)
840                                 BIO_get_callback_arg(b), UB_EV_READ);
841         }
842         if( (oper == (BIO_CB_WRITE|BIO_CB_RETURN) && argl == 0) ||
843                 (oper == (BIO_CB_PUTS|BIO_CB_RETURN) && argl == 0)) {
844                 if(WSAGetLastError() == WSAEWOULDBLOCK)
845                         ub_winsock_tcp_wouldblock((struct ub_event*)
846                                 BIO_get_callback_arg(b), UB_EV_WRITE);
847         }
848         /* return original return value */
849         return retvalue;
850 }
851
852 /** set win bio callbacks for nonblocking operations */
853 void
854 comm_point_tcp_win_bio_cb(struct comm_point* c, void* thessl)
855 {
856         SSL* ssl = (SSL*)thessl;
857         /* set them both just in case, but usually they are the same BIO */
858         BIO_set_callback(SSL_get_rbio(ssl), &win_bio_cb);
859         BIO_set_callback_arg(SSL_get_rbio(ssl), (char*)c->ev->ev);
860         BIO_set_callback(SSL_get_wbio(ssl), &win_bio_cb);
861         BIO_set_callback_arg(SSL_get_wbio(ssl), (char*)c->ev->ev);
862 }
863 #endif
864
865 void 
866 comm_point_tcp_accept_callback(int fd, short event, void* arg)
867 {
868         struct comm_point* c = (struct comm_point*)arg, *c_hdl;
869         int new_fd;
870         log_assert(c->type == comm_tcp_accept);
871         if(!(event & UB_EV_READ)) {
872                 log_info("ignoring tcp accept event %d", (int)event);
873                 return;
874         }
875         ub_comm_base_now(c->ev->base);
876         /* find free tcp handler. */
877         if(!c->tcp_free) {
878                 log_warn("accepted too many tcp, connections full");
879                 return;
880         }
881         /* accept incoming connection. */
882         c_hdl = c->tcp_free;
883         log_assert(fd != -1);
884         (void)fd;
885         new_fd = comm_point_perform_accept(c, &c_hdl->repinfo.addr,
886                 &c_hdl->repinfo.addrlen);
887         if(new_fd == -1)
888                 return;
889         if(c->ssl) {
890                 c_hdl->ssl = incoming_ssl_fd(c->ssl, new_fd);
891                 if(!c_hdl->ssl) {
892                         c_hdl->fd = new_fd;
893                         comm_point_close(c_hdl);
894                         return;
895                 }
896                 c_hdl->ssl_shake_state = comm_ssl_shake_read;
897 #ifdef USE_WINSOCK
898                 comm_point_tcp_win_bio_cb(c_hdl, c_hdl->ssl);
899 #endif
900         }
901
902         /* grab the tcp handler buffers */
903         c->cur_tcp_count++;
904         c->tcp_free = c_hdl->tcp_free;
905         if(!c->tcp_free) {
906                 /* stop accepting incoming queries for now. */
907                 comm_point_stop_listening(c);
908         }
909         setup_tcp_handler(c_hdl, new_fd, c->cur_tcp_count, c->max_tcp_count);
910 }
911
912 /** Make tcp handler free for next assignment */
913 static void
914 reclaim_tcp_handler(struct comm_point* c)
915 {
916         log_assert(c->type == comm_tcp);
917         if(c->ssl) {
918 #ifdef HAVE_SSL
919                 SSL_shutdown(c->ssl);
920                 SSL_free(c->ssl);
921                 c->ssl = NULL;
922 #endif
923         }
924         comm_point_close(c);
925         if(c->tcp_parent) {
926                 c->tcp_parent->cur_tcp_count--;
927                 c->tcp_free = c->tcp_parent->tcp_free;
928                 c->tcp_parent->tcp_free = c;
929                 if(!c->tcp_free) {
930                         /* re-enable listening on accept socket */
931                         comm_point_start_listening(c->tcp_parent, -1, -1);
932                 }
933         }
934 }
935
936 /** do the callback when writing is done */
937 static void
938 tcp_callback_writer(struct comm_point* c)
939 {
940         log_assert(c->type == comm_tcp);
941         sldns_buffer_clear(c->buffer);
942         if(c->tcp_do_toggle_rw)
943                 c->tcp_is_reading = 1;
944         c->tcp_byte_count = 0;
945         /* switch from listening(write) to listening(read) */
946         comm_point_stop_listening(c);
947         comm_point_start_listening(c, -1, -1);
948 }
949
950 /** do the callback when reading is done */
951 static void
952 tcp_callback_reader(struct comm_point* c)
953 {
954         log_assert(c->type == comm_tcp || c->type == comm_local);
955         sldns_buffer_flip(c->buffer);
956         if(c->tcp_do_toggle_rw)
957                 c->tcp_is_reading = 0;
958         c->tcp_byte_count = 0;
959         if(c->type == comm_tcp)
960                 comm_point_stop_listening(c);
961         fptr_ok(fptr_whitelist_comm_point(c->callback));
962         if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &c->repinfo) ) {
963                 comm_point_start_listening(c, -1, c->tcp_timeout_msec);
964         }
965 }
966
967 /** continue ssl handshake */
968 #ifdef HAVE_SSL
969 static int
970 ssl_handshake(struct comm_point* c)
971 {
972         int r;
973         if(c->ssl_shake_state == comm_ssl_shake_hs_read) {
974                 /* read condition satisfied back to writing */
975                 comm_point_listen_for_rw(c, 1, 1);
976                 c->ssl_shake_state = comm_ssl_shake_none;
977                 return 1;
978         }
979         if(c->ssl_shake_state == comm_ssl_shake_hs_write) {
980                 /* write condition satisfied, back to reading */
981                 comm_point_listen_for_rw(c, 1, 0);
982                 c->ssl_shake_state = comm_ssl_shake_none;
983                 return 1;
984         }
985
986         ERR_clear_error();
987         r = SSL_do_handshake(c->ssl);
988         if(r != 1) {
989                 int want = SSL_get_error(c->ssl, r);
990                 if(want == SSL_ERROR_WANT_READ) {
991                         if(c->ssl_shake_state == comm_ssl_shake_read)
992                                 return 1;
993                         c->ssl_shake_state = comm_ssl_shake_read;
994                         comm_point_listen_for_rw(c, 1, 0);
995                         return 1;
996                 } else if(want == SSL_ERROR_WANT_WRITE) {
997                         if(c->ssl_shake_state == comm_ssl_shake_write)
998                                 return 1;
999                         c->ssl_shake_state = comm_ssl_shake_write;
1000                         comm_point_listen_for_rw(c, 0, 1);
1001                         return 1;
1002                 } else if(r == 0) {
1003                         return 0; /* closed */
1004                 } else if(want == SSL_ERROR_SYSCALL) {
1005                         /* SYSCALL and errno==0 means closed uncleanly */
1006                         if(errno != 0)
1007                                 log_err("SSL_handshake syscall: %s",
1008                                         strerror(errno));
1009                         return 0;
1010                 } else {
1011                         log_crypto_err("ssl handshake failed");
1012                         log_addr(1, "ssl handshake failed", &c->repinfo.addr,
1013                                 c->repinfo.addrlen);
1014                         return 0;
1015                 }
1016         }
1017         /* this is where peer verification could take place */
1018         log_addr(VERB_ALGO, "SSL DNS connection", &c->repinfo.addr,
1019                 c->repinfo.addrlen);
1020
1021         /* setup listen rw correctly */
1022         if(c->tcp_is_reading) {
1023                 if(c->ssl_shake_state != comm_ssl_shake_read)
1024                         comm_point_listen_for_rw(c, 1, 0);
1025         } else {
1026                 comm_point_listen_for_rw(c, 1, 1);
1027         }
1028         c->ssl_shake_state = comm_ssl_shake_none;
1029         return 1;
1030 }
1031 #endif /* HAVE_SSL */
1032
1033 /** ssl read callback on TCP */
1034 static int
1035 ssl_handle_read(struct comm_point* c)
1036 {
1037 #ifdef HAVE_SSL
1038         int r;
1039         if(c->ssl_shake_state != comm_ssl_shake_none) {
1040                 if(!ssl_handshake(c))
1041                         return 0;
1042                 if(c->ssl_shake_state != comm_ssl_shake_none)
1043                         return 1;
1044         }
1045         if(c->tcp_byte_count < sizeof(uint16_t)) {
1046                 /* read length bytes */
1047                 ERR_clear_error();
1048                 if((r=SSL_read(c->ssl, (void*)sldns_buffer_at(c->buffer,
1049                         c->tcp_byte_count), (int)(sizeof(uint16_t) -
1050                         c->tcp_byte_count))) <= 0) {
1051                         int want = SSL_get_error(c->ssl, r);
1052                         if(want == SSL_ERROR_ZERO_RETURN) {
1053                                 return 0; /* shutdown, closed */
1054                         } else if(want == SSL_ERROR_WANT_READ) {
1055                                 return 1; /* read more later */
1056                         } else if(want == SSL_ERROR_WANT_WRITE) {
1057                                 c->ssl_shake_state = comm_ssl_shake_hs_write;
1058                                 comm_point_listen_for_rw(c, 0, 1);
1059                                 return 1;
1060                         } else if(want == SSL_ERROR_SYSCALL) {
1061                                 if(errno != 0)
1062                                         log_err("SSL_read syscall: %s",
1063                                                 strerror(errno));
1064                                 return 0;
1065                         }
1066                         log_crypto_err("could not SSL_read");
1067                         return 0;
1068                 }
1069                 c->tcp_byte_count += r;
1070                 if(c->tcp_byte_count != sizeof(uint16_t))
1071                         return 1;
1072                 if(sldns_buffer_read_u16_at(c->buffer, 0) >
1073                         sldns_buffer_capacity(c->buffer)) {
1074                         verbose(VERB_QUERY, "ssl: dropped larger than buffer");
1075                         return 0;
1076                 }
1077                 sldns_buffer_set_limit(c->buffer,
1078                         sldns_buffer_read_u16_at(c->buffer, 0));
1079                 if(sldns_buffer_limit(c->buffer) < LDNS_HEADER_SIZE) {
1080                         verbose(VERB_QUERY, "ssl: dropped bogus too short.");
1081                         return 0;
1082                 }
1083                 verbose(VERB_ALGO, "Reading ssl tcp query of length %d",
1084                         (int)sldns_buffer_limit(c->buffer));
1085         }
1086         log_assert(sldns_buffer_remaining(c->buffer) > 0);
1087         ERR_clear_error();
1088         r = SSL_read(c->ssl, (void*)sldns_buffer_current(c->buffer),
1089                 (int)sldns_buffer_remaining(c->buffer));
1090         if(r <= 0) {
1091                 int want = SSL_get_error(c->ssl, r);
1092                 if(want == SSL_ERROR_ZERO_RETURN) {
1093                         return 0; /* shutdown, closed */
1094                 } else if(want == SSL_ERROR_WANT_READ) {
1095                         return 1; /* read more later */
1096                 } else if(want == SSL_ERROR_WANT_WRITE) {
1097                         c->ssl_shake_state = comm_ssl_shake_hs_write;
1098                         comm_point_listen_for_rw(c, 0, 1);
1099                         return 1;
1100                 } else if(want == SSL_ERROR_SYSCALL) {
1101                         if(errno != 0)
1102                                 log_err("SSL_read syscall: %s",
1103                                         strerror(errno));
1104                         return 0;
1105                 }
1106                 log_crypto_err("could not SSL_read");
1107                 return 0;
1108         }
1109         sldns_buffer_skip(c->buffer, (ssize_t)r);
1110         if(sldns_buffer_remaining(c->buffer) <= 0) {
1111                 tcp_callback_reader(c);
1112         }
1113         return 1;
1114 #else
1115         (void)c;
1116         return 0;
1117 #endif /* HAVE_SSL */
1118 }
1119
1120 /** ssl write callback on TCP */
1121 static int
1122 ssl_handle_write(struct comm_point* c)
1123 {
1124 #ifdef HAVE_SSL
1125         int r;
1126         if(c->ssl_shake_state != comm_ssl_shake_none) {
1127                 if(!ssl_handshake(c))
1128                         return 0;
1129                 if(c->ssl_shake_state != comm_ssl_shake_none)
1130                         return 1;
1131         }
1132         /* ignore return, if fails we may simply block */
1133         (void)SSL_set_mode(c->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
1134         if(c->tcp_byte_count < sizeof(uint16_t)) {
1135                 uint16_t len = htons(sldns_buffer_limit(c->buffer));
1136                 ERR_clear_error();
1137                 r = SSL_write(c->ssl,
1138                         (void*)(((uint8_t*)&len)+c->tcp_byte_count),
1139                         (int)(sizeof(uint16_t)-c->tcp_byte_count));
1140                 if(r <= 0) {
1141                         int want = SSL_get_error(c->ssl, r);
1142                         if(want == SSL_ERROR_ZERO_RETURN) {
1143                                 return 0; /* closed */
1144                         } else if(want == SSL_ERROR_WANT_READ) {
1145                                 c->ssl_shake_state = comm_ssl_shake_read;
1146                                 comm_point_listen_for_rw(c, 1, 0);
1147                                 return 1; /* wait for read condition */
1148                         } else if(want == SSL_ERROR_WANT_WRITE) {
1149                                 return 1; /* write more later */
1150                         } else if(want == SSL_ERROR_SYSCALL) {
1151                                 if(errno != 0)
1152                                         log_err("SSL_write syscall: %s",
1153                                                 strerror(errno));
1154                                 return 0;
1155                         }
1156                         log_crypto_err("could not SSL_write");
1157                         return 0;
1158                 }
1159                 c->tcp_byte_count += r;
1160                 if(c->tcp_byte_count < sizeof(uint16_t))
1161                         return 1;
1162                 sldns_buffer_set_position(c->buffer, c->tcp_byte_count -
1163                         sizeof(uint16_t));
1164                 if(sldns_buffer_remaining(c->buffer) == 0) {
1165                         tcp_callback_writer(c);
1166                         return 1;
1167                 }
1168         }
1169         log_assert(sldns_buffer_remaining(c->buffer) > 0);
1170         ERR_clear_error();
1171         r = SSL_write(c->ssl, (void*)sldns_buffer_current(c->buffer),
1172                 (int)sldns_buffer_remaining(c->buffer));
1173         if(r <= 0) {
1174                 int want = SSL_get_error(c->ssl, r);
1175                 if(want == SSL_ERROR_ZERO_RETURN) {
1176                         return 0; /* closed */
1177                 } else if(want == SSL_ERROR_WANT_READ) {
1178                         c->ssl_shake_state = comm_ssl_shake_read;
1179                         comm_point_listen_for_rw(c, 1, 0);
1180                         return 1; /* wait for read condition */
1181                 } else if(want == SSL_ERROR_WANT_WRITE) {
1182                         return 1; /* write more later */
1183                 } else if(want == SSL_ERROR_SYSCALL) {
1184                         if(errno != 0)
1185                                 log_err("SSL_write syscall: %s",
1186                                         strerror(errno));
1187                         return 0;
1188                 }
1189                 log_crypto_err("could not SSL_write");
1190                 return 0;
1191         }
1192         sldns_buffer_skip(c->buffer, (ssize_t)r);
1193
1194         if(sldns_buffer_remaining(c->buffer) == 0) {
1195                 tcp_callback_writer(c);
1196         }
1197         return 1;
1198 #else
1199         (void)c;
1200         return 0;
1201 #endif /* HAVE_SSL */
1202 }
1203
1204 /** handle ssl tcp connection with dns contents */
1205 static int
1206 ssl_handle_it(struct comm_point* c)
1207 {
1208         if(c->tcp_is_reading)
1209                 return ssl_handle_read(c);
1210         return ssl_handle_write(c);
1211 }
1212
1213 /** Handle tcp reading callback. 
1214  * @param fd: file descriptor of socket.
1215  * @param c: comm point to read from into buffer.
1216  * @param short_ok: if true, very short packets are OK (for comm_local).
1217  * @return: 0 on error 
1218  */
1219 static int
1220 comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
1221 {
1222         ssize_t r;
1223         log_assert(c->type == comm_tcp || c->type == comm_local);
1224         if(c->ssl)
1225                 return ssl_handle_it(c);
1226         if(!c->tcp_is_reading)
1227                 return 0;
1228
1229         log_assert(fd != -1);
1230         if(c->tcp_byte_count < sizeof(uint16_t)) {
1231                 /* read length bytes */
1232                 r = recv(fd,(void*)sldns_buffer_at(c->buffer,c->tcp_byte_count),
1233                         sizeof(uint16_t)-c->tcp_byte_count, 0);
1234                 if(r == 0)
1235                         return 0;
1236                 else if(r == -1) {
1237 #ifndef USE_WINSOCK
1238                         if(errno == EINTR || errno == EAGAIN)
1239                                 return 1;
1240 #ifdef ECONNRESET
1241                         if(errno == ECONNRESET && verbosity < 2)
1242                                 return 0; /* silence reset by peer */
1243 #endif
1244                         log_err_addr("read (in tcp s)", strerror(errno),
1245                                 &c->repinfo.addr, c->repinfo.addrlen);
1246 #else /* USE_WINSOCK */
1247                         if(WSAGetLastError() == WSAECONNRESET)
1248                                 return 0;
1249                         if(WSAGetLastError() == WSAEINPROGRESS)
1250                                 return 1;
1251                         if(WSAGetLastError() == WSAEWOULDBLOCK) {
1252                                 ub_winsock_tcp_wouldblock(c->ev->ev,
1253                                         UB_EV_READ);
1254                                 return 1;
1255                         }
1256                         log_err_addr("read (in tcp s)", 
1257                                 wsa_strerror(WSAGetLastError()),
1258                                 &c->repinfo.addr, c->repinfo.addrlen);
1259 #endif
1260                         return 0;
1261                 } 
1262                 c->tcp_byte_count += r;
1263                 if(c->tcp_byte_count != sizeof(uint16_t))
1264                         return 1;
1265                 if(sldns_buffer_read_u16_at(c->buffer, 0) >
1266                         sldns_buffer_capacity(c->buffer)) {
1267                         verbose(VERB_QUERY, "tcp: dropped larger than buffer");
1268                         return 0;
1269                 }
1270                 sldns_buffer_set_limit(c->buffer, 
1271                         sldns_buffer_read_u16_at(c->buffer, 0));
1272                 if(!short_ok && 
1273                         sldns_buffer_limit(c->buffer) < LDNS_HEADER_SIZE) {
1274                         verbose(VERB_QUERY, "tcp: dropped bogus too short.");
1275                         return 0;
1276                 }
1277                 verbose(VERB_ALGO, "Reading tcp query of length %d", 
1278                         (int)sldns_buffer_limit(c->buffer));
1279         }
1280
1281         log_assert(sldns_buffer_remaining(c->buffer) > 0);
1282         r = recv(fd, (void*)sldns_buffer_current(c->buffer), 
1283                 sldns_buffer_remaining(c->buffer), 0);
1284         if(r == 0) {
1285                 return 0;
1286         } else if(r == -1) {
1287 #ifndef USE_WINSOCK
1288                 if(errno == EINTR || errno == EAGAIN)
1289                         return 1;
1290                 log_err_addr("read (in tcp r)", strerror(errno),
1291                         &c->repinfo.addr, c->repinfo.addrlen);
1292 #else /* USE_WINSOCK */
1293                 if(WSAGetLastError() == WSAECONNRESET)
1294                         return 0;
1295                 if(WSAGetLastError() == WSAEINPROGRESS)
1296                         return 1;
1297                 if(WSAGetLastError() == WSAEWOULDBLOCK) {
1298                         ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
1299                         return 1;
1300                 }
1301                 log_err_addr("read (in tcp r)",
1302                         wsa_strerror(WSAGetLastError()),
1303                         &c->repinfo.addr, c->repinfo.addrlen);
1304 #endif
1305                 return 0;
1306         }
1307         sldns_buffer_skip(c->buffer, r);
1308         if(sldns_buffer_remaining(c->buffer) <= 0) {
1309                 tcp_callback_reader(c);
1310         }
1311         return 1;
1312 }
1313
1314 /** 
1315  * Handle tcp writing callback. 
1316  * @param fd: file descriptor of socket.
1317  * @param c: comm point to write buffer out of.
1318  * @return: 0 on error
1319  */
1320 static int
1321 comm_point_tcp_handle_write(int fd, struct comm_point* c)
1322 {
1323         ssize_t r;
1324         struct sldns_buffer *buffer;
1325         log_assert(c->type == comm_tcp);
1326 #ifdef USE_DNSCRYPT
1327         buffer = c->dnscrypt_buffer;
1328 #else
1329         buffer = c->buffer;
1330 #endif
1331         if(c->tcp_is_reading && !c->ssl)
1332                 return 0;
1333         log_assert(fd != -1);
1334         if(c->tcp_byte_count == 0 && c->tcp_check_nb_connect) {
1335                 /* check for pending error from nonblocking connect */
1336                 /* from Stevens, unix network programming, vol1, 3rd ed, p450*/
1337                 int error = 0;
1338                 socklen_t len = (socklen_t)sizeof(error);
1339                 if(getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&error, 
1340                         &len) < 0){
1341 #ifndef USE_WINSOCK
1342                         error = errno; /* on solaris errno is error */
1343 #else /* USE_WINSOCK */
1344                         error = WSAGetLastError();
1345 #endif
1346                 }
1347 #ifndef USE_WINSOCK
1348 #if defined(EINPROGRESS) && defined(EWOULDBLOCK)
1349                 if(error == EINPROGRESS || error == EWOULDBLOCK)
1350                         return 1; /* try again later */
1351                 else
1352 #endif
1353                 if(error != 0 && verbosity < 2)
1354                         return 0; /* silence lots of chatter in the logs */
1355                 else if(error != 0) {
1356                         log_err_addr("tcp connect", strerror(error),
1357                                 &c->repinfo.addr, c->repinfo.addrlen);
1358 #else /* USE_WINSOCK */
1359                 /* examine error */
1360                 if(error == WSAEINPROGRESS)
1361                         return 1;
1362                 else if(error == WSAEWOULDBLOCK) {
1363                         ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
1364                         return 1;
1365                 } else if(error != 0 && verbosity < 2)
1366                         return 0;
1367                 else if(error != 0) {
1368                         log_err_addr("tcp connect", wsa_strerror(error),
1369                                 &c->repinfo.addr, c->repinfo.addrlen);
1370 #endif /* USE_WINSOCK */
1371                         return 0;
1372                 }
1373         }
1374         if(c->ssl)
1375                 return ssl_handle_it(c);
1376
1377 #ifdef USE_MSG_FASTOPEN
1378         /* Only try this on first use of a connection that uses tfo, 
1379            otherwise fall through to normal write */
1380         /* Also, TFO support on WINDOWS not implemented at the moment */
1381         if(c->tcp_do_fastopen == 1) {
1382                 /* this form of sendmsg() does both a connect() and send() so need to
1383                    look for various flavours of error*/
1384                 uint16_t len = htons(sldns_buffer_limit(buffer));
1385                 struct msghdr msg;
1386                 struct iovec iov[2];
1387                 c->tcp_do_fastopen = 0;
1388                 memset(&msg, 0, sizeof(msg));
1389                 iov[0].iov_base = (uint8_t*)&len + c->tcp_byte_count;
1390                 iov[0].iov_len = sizeof(uint16_t) - c->tcp_byte_count;
1391                 iov[1].iov_base = sldns_buffer_begin(buffer);
1392                 iov[1].iov_len = sldns_buffer_limit(buffer);
1393                 log_assert(iov[0].iov_len > 0);
1394                 log_assert(iov[1].iov_len > 0);
1395                 msg.msg_name = &c->repinfo.addr;
1396                 msg.msg_namelen = c->repinfo.addrlen;
1397                 msg.msg_iov = iov;
1398                 msg.msg_iovlen = 2;
1399                 r = sendmsg(fd, &msg, MSG_FASTOPEN);
1400                 if (r == -1) {
1401 #if defined(EINPROGRESS) && defined(EWOULDBLOCK)
1402                         /* Handshake is underway, maybe because no TFO cookie available.
1403                            Come back to write the messsage*/
1404                         if(errno == EINPROGRESS || errno == EWOULDBLOCK)
1405                                 return 1;
1406 #endif
1407                         if(errno == EINTR || errno == EAGAIN)
1408                                 return 1;
1409                         /* Not handling EISCONN here as shouldn't ever hit that case.*/
1410                         if(errno != 0 && verbosity < 2)
1411                                 return 0; /* silence lots of chatter in the logs */
1412                         else if(errno != 0) 
1413                                 log_err_addr("tcp sendmsg", strerror(errno),
1414                                         &c->repinfo.addr, c->repinfo.addrlen);
1415                         return 0;
1416                 } else {
1417                         c->tcp_byte_count += r;
1418                         if(c->tcp_byte_count < sizeof(uint16_t))
1419                                 return 1;
1420                         sldns_buffer_set_position(buffer, c->tcp_byte_count - 
1421                                 sizeof(uint16_t));
1422                         if(sldns_buffer_remaining(buffer) == 0) {
1423                                 tcp_callback_writer(c);
1424                                 return 1;
1425                         }
1426                 }
1427         }
1428 #endif /* USE_MSG_FASTOPEN */
1429
1430         if(c->tcp_byte_count < sizeof(uint16_t)) {
1431                 uint16_t len = htons(sldns_buffer_limit(buffer));
1432 #ifdef HAVE_WRITEV
1433                 struct iovec iov[2];
1434                 iov[0].iov_base = (uint8_t*)&len + c->tcp_byte_count;
1435                 iov[0].iov_len = sizeof(uint16_t) - c->tcp_byte_count;
1436                 iov[1].iov_base = sldns_buffer_begin(buffer);
1437                 iov[1].iov_len = sldns_buffer_limit(buffer);
1438                 log_assert(iov[0].iov_len > 0);
1439                 log_assert(iov[1].iov_len > 0);
1440                 r = writev(fd, iov, 2);
1441 #else /* HAVE_WRITEV */
1442                 r = send(fd, (void*)(((uint8_t*)&len)+c->tcp_byte_count),
1443                         sizeof(uint16_t)-c->tcp_byte_count, 0);
1444 #endif /* HAVE_WRITEV */
1445                 if(r == -1) {
1446 #ifndef USE_WINSOCK
1447 #  ifdef EPIPE
1448                         if(errno == EPIPE && verbosity < 2)
1449                                 return 0; /* silence 'broken pipe' */
1450   #endif
1451                         if(errno == EINTR || errno == EAGAIN)
1452                                 return 1;
1453 #  ifdef HAVE_WRITEV
1454                         log_err_addr("tcp writev", strerror(errno),
1455                                 &c->repinfo.addr, c->repinfo.addrlen);
1456 #  else /* HAVE_WRITEV */
1457                         log_err_addr("tcp send s", strerror(errno),
1458                                 &c->repinfo.addr, c->repinfo.addrlen);
1459 #  endif /* HAVE_WRITEV */
1460 #else
1461                         if(WSAGetLastError() == WSAENOTCONN)
1462                                 return 1;
1463                         if(WSAGetLastError() == WSAEINPROGRESS)
1464                                 return 1;
1465                         if(WSAGetLastError() == WSAEWOULDBLOCK) {
1466                                 ub_winsock_tcp_wouldblock(c->ev->ev,
1467                                         UB_EV_WRITE);
1468                                 return 1; 
1469                         }
1470                         log_err_addr("tcp send s",
1471                                 wsa_strerror(WSAGetLastError()),
1472                                 &c->repinfo.addr, c->repinfo.addrlen);
1473 #endif
1474                         return 0;
1475                 }
1476                 c->tcp_byte_count += r;
1477                 if(c->tcp_byte_count < sizeof(uint16_t))
1478                         return 1;
1479                 sldns_buffer_set_position(buffer, c->tcp_byte_count - 
1480                         sizeof(uint16_t));
1481                 if(sldns_buffer_remaining(buffer) == 0) {
1482                         tcp_callback_writer(c);
1483                         return 1;
1484                 }
1485         }
1486         log_assert(sldns_buffer_remaining(buffer) > 0);
1487         r = send(fd, (void*)sldns_buffer_current(buffer), 
1488                 sldns_buffer_remaining(buffer), 0);
1489         if(r == -1) {
1490 #ifndef USE_WINSOCK
1491                 if(errno == EINTR || errno == EAGAIN)
1492                         return 1;
1493                 log_err_addr("tcp send r", strerror(errno),
1494                         &c->repinfo.addr, c->repinfo.addrlen);
1495 #else
1496                 if(WSAGetLastError() == WSAEINPROGRESS)
1497                         return 1;
1498                 if(WSAGetLastError() == WSAEWOULDBLOCK) {
1499                         ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
1500                         return 1; 
1501                 }
1502                 log_err_addr("tcp send r", wsa_strerror(WSAGetLastError()),
1503                         &c->repinfo.addr, c->repinfo.addrlen);
1504 #endif
1505                 return 0;
1506         }
1507         sldns_buffer_skip(buffer, r);
1508
1509         if(sldns_buffer_remaining(buffer) == 0) {
1510                 tcp_callback_writer(c);
1511         }
1512         
1513         return 1;
1514 }
1515
1516 void 
1517 comm_point_tcp_handle_callback(int fd, short event, void* arg)
1518 {
1519         struct comm_point* c = (struct comm_point*)arg;
1520         log_assert(c->type == comm_tcp);
1521         ub_comm_base_now(c->ev->base);
1522
1523 #ifdef USE_DNSCRYPT
1524         /* Initialize if this is a dnscrypt socket */
1525         if(c->tcp_parent) {
1526                 c->dnscrypt = c->tcp_parent->dnscrypt;
1527         }
1528     if(c->dnscrypt && c->dnscrypt_buffer == c->buffer) {
1529         c->dnscrypt_buffer = sldns_buffer_new(sldns_buffer_capacity(c->buffer));
1530         if(!c->dnscrypt_buffer) {
1531             log_err("Could not allocate dnscrypt buffer");
1532             return;
1533         }
1534     }
1535 #endif
1536
1537         if(event&UB_EV_READ) {
1538                 if(!comm_point_tcp_handle_read(fd, c, 0)) {
1539                         reclaim_tcp_handler(c);
1540                         if(!c->tcp_do_close) {
1541                                 fptr_ok(fptr_whitelist_comm_point(
1542                                         c->callback));
1543                                 (void)(*c->callback)(c, c->cb_arg, 
1544                                         NETEVENT_CLOSED, NULL);
1545                         }
1546                 }
1547                 return;
1548         }
1549         if(event&UB_EV_WRITE) {
1550                 if(!comm_point_tcp_handle_write(fd, c)) {
1551                         reclaim_tcp_handler(c);
1552                         if(!c->tcp_do_close) {
1553                                 fptr_ok(fptr_whitelist_comm_point(
1554                                         c->callback));
1555                                 (void)(*c->callback)(c, c->cb_arg, 
1556                                         NETEVENT_CLOSED, NULL);
1557                         }
1558                 }
1559                 return;
1560         }
1561         if(event&UB_EV_TIMEOUT) {
1562                 verbose(VERB_QUERY, "tcp took too long, dropped");
1563                 reclaim_tcp_handler(c);
1564                 if(!c->tcp_do_close) {
1565                         fptr_ok(fptr_whitelist_comm_point(c->callback));
1566                         (void)(*c->callback)(c, c->cb_arg,
1567                                 NETEVENT_TIMEOUT, NULL);
1568                 }
1569                 return;
1570         }
1571         log_err("Ignored event %d for tcphdl.", event);
1572 }
1573
1574 void comm_point_local_handle_callback(int fd, short event, void* arg)
1575 {
1576         struct comm_point* c = (struct comm_point*)arg;
1577         log_assert(c->type == comm_local);
1578         ub_comm_base_now(c->ev->base);
1579
1580         if(event&UB_EV_READ) {
1581                 if(!comm_point_tcp_handle_read(fd, c, 1)) {
1582                         fptr_ok(fptr_whitelist_comm_point(c->callback));
1583                         (void)(*c->callback)(c, c->cb_arg, NETEVENT_CLOSED, 
1584                                 NULL);
1585                 }
1586                 return;
1587         }
1588         log_err("Ignored event %d for localhdl.", event);
1589 }
1590
1591 void comm_point_raw_handle_callback(int ATTR_UNUSED(fd), 
1592         short event, void* arg)
1593 {
1594         struct comm_point* c = (struct comm_point*)arg;
1595         int err = NETEVENT_NOERROR;
1596         log_assert(c->type == comm_raw);
1597         ub_comm_base_now(c->ev->base);
1598         
1599         if(event&UB_EV_TIMEOUT)
1600                 err = NETEVENT_TIMEOUT;
1601         fptr_ok(fptr_whitelist_comm_point_raw(c->callback));
1602         (void)(*c->callback)(c, c->cb_arg, err, NULL);
1603 }
1604
1605 struct comm_point* 
1606 comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
1607         comm_point_callback_type* callback, void* callback_arg)
1608 {
1609         struct comm_point* c = (struct comm_point*)calloc(1,
1610                 sizeof(struct comm_point));
1611         short evbits;
1612         if(!c)
1613                 return NULL;
1614         c->ev = (struct internal_event*)calloc(1,
1615                 sizeof(struct internal_event));
1616         if(!c->ev) {
1617                 free(c);
1618                 return NULL;
1619         }
1620         c->ev->base = base;
1621         c->fd = fd;
1622         c->buffer = buffer;
1623         c->timeout = NULL;
1624         c->tcp_is_reading = 0;
1625         c->tcp_byte_count = 0;
1626         c->tcp_parent = NULL;
1627         c->max_tcp_count = 0;
1628         c->cur_tcp_count = 0;
1629         c->tcp_handlers = NULL;
1630         c->tcp_free = NULL;
1631         c->type = comm_udp;
1632         c->tcp_do_close = 0;
1633         c->do_not_close = 0;
1634         c->tcp_do_toggle_rw = 0;
1635         c->tcp_check_nb_connect = 0;
1636 #ifdef USE_MSG_FASTOPEN
1637         c->tcp_do_fastopen = 0;
1638 #endif
1639 #ifdef USE_DNSCRYPT
1640         c->dnscrypt = 0;
1641         c->dnscrypt_buffer = buffer;
1642 #endif
1643         c->inuse = 0;
1644         c->callback = callback;
1645         c->cb_arg = callback_arg;
1646         evbits = UB_EV_READ | UB_EV_PERSIST;
1647         /* ub_event stuff */
1648         c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
1649                 comm_point_udp_callback, c);
1650         if(c->ev->ev == NULL) {
1651                 log_err("could not baseset udp event");
1652                 comm_point_delete(c);
1653                 return NULL;
1654         }
1655         if(fd!=-1 && ub_event_add(c->ev->ev, c->timeout) != 0 ) {
1656                 log_err("could not add udp event");
1657                 comm_point_delete(c);
1658                 return NULL;
1659         }
1660         return c;
1661 }
1662
1663 struct comm_point* 
1664 comm_point_create_udp_ancil(struct comm_base *base, int fd, 
1665         sldns_buffer* buffer, 
1666         comm_point_callback_type* callback, void* callback_arg)
1667 {
1668         struct comm_point* c = (struct comm_point*)calloc(1,
1669                 sizeof(struct comm_point));
1670         short evbits;
1671         if(!c)
1672                 return NULL;
1673         c->ev = (struct internal_event*)calloc(1,
1674                 sizeof(struct internal_event));
1675         if(!c->ev) {
1676                 free(c);
1677                 return NULL;
1678         }
1679         c->ev->base = base;
1680         c->fd = fd;
1681         c->buffer = buffer;
1682         c->timeout = NULL;
1683         c->tcp_is_reading = 0;
1684         c->tcp_byte_count = 0;
1685         c->tcp_parent = NULL;
1686         c->max_tcp_count = 0;
1687         c->cur_tcp_count = 0;
1688         c->tcp_handlers = NULL;
1689         c->tcp_free = NULL;
1690         c->type = comm_udp;
1691         c->tcp_do_close = 0;
1692         c->do_not_close = 0;
1693 #ifdef USE_DNSCRYPT
1694     c->dnscrypt = 0;
1695     c->dnscrypt_buffer = buffer;
1696 #endif
1697         c->inuse = 0;
1698         c->tcp_do_toggle_rw = 0;
1699         c->tcp_check_nb_connect = 0;
1700 #ifdef USE_MSG_FASTOPEN
1701         c->tcp_do_fastopen = 0;
1702 #endif
1703         c->callback = callback;
1704         c->cb_arg = callback_arg;
1705         evbits = UB_EV_READ | UB_EV_PERSIST;
1706         /* ub_event stuff */
1707         c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
1708                 comm_point_udp_ancil_callback, c);
1709         if(c->ev->ev == NULL) {
1710                 log_err("could not baseset udp event");
1711                 comm_point_delete(c);
1712                 return NULL;
1713         }
1714         if(fd!=-1 && ub_event_add(c->ev->ev, c->timeout) != 0 ) {
1715                 log_err("could not add udp event");
1716                 comm_point_delete(c);
1717                 return NULL;
1718         }
1719         return c;
1720 }
1721
1722 static struct comm_point* 
1723 comm_point_create_tcp_handler(struct comm_base *base, 
1724         struct comm_point* parent, size_t bufsize,
1725         comm_point_callback_type* callback, void* callback_arg)
1726 {
1727         struct comm_point* c = (struct comm_point*)calloc(1,
1728                 sizeof(struct comm_point));
1729         short evbits;
1730         if(!c)
1731                 return NULL;
1732         c->ev = (struct internal_event*)calloc(1,
1733                 sizeof(struct internal_event));
1734         if(!c->ev) {
1735                 free(c);
1736                 return NULL;
1737         }
1738         c->ev->base = base;
1739         c->fd = -1;
1740         c->buffer = sldns_buffer_new(bufsize);
1741         if(!c->buffer) {
1742                 free(c->ev);
1743                 free(c);
1744                 return NULL;
1745         }
1746         c->timeout = (struct timeval*)malloc(sizeof(struct timeval));
1747         if(!c->timeout) {
1748                 sldns_buffer_free(c->buffer);
1749                 free(c->ev);
1750                 free(c);
1751                 return NULL;
1752         }
1753         c->tcp_is_reading = 0;
1754         c->tcp_byte_count = 0;
1755         c->tcp_parent = parent;
1756         c->max_tcp_count = 0;
1757         c->cur_tcp_count = 0;
1758         c->tcp_handlers = NULL;
1759         c->tcp_free = NULL;
1760         c->type = comm_tcp;
1761         c->tcp_do_close = 0;
1762         c->do_not_close = 0;
1763         c->tcp_do_toggle_rw = 1;
1764         c->tcp_check_nb_connect = 0;
1765 #ifdef USE_MSG_FASTOPEN
1766         c->tcp_do_fastopen = 0;
1767 #endif
1768 #ifdef USE_DNSCRYPT
1769     c->dnscrypt = 0;
1770     // We don't know just yet if this is a dnscrypt channel. Allocation
1771     // will be done when handling the callback.
1772     c->dnscrypt_buffer = c->buffer;
1773 #endif
1774         c->repinfo.c = c;
1775         c->callback = callback;
1776         c->cb_arg = callback_arg;
1777         /* add to parent free list */
1778         c->tcp_free = parent->tcp_free;
1779         parent->tcp_free = c;
1780         /* ub_event stuff */
1781         evbits = UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT;
1782         c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
1783                 comm_point_tcp_handle_callback, c);
1784         if(c->ev->ev == NULL)
1785         {
1786                 log_err("could not basetset tcphdl event");
1787                 parent->tcp_free = c->tcp_free;
1788                 free(c->ev);
1789                 free(c);
1790                 return NULL;
1791         }
1792         return c;
1793 }
1794
1795 struct comm_point* 
1796 comm_point_create_tcp(struct comm_base *base, int fd, int num, size_t bufsize,
1797         comm_point_callback_type* callback, void* callback_arg)
1798 {
1799         struct comm_point* c = (struct comm_point*)calloc(1,
1800                 sizeof(struct comm_point));
1801         short evbits;
1802         int i;
1803         /* first allocate the TCP accept listener */
1804         if(!c)
1805                 return NULL;
1806         c->ev = (struct internal_event*)calloc(1,
1807                 sizeof(struct internal_event));
1808         if(!c->ev) {
1809                 free(c);
1810                 return NULL;
1811         }
1812         c->ev->base = base;
1813         c->fd = fd;
1814         c->buffer = NULL;
1815         c->timeout = NULL;
1816         c->tcp_is_reading = 0;
1817         c->tcp_byte_count = 0;
1818         c->tcp_parent = NULL;
1819         c->max_tcp_count = num;
1820         c->cur_tcp_count = 0;
1821         c->tcp_handlers = (struct comm_point**)calloc((size_t)num,
1822                 sizeof(struct comm_point*));
1823         if(!c->tcp_handlers) {
1824                 free(c->ev);
1825                 free(c);
1826                 return NULL;
1827         }
1828         c->tcp_free = NULL;
1829         c->type = comm_tcp_accept;
1830         c->tcp_do_close = 0;
1831         c->do_not_close = 0;
1832         c->tcp_do_toggle_rw = 0;
1833         c->tcp_check_nb_connect = 0;
1834 #ifdef USE_MSG_FASTOPEN
1835         c->tcp_do_fastopen = 0;
1836 #endif
1837 #ifdef USE_DNSCRYPT
1838         c->dnscrypt = 0;
1839         c->dnscrypt_buffer = NULL;
1840 #endif
1841         c->callback = NULL;
1842         c->cb_arg = NULL;
1843         evbits = UB_EV_READ | UB_EV_PERSIST;
1844         /* ub_event stuff */
1845         c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
1846                 comm_point_tcp_accept_callback, c);
1847         if(c->ev->ev == NULL) {
1848                 log_err("could not baseset tcpacc event");
1849                 comm_point_delete(c);
1850                 return NULL;
1851         }
1852         if (ub_event_add(c->ev->ev, c->timeout) != 0) {
1853                 log_err("could not add tcpacc event");
1854                 comm_point_delete(c);
1855                 return NULL;
1856         }
1857         /* now prealloc the tcp handlers */
1858         for(i=0; i<num; i++) {
1859                 c->tcp_handlers[i] = comm_point_create_tcp_handler(base,
1860                         c, bufsize, callback, callback_arg);
1861                 if(!c->tcp_handlers[i]) {
1862                         comm_point_delete(c);
1863                         return NULL;
1864                 }
1865         }
1866         
1867         return c;
1868 }
1869
1870 struct comm_point* 
1871 comm_point_create_tcp_out(struct comm_base *base, size_t bufsize,
1872         comm_point_callback_type* callback, void* callback_arg)
1873 {
1874         struct comm_point* c = (struct comm_point*)calloc(1,
1875                 sizeof(struct comm_point));
1876         short evbits;
1877         if(!c)
1878                 return NULL;
1879         c->ev = (struct internal_event*)calloc(1,
1880                 sizeof(struct internal_event));
1881         if(!c->ev) {
1882                 free(c);
1883                 return NULL;
1884         }
1885         c->ev->base = base;
1886         c->fd = -1;
1887         c->buffer = sldns_buffer_new(bufsize);
1888         if(!c->buffer) {
1889                 free(c->ev);
1890                 free(c);
1891                 return NULL;
1892         }
1893         c->timeout = NULL;
1894         c->tcp_is_reading = 0;
1895         c->tcp_byte_count = 0;
1896         c->tcp_parent = NULL;
1897         c->max_tcp_count = 0;
1898         c->cur_tcp_count = 0;
1899         c->tcp_handlers = NULL;
1900         c->tcp_free = NULL;
1901         c->type = comm_tcp;
1902         c->tcp_do_close = 0;
1903         c->do_not_close = 0;
1904         c->tcp_do_toggle_rw = 1;
1905         c->tcp_check_nb_connect = 1;
1906 #ifdef USE_MSG_FASTOPEN
1907         c->tcp_do_fastopen = 1;
1908 #endif
1909 #ifdef USE_DNSCRYPT
1910         c->dnscrypt = 0;
1911         c->dnscrypt_buffer = c->buffer;
1912 #endif
1913         c->repinfo.c = c;
1914         c->callback = callback;
1915         c->cb_arg = callback_arg;
1916         evbits = UB_EV_PERSIST | UB_EV_WRITE;
1917         c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
1918                 comm_point_tcp_handle_callback, c);
1919         if(c->ev->ev == NULL)
1920         {
1921                 log_err("could not baseset tcpout event");
1922                 sldns_buffer_free(c->buffer);
1923                 free(c->ev);
1924                 free(c);
1925                 return NULL;
1926         }
1927
1928         return c;
1929 }
1930
1931 struct comm_point* 
1932 comm_point_create_local(struct comm_base *base, int fd, size_t bufsize,
1933         comm_point_callback_type* callback, void* callback_arg)
1934 {
1935         struct comm_point* c = (struct comm_point*)calloc(1,
1936                 sizeof(struct comm_point));
1937         short evbits;
1938         if(!c)
1939                 return NULL;
1940         c->ev = (struct internal_event*)calloc(1,
1941                 sizeof(struct internal_event));
1942         if(!c->ev) {
1943                 free(c);
1944                 return NULL;
1945         }
1946         c->ev->base = base;
1947         c->fd = fd;
1948         c->buffer = sldns_buffer_new(bufsize);
1949         if(!c->buffer) {
1950                 free(c->ev);
1951                 free(c);
1952                 return NULL;
1953         }
1954         c->timeout = NULL;
1955         c->tcp_is_reading = 1;
1956         c->tcp_byte_count = 0;
1957         c->tcp_parent = NULL;
1958         c->max_tcp_count = 0;
1959         c->cur_tcp_count = 0;
1960         c->tcp_handlers = NULL;
1961         c->tcp_free = NULL;
1962         c->type = comm_local;
1963         c->tcp_do_close = 0;
1964         c->do_not_close = 1;
1965         c->tcp_do_toggle_rw = 0;
1966         c->tcp_check_nb_connect = 0;
1967 #ifdef USE_MSG_FASTOPEN
1968         c->tcp_do_fastopen = 0;
1969 #endif
1970 #ifdef USE_DNSCRYPT
1971         c->dnscrypt = 0;
1972         c->dnscrypt_buffer = c->buffer;
1973 #endif
1974         c->callback = callback;
1975         c->cb_arg = callback_arg;
1976         /* ub_event stuff */
1977         evbits = UB_EV_PERSIST | UB_EV_READ;
1978         c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
1979                 comm_point_local_handle_callback, c);
1980         if(c->ev->ev == NULL) {
1981                 log_err("could not baseset localhdl event");
1982                 free(c->ev);
1983                 free(c);
1984                 return NULL;
1985         }
1986         if (ub_event_add(c->ev->ev, c->timeout) != 0) {
1987                 log_err("could not add localhdl event");
1988                 ub_event_free(c->ev->ev);
1989                 free(c->ev);
1990                 free(c);
1991                 return NULL;
1992         }
1993         return c;
1994 }
1995
1996 struct comm_point* 
1997 comm_point_create_raw(struct comm_base* base, int fd, int writing, 
1998         comm_point_callback_type* callback, void* callback_arg)
1999 {
2000         struct comm_point* c = (struct comm_point*)calloc(1,
2001                 sizeof(struct comm_point));
2002         short evbits;
2003         if(!c)
2004                 return NULL;
2005         c->ev = (struct internal_event*)calloc(1,
2006                 sizeof(struct internal_event));
2007         if(!c->ev) {
2008                 free(c);
2009                 return NULL;
2010         }
2011         c->ev->base = base;
2012         c->fd = fd;
2013         c->buffer = NULL;
2014         c->timeout = NULL;
2015         c->tcp_is_reading = 0;
2016         c->tcp_byte_count = 0;
2017         c->tcp_parent = NULL;
2018         c->max_tcp_count = 0;
2019         c->cur_tcp_count = 0;
2020         c->tcp_handlers = NULL;
2021         c->tcp_free = NULL;
2022         c->type = comm_raw;
2023         c->tcp_do_close = 0;
2024         c->do_not_close = 1;
2025         c->tcp_do_toggle_rw = 0;
2026         c->tcp_check_nb_connect = 0;
2027 #ifdef USE_MSG_FASTOPEN
2028         c->tcp_do_fastopen = 0;
2029 #endif
2030 #ifdef USE_DNSCRYPT
2031         c->dnscrypt = 0;
2032         c->dnscrypt_buffer = c->buffer;
2033 #endif
2034         c->callback = callback;
2035         c->cb_arg = callback_arg;
2036         /* ub_event stuff */
2037         if(writing)
2038                 evbits = UB_EV_PERSIST | UB_EV_WRITE;
2039         else    evbits = UB_EV_PERSIST | UB_EV_READ;
2040         c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
2041                 comm_point_raw_handle_callback, c);
2042         if(c->ev->ev == NULL) {
2043                 log_err("could not baseset rawhdl event");
2044                 free(c->ev);
2045                 free(c);
2046                 return NULL;
2047         }
2048         if (ub_event_add(c->ev->ev, c->timeout) != 0) {
2049                 log_err("could not add rawhdl event");
2050                 ub_event_free(c->ev->ev);
2051                 free(c->ev);
2052                 free(c);
2053                 return NULL;
2054         }
2055         return c;
2056 }
2057
2058 void 
2059 comm_point_close(struct comm_point* c)
2060 {
2061         if(!c)
2062                 return;
2063         if(c->fd != -1)
2064                 if(ub_event_del(c->ev->ev) != 0) {
2065                         log_err("could not event_del on close");
2066                 }
2067         /* close fd after removing from event lists, or epoll.. is messed up */
2068         if(c->fd != -1 && !c->do_not_close) {
2069                 verbose(VERB_ALGO, "close fd %d", c->fd);
2070 #ifndef USE_WINSOCK
2071                 close(c->fd);
2072 #else
2073                 closesocket(c->fd);
2074 #endif
2075         }
2076         c->fd = -1;
2077 }
2078
2079 void 
2080 comm_point_delete(struct comm_point* c)
2081 {
2082         if(!c) 
2083                 return;
2084         if(c->type == comm_tcp && c->ssl) {
2085 #ifdef HAVE_SSL
2086                 SSL_shutdown(c->ssl);
2087                 SSL_free(c->ssl);
2088 #endif
2089         }
2090         comm_point_close(c);
2091         if(c->tcp_handlers) {
2092                 int i;
2093                 for(i=0; i<c->max_tcp_count; i++)
2094                         comm_point_delete(c->tcp_handlers[i]);
2095                 free(c->tcp_handlers);
2096         }
2097         free(c->timeout);
2098         if(c->type == comm_tcp || c->type == comm_local) {
2099                 sldns_buffer_free(c->buffer);
2100 #ifdef USE_DNSCRYPT
2101         if(c->dnscrypt && c->dnscrypt_buffer != c->buffer) {
2102             sldns_buffer_free(c->dnscrypt_buffer);
2103         }
2104 #endif
2105     }
2106         ub_event_free(c->ev->ev);
2107         free(c->ev);
2108         free(c);
2109 }
2110
2111 void 
2112 comm_point_send_reply(struct comm_reply *repinfo)
2113 {
2114         struct sldns_buffer* buffer;
2115         log_assert(repinfo && repinfo->c);
2116 #ifdef USE_DNSCRYPT
2117         buffer = repinfo->c->dnscrypt_buffer;
2118         if(!dnsc_handle_uncurved_request(repinfo)) {
2119                 return;
2120         }
2121 #else
2122         buffer = repinfo->c->buffer;
2123 #endif
2124         if(repinfo->c->type == comm_udp) {
2125                 if(repinfo->srctype)
2126                         comm_point_send_udp_msg_if(repinfo->c, 
2127                         buffer, (struct sockaddr*)&repinfo->addr, 
2128                         repinfo->addrlen, repinfo);
2129                 else
2130                         comm_point_send_udp_msg(repinfo->c, buffer,
2131                         (struct sockaddr*)&repinfo->addr, repinfo->addrlen);
2132 #ifdef USE_DNSTAP
2133                 if(repinfo->c->dtenv != NULL &&
2134                    repinfo->c->dtenv->log_client_response_messages)
2135                         dt_msg_send_client_response(repinfo->c->dtenv,
2136                         &repinfo->addr, repinfo->c->type, repinfo->c->buffer);
2137 #endif
2138         } else {
2139 #ifdef USE_DNSTAP
2140                 if(repinfo->c->tcp_parent->dtenv != NULL &&
2141                    repinfo->c->tcp_parent->dtenv->log_client_response_messages)
2142                         dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv,
2143                         &repinfo->addr, repinfo->c->type, repinfo->c->buffer);
2144 #endif
2145                 comm_point_start_listening(repinfo->c, -1,
2146                         repinfo->c->tcp_timeout_msec);
2147         }
2148 }
2149
2150 void 
2151 comm_point_drop_reply(struct comm_reply* repinfo)
2152 {
2153         if(!repinfo)
2154                 return;
2155         log_assert(repinfo && repinfo->c);
2156         log_assert(repinfo->c->type != comm_tcp_accept);
2157         if(repinfo->c->type == comm_udp)
2158                 return;
2159         reclaim_tcp_handler(repinfo->c);
2160 }
2161
2162 void 
2163 comm_point_stop_listening(struct comm_point* c)
2164 {
2165         verbose(VERB_ALGO, "comm point stop listening %d", c->fd);
2166         if(ub_event_del(c->ev->ev) != 0) {
2167                 log_err("event_del error to stoplisten");
2168         }
2169 }
2170
2171 void 
2172 comm_point_start_listening(struct comm_point* c, int newfd, int msec)
2173 {
2174         verbose(VERB_ALGO, "comm point start listening %d", 
2175                 c->fd==-1?newfd:c->fd);
2176         if(c->type == comm_tcp_accept && !c->tcp_free) {
2177                 /* no use to start listening no free slots. */
2178                 return;
2179         }
2180         if(msec != -1 && msec != 0) {
2181                 if(!c->timeout) {
2182                         c->timeout = (struct timeval*)malloc(sizeof(
2183                                 struct timeval));
2184                         if(!c->timeout) {
2185                                 log_err("cpsl: malloc failed. No net read.");
2186                                 return;
2187                         }
2188                 }
2189                 ub_event_add_bits(c->ev->ev, UB_EV_TIMEOUT);
2190 #ifndef S_SPLINT_S /* splint fails on struct timeval. */
2191                 c->timeout->tv_sec = msec/1000;
2192                 c->timeout->tv_usec = (msec%1000)*1000;
2193 #endif /* S_SPLINT_S */
2194         }
2195         if(c->type == comm_tcp) {
2196                 ub_event_del_bits(c->ev->ev, UB_EV_READ|UB_EV_WRITE);
2197                 if(c->tcp_is_reading)
2198                         ub_event_add_bits(c->ev->ev, UB_EV_READ);
2199                 else    ub_event_add_bits(c->ev->ev, UB_EV_WRITE);
2200         }
2201         if(newfd != -1) {
2202                 if(c->fd != -1) {
2203 #ifndef USE_WINSOCK
2204                         close(c->fd);
2205 #else
2206                         closesocket(c->fd);
2207 #endif
2208                 }
2209                 c->fd = newfd;
2210                 ub_event_set_fd(c->ev->ev, c->fd);
2211         }
2212         if(ub_event_add(c->ev->ev, msec==0?NULL:c->timeout) != 0) {
2213                 log_err("event_add failed. in cpsl.");
2214         }
2215 }
2216
2217 void comm_point_listen_for_rw(struct comm_point* c, int rd, int wr)
2218 {
2219         verbose(VERB_ALGO, "comm point listen_for_rw %d %d", c->fd, wr);
2220         if(ub_event_del(c->ev->ev) != 0) {
2221                 log_err("event_del error to cplf");
2222         }
2223         ub_event_del_bits(c->ev->ev, UB_EV_READ|UB_EV_WRITE);
2224         if(rd) ub_event_add_bits(c->ev->ev, UB_EV_READ);
2225         if(wr) ub_event_add_bits(c->ev->ev, UB_EV_WRITE);
2226         if(ub_event_add(c->ev->ev, c->timeout) != 0) {
2227                 log_err("event_add failed. in cplf.");
2228         }
2229 }
2230
2231 size_t comm_point_get_mem(struct comm_point* c)
2232 {
2233         size_t s;
2234         if(!c) 
2235                 return 0;
2236         s = sizeof(*c) + sizeof(*c->ev);
2237         if(c->timeout) 
2238                 s += sizeof(*c->timeout);
2239         if(c->type == comm_tcp || c->type == comm_local) {
2240                 s += sizeof(*c->buffer) + sldns_buffer_capacity(c->buffer);
2241 #ifdef USE_DNSCRYPT
2242         s += sizeof(*c->dnscrypt_buffer);
2243         if(c->buffer != c->dnscrypt_buffer) {
2244             s += sldns_buffer_capacity(c->dnscrypt_buffer);
2245         }
2246 #endif
2247     }
2248         if(c->type == comm_tcp_accept) {
2249                 int i;
2250                 for(i=0; i<c->max_tcp_count; i++)
2251                         s += comm_point_get_mem(c->tcp_handlers[i]);
2252         }
2253         return s;
2254 }
2255
2256 struct comm_timer* 
2257 comm_timer_create(struct comm_base* base, void (*cb)(void*), void* cb_arg)
2258 {
2259         struct internal_timer *tm = (struct internal_timer*)calloc(1,
2260                 sizeof(struct internal_timer));
2261         if(!tm) {
2262                 log_err("malloc failed");
2263                 return NULL;
2264         }
2265         tm->super.ev_timer = tm;
2266         tm->base = base;
2267         tm->super.callback = cb;
2268         tm->super.cb_arg = cb_arg;
2269         tm->ev = ub_event_new(base->eb->base, -1, UB_EV_TIMEOUT, 
2270                 comm_timer_callback, &tm->super);
2271         if(tm->ev == NULL) {
2272                 log_err("timer_create: event_base_set failed.");
2273                 free(tm);
2274                 return NULL;
2275         }
2276         return &tm->super;
2277 }
2278
2279 void 
2280 comm_timer_disable(struct comm_timer* timer)
2281 {
2282         if(!timer)
2283                 return;
2284         ub_timer_del(timer->ev_timer->ev);
2285         timer->ev_timer->enabled = 0;
2286 }
2287
2288 void 
2289 comm_timer_set(struct comm_timer* timer, struct timeval* tv)
2290 {
2291         log_assert(tv);
2292         if(timer->ev_timer->enabled)
2293                 comm_timer_disable(timer);
2294         if(ub_timer_add(timer->ev_timer->ev, timer->ev_timer->base->eb->base,
2295                 comm_timer_callback, timer, tv) != 0)
2296                 log_err("comm_timer_set: evtimer_add failed.");
2297         timer->ev_timer->enabled = 1;
2298 }
2299
2300 void 
2301 comm_timer_delete(struct comm_timer* timer)
2302 {
2303         if(!timer)
2304                 return;
2305         comm_timer_disable(timer);
2306         /* Free the sub struct timer->ev_timer derived from the super struct timer.
2307          * i.e. assert(timer == timer->ev_timer)
2308          */
2309         ub_event_free(timer->ev_timer->ev);
2310         free(timer->ev_timer);
2311 }
2312
2313 void 
2314 comm_timer_callback(int ATTR_UNUSED(fd), short event, void* arg)
2315 {
2316         struct comm_timer* tm = (struct comm_timer*)arg;
2317         if(!(event&UB_EV_TIMEOUT))
2318                 return;
2319         ub_comm_base_now(tm->ev_timer->base);
2320         tm->ev_timer->enabled = 0;
2321         fptr_ok(fptr_whitelist_comm_timer(tm->callback));
2322         (*tm->callback)(tm->cb_arg);
2323 }
2324
2325 int 
2326 comm_timer_is_set(struct comm_timer* timer)
2327 {
2328         return (int)timer->ev_timer->enabled;
2329 }
2330
2331 size_t 
2332 comm_timer_get_mem(struct comm_timer* ATTR_UNUSED(timer))
2333 {
2334         return sizeof(struct internal_timer);
2335 }
2336
2337 struct comm_signal* 
2338 comm_signal_create(struct comm_base* base,
2339         void (*callback)(int, void*), void* cb_arg)
2340 {
2341         struct comm_signal* com = (struct comm_signal*)malloc(
2342                 sizeof(struct comm_signal));
2343         if(!com) {
2344                 log_err("malloc failed");
2345                 return NULL;
2346         }
2347         com->base = base;
2348         com->callback = callback;
2349         com->cb_arg = cb_arg;
2350         com->ev_signal = NULL;
2351         return com;
2352 }
2353
2354 void 
2355 comm_signal_callback(int sig, short event, void* arg)
2356 {
2357         struct comm_signal* comsig = (struct comm_signal*)arg;
2358         if(!(event & UB_EV_SIGNAL))
2359                 return;
2360         ub_comm_base_now(comsig->base);
2361         fptr_ok(fptr_whitelist_comm_signal(comsig->callback));
2362         (*comsig->callback)(sig, comsig->cb_arg);
2363 }
2364
2365 int 
2366 comm_signal_bind(struct comm_signal* comsig, int sig)
2367 {
2368         struct internal_signal* entry = (struct internal_signal*)calloc(1, 
2369                 sizeof(struct internal_signal));
2370         if(!entry) {
2371                 log_err("malloc failed");
2372                 return 0;
2373         }
2374         log_assert(comsig);
2375         /* add signal event */
2376         entry->ev = ub_signal_new(comsig->base->eb->base, sig,
2377                 comm_signal_callback, comsig);
2378         if(entry->ev == NULL) {
2379                 log_err("Could not create signal event");
2380                 free(entry);
2381                 return 0;
2382         }
2383         if(ub_signal_add(entry->ev, NULL) != 0) {
2384                 log_err("Could not add signal handler");
2385                 ub_event_free(entry->ev);
2386                 free(entry);
2387                 return 0;
2388         }
2389         /* link into list */
2390         entry->next = comsig->ev_signal;
2391         comsig->ev_signal = entry;
2392         return 1;
2393 }
2394
2395 void 
2396 comm_signal_delete(struct comm_signal* comsig)
2397 {
2398         struct internal_signal* p, *np;
2399         if(!comsig)
2400                 return;
2401         p=comsig->ev_signal;
2402         while(p) {
2403                 np = p->next;
2404                 ub_signal_del(p->ev);
2405                 ub_event_free(p->ev);
2406                 free(p);
2407                 p = np;
2408         }
2409         free(comsig);
2410 }