xref: /openbsd-src/usr.sbin/unbound/util/netevent.c (revision f763167468dba5339ed4b14b7ecaca2a397ab0f6)
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 != EPIPE && errno != 0 && verbosity < 2)
1411 				return 0; /* silence lots of chatter in the logs */
1412 			if(errno != EPIPE && errno != 0) {
1413 				log_err_addr("tcp sendmsg", strerror(errno),
1414 					&c->repinfo.addr, c->repinfo.addrlen);
1415 				return 0;
1416 			}
1417 			/* fallthrough to nonFASTOPEN
1418 			 * (MSG_FASTOPEN on Linux 3 produces EPIPE)
1419 			 * we need to perform connect() */
1420 			if(connect(fd, (struct sockaddr *)&c->repinfo.addr, c->repinfo.addrlen) == -1) {
1421 #ifdef EINPROGRESS
1422 				if(errno == EINPROGRESS)
1423 					return 1; /* wait until connect done*/
1424 #endif
1425 #ifdef USE_WINSOCK
1426 				if(WSAGetLastError() == WSAEINPROGRESS ||
1427 					WSAGetLastError() == WSAEWOULDBLOCK)
1428 					return 1; /* wait until connect done*/
1429 #endif
1430 				if(tcp_connect_errno_needs_log(
1431 					(struct sockaddr *)&c->repinfo.addr, c->repinfo.addrlen)) {
1432 					log_err_addr("outgoing tcp: connect after EPIPE for fastopen",
1433 						strerror(errno), &c->repinfo.addr, c->repinfo.addrlen);
1434 				}
1435 				return 0;
1436 			}
1437 
1438 		} else {
1439 			c->tcp_byte_count += r;
1440 			if(c->tcp_byte_count < sizeof(uint16_t))
1441 				return 1;
1442 			sldns_buffer_set_position(buffer, c->tcp_byte_count -
1443 				sizeof(uint16_t));
1444 			if(sldns_buffer_remaining(buffer) == 0) {
1445 				tcp_callback_writer(c);
1446 				return 1;
1447 			}
1448 		}
1449 	}
1450 #endif /* USE_MSG_FASTOPEN */
1451 
1452 	if(c->tcp_byte_count < sizeof(uint16_t)) {
1453 		uint16_t len = htons(sldns_buffer_limit(buffer));
1454 #ifdef HAVE_WRITEV
1455 		struct iovec iov[2];
1456 		iov[0].iov_base = (uint8_t*)&len + c->tcp_byte_count;
1457 		iov[0].iov_len = sizeof(uint16_t) - c->tcp_byte_count;
1458 		iov[1].iov_base = sldns_buffer_begin(buffer);
1459 		iov[1].iov_len = sldns_buffer_limit(buffer);
1460 		log_assert(iov[0].iov_len > 0);
1461 		log_assert(iov[1].iov_len > 0);
1462 		r = writev(fd, iov, 2);
1463 #else /* HAVE_WRITEV */
1464 		r = send(fd, (void*)(((uint8_t*)&len)+c->tcp_byte_count),
1465 			sizeof(uint16_t)-c->tcp_byte_count, 0);
1466 #endif /* HAVE_WRITEV */
1467 		if(r == -1) {
1468 #ifndef USE_WINSOCK
1469 #  ifdef EPIPE
1470                 	if(errno == EPIPE && verbosity < 2)
1471                         	return 0; /* silence 'broken pipe' */
1472   #endif
1473 			if(errno == EINTR || errno == EAGAIN)
1474 				return 1;
1475 #  ifdef HAVE_WRITEV
1476 			log_err_addr("tcp writev", strerror(errno),
1477 				&c->repinfo.addr, c->repinfo.addrlen);
1478 #  else /* HAVE_WRITEV */
1479 			log_err_addr("tcp send s", strerror(errno),
1480 				&c->repinfo.addr, c->repinfo.addrlen);
1481 #  endif /* HAVE_WRITEV */
1482 #else
1483 			if(WSAGetLastError() == WSAENOTCONN)
1484 				return 1;
1485 			if(WSAGetLastError() == WSAEINPROGRESS)
1486 				return 1;
1487 			if(WSAGetLastError() == WSAEWOULDBLOCK) {
1488 				ub_winsock_tcp_wouldblock(c->ev->ev,
1489 					UB_EV_WRITE);
1490 				return 1;
1491 			}
1492 			log_err_addr("tcp send s",
1493 				wsa_strerror(WSAGetLastError()),
1494 				&c->repinfo.addr, c->repinfo.addrlen);
1495 #endif
1496 			return 0;
1497 		}
1498 		c->tcp_byte_count += r;
1499 		if(c->tcp_byte_count < sizeof(uint16_t))
1500 			return 1;
1501 		sldns_buffer_set_position(buffer, c->tcp_byte_count -
1502 			sizeof(uint16_t));
1503 		if(sldns_buffer_remaining(buffer) == 0) {
1504 			tcp_callback_writer(c);
1505 			return 1;
1506 		}
1507 	}
1508 	log_assert(sldns_buffer_remaining(buffer) > 0);
1509 	r = send(fd, (void*)sldns_buffer_current(buffer),
1510 		sldns_buffer_remaining(buffer), 0);
1511 	if(r == -1) {
1512 #ifndef USE_WINSOCK
1513 		if(errno == EINTR || errno == EAGAIN)
1514 			return 1;
1515 		log_err_addr("tcp send r", strerror(errno),
1516 			&c->repinfo.addr, c->repinfo.addrlen);
1517 #else
1518 		if(WSAGetLastError() == WSAEINPROGRESS)
1519 			return 1;
1520 		if(WSAGetLastError() == WSAEWOULDBLOCK) {
1521 			ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
1522 			return 1;
1523 		}
1524 		log_err_addr("tcp send r", wsa_strerror(WSAGetLastError()),
1525 			&c->repinfo.addr, c->repinfo.addrlen);
1526 #endif
1527 		return 0;
1528 	}
1529 	sldns_buffer_skip(buffer, r);
1530 
1531 	if(sldns_buffer_remaining(buffer) == 0) {
1532 		tcp_callback_writer(c);
1533 	}
1534 
1535 	return 1;
1536 }
1537 
1538 void
1539 comm_point_tcp_handle_callback(int fd, short event, void* arg)
1540 {
1541 	struct comm_point* c = (struct comm_point*)arg;
1542 	log_assert(c->type == comm_tcp);
1543 	ub_comm_base_now(c->ev->base);
1544 
1545 #ifdef USE_DNSCRYPT
1546 	/* Initialize if this is a dnscrypt socket */
1547 	if(c->tcp_parent) {
1548 		c->dnscrypt = c->tcp_parent->dnscrypt;
1549 	}
1550 	if(c->dnscrypt && c->dnscrypt_buffer == c->buffer) {
1551 		c->dnscrypt_buffer = sldns_buffer_new(sldns_buffer_capacity(c->buffer));
1552 		if(!c->dnscrypt_buffer) {
1553 			log_err("Could not allocate dnscrypt buffer");
1554 			reclaim_tcp_handler(c);
1555 			if(!c->tcp_do_close) {
1556 				fptr_ok(fptr_whitelist_comm_point(
1557 					c->callback));
1558 				(void)(*c->callback)(c, c->cb_arg,
1559 					NETEVENT_CLOSED, NULL);
1560 			}
1561 			return;
1562 		}
1563 	}
1564 #endif
1565 
1566 	if(event&UB_EV_READ) {
1567 		if(!comm_point_tcp_handle_read(fd, c, 0)) {
1568 			reclaim_tcp_handler(c);
1569 			if(!c->tcp_do_close) {
1570 				fptr_ok(fptr_whitelist_comm_point(
1571 					c->callback));
1572 				(void)(*c->callback)(c, c->cb_arg,
1573 					NETEVENT_CLOSED, NULL);
1574 			}
1575 		}
1576 		return;
1577 	}
1578 	if(event&UB_EV_WRITE) {
1579 		if(!comm_point_tcp_handle_write(fd, c)) {
1580 			reclaim_tcp_handler(c);
1581 			if(!c->tcp_do_close) {
1582 				fptr_ok(fptr_whitelist_comm_point(
1583 					c->callback));
1584 				(void)(*c->callback)(c, c->cb_arg,
1585 					NETEVENT_CLOSED, NULL);
1586 			}
1587 		}
1588 		return;
1589 	}
1590 	if(event&UB_EV_TIMEOUT) {
1591 		verbose(VERB_QUERY, "tcp took too long, dropped");
1592 		reclaim_tcp_handler(c);
1593 		if(!c->tcp_do_close) {
1594 			fptr_ok(fptr_whitelist_comm_point(c->callback));
1595 			(void)(*c->callback)(c, c->cb_arg,
1596 				NETEVENT_TIMEOUT, NULL);
1597 		}
1598 		return;
1599 	}
1600 	log_err("Ignored event %d for tcphdl.", event);
1601 }
1602 
1603 void comm_point_local_handle_callback(int fd, short event, void* arg)
1604 {
1605 	struct comm_point* c = (struct comm_point*)arg;
1606 	log_assert(c->type == comm_local);
1607 	ub_comm_base_now(c->ev->base);
1608 
1609 	if(event&UB_EV_READ) {
1610 		if(!comm_point_tcp_handle_read(fd, c, 1)) {
1611 			fptr_ok(fptr_whitelist_comm_point(c->callback));
1612 			(void)(*c->callback)(c, c->cb_arg, NETEVENT_CLOSED,
1613 				NULL);
1614 		}
1615 		return;
1616 	}
1617 	log_err("Ignored event %d for localhdl.", event);
1618 }
1619 
1620 void comm_point_raw_handle_callback(int ATTR_UNUSED(fd),
1621 	short event, void* arg)
1622 {
1623 	struct comm_point* c = (struct comm_point*)arg;
1624 	int err = NETEVENT_NOERROR;
1625 	log_assert(c->type == comm_raw);
1626 	ub_comm_base_now(c->ev->base);
1627 
1628 	if(event&UB_EV_TIMEOUT)
1629 		err = NETEVENT_TIMEOUT;
1630 	fptr_ok(fptr_whitelist_comm_point_raw(c->callback));
1631 	(void)(*c->callback)(c, c->cb_arg, err, NULL);
1632 }
1633 
1634 struct comm_point*
1635 comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
1636 	comm_point_callback_type* callback, void* callback_arg)
1637 {
1638 	struct comm_point* c = (struct comm_point*)calloc(1,
1639 		sizeof(struct comm_point));
1640 	short evbits;
1641 	if(!c)
1642 		return NULL;
1643 	c->ev = (struct internal_event*)calloc(1,
1644 		sizeof(struct internal_event));
1645 	if(!c->ev) {
1646 		free(c);
1647 		return NULL;
1648 	}
1649 	c->ev->base = base;
1650 	c->fd = fd;
1651 	c->buffer = buffer;
1652 	c->timeout = NULL;
1653 	c->tcp_is_reading = 0;
1654 	c->tcp_byte_count = 0;
1655 	c->tcp_parent = NULL;
1656 	c->max_tcp_count = 0;
1657 	c->cur_tcp_count = 0;
1658 	c->tcp_handlers = NULL;
1659 	c->tcp_free = NULL;
1660 	c->type = comm_udp;
1661 	c->tcp_do_close = 0;
1662 	c->do_not_close = 0;
1663 	c->tcp_do_toggle_rw = 0;
1664 	c->tcp_check_nb_connect = 0;
1665 #ifdef USE_MSG_FASTOPEN
1666 	c->tcp_do_fastopen = 0;
1667 #endif
1668 #ifdef USE_DNSCRYPT
1669 	c->dnscrypt = 0;
1670 	c->dnscrypt_buffer = buffer;
1671 #endif
1672 	c->inuse = 0;
1673 	c->callback = callback;
1674 	c->cb_arg = callback_arg;
1675 	evbits = UB_EV_READ | UB_EV_PERSIST;
1676 	/* ub_event stuff */
1677 	c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
1678 		comm_point_udp_callback, c);
1679 	if(c->ev->ev == NULL) {
1680 		log_err("could not baseset udp event");
1681 		comm_point_delete(c);
1682 		return NULL;
1683 	}
1684 	if(fd!=-1 && ub_event_add(c->ev->ev, c->timeout) != 0 ) {
1685 		log_err("could not add udp event");
1686 		comm_point_delete(c);
1687 		return NULL;
1688 	}
1689 	return c;
1690 }
1691 
1692 struct comm_point*
1693 comm_point_create_udp_ancil(struct comm_base *base, int fd,
1694 	sldns_buffer* buffer,
1695 	comm_point_callback_type* callback, void* callback_arg)
1696 {
1697 	struct comm_point* c = (struct comm_point*)calloc(1,
1698 		sizeof(struct comm_point));
1699 	short evbits;
1700 	if(!c)
1701 		return NULL;
1702 	c->ev = (struct internal_event*)calloc(1,
1703 		sizeof(struct internal_event));
1704 	if(!c->ev) {
1705 		free(c);
1706 		return NULL;
1707 	}
1708 	c->ev->base = base;
1709 	c->fd = fd;
1710 	c->buffer = buffer;
1711 	c->timeout = NULL;
1712 	c->tcp_is_reading = 0;
1713 	c->tcp_byte_count = 0;
1714 	c->tcp_parent = NULL;
1715 	c->max_tcp_count = 0;
1716 	c->cur_tcp_count = 0;
1717 	c->tcp_handlers = NULL;
1718 	c->tcp_free = NULL;
1719 	c->type = comm_udp;
1720 	c->tcp_do_close = 0;
1721 	c->do_not_close = 0;
1722 #ifdef USE_DNSCRYPT
1723 	c->dnscrypt = 0;
1724 	c->dnscrypt_buffer = buffer;
1725 #endif
1726 	c->inuse = 0;
1727 	c->tcp_do_toggle_rw = 0;
1728 	c->tcp_check_nb_connect = 0;
1729 #ifdef USE_MSG_FASTOPEN
1730 	c->tcp_do_fastopen = 0;
1731 #endif
1732 	c->callback = callback;
1733 	c->cb_arg = callback_arg;
1734 	evbits = UB_EV_READ | UB_EV_PERSIST;
1735 	/* ub_event stuff */
1736 	c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
1737 		comm_point_udp_ancil_callback, c);
1738 	if(c->ev->ev == NULL) {
1739 		log_err("could not baseset udp event");
1740 		comm_point_delete(c);
1741 		return NULL;
1742 	}
1743 	if(fd!=-1 && ub_event_add(c->ev->ev, c->timeout) != 0 ) {
1744 		log_err("could not add udp event");
1745 		comm_point_delete(c);
1746 		return NULL;
1747 	}
1748 	return c;
1749 }
1750 
1751 static struct comm_point*
1752 comm_point_create_tcp_handler(struct comm_base *base,
1753 	struct comm_point* parent, size_t bufsize,
1754         comm_point_callback_type* callback, void* callback_arg)
1755 {
1756 	struct comm_point* c = (struct comm_point*)calloc(1,
1757 		sizeof(struct comm_point));
1758 	short evbits;
1759 	if(!c)
1760 		return NULL;
1761 	c->ev = (struct internal_event*)calloc(1,
1762 		sizeof(struct internal_event));
1763 	if(!c->ev) {
1764 		free(c);
1765 		return NULL;
1766 	}
1767 	c->ev->base = base;
1768 	c->fd = -1;
1769 	c->buffer = sldns_buffer_new(bufsize);
1770 	if(!c->buffer) {
1771 		free(c->ev);
1772 		free(c);
1773 		return NULL;
1774 	}
1775 	c->timeout = (struct timeval*)malloc(sizeof(struct timeval));
1776 	if(!c->timeout) {
1777 		sldns_buffer_free(c->buffer);
1778 		free(c->ev);
1779 		free(c);
1780 		return NULL;
1781 	}
1782 	c->tcp_is_reading = 0;
1783 	c->tcp_byte_count = 0;
1784 	c->tcp_parent = parent;
1785 	c->max_tcp_count = 0;
1786 	c->cur_tcp_count = 0;
1787 	c->tcp_handlers = NULL;
1788 	c->tcp_free = NULL;
1789 	c->type = comm_tcp;
1790 	c->tcp_do_close = 0;
1791 	c->do_not_close = 0;
1792 	c->tcp_do_toggle_rw = 1;
1793 	c->tcp_check_nb_connect = 0;
1794 #ifdef USE_MSG_FASTOPEN
1795 	c->tcp_do_fastopen = 0;
1796 #endif
1797 #ifdef USE_DNSCRYPT
1798 	c->dnscrypt = 0;
1799 	/* We don't know just yet if this is a dnscrypt channel. Allocation
1800 	 * will be done when handling the callback. */
1801 	c->dnscrypt_buffer = c->buffer;
1802 #endif
1803 	c->repinfo.c = c;
1804 	c->callback = callback;
1805 	c->cb_arg = callback_arg;
1806 	/* add to parent free list */
1807 	c->tcp_free = parent->tcp_free;
1808 	parent->tcp_free = c;
1809 	/* ub_event stuff */
1810 	evbits = UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT;
1811 	c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
1812 		comm_point_tcp_handle_callback, c);
1813 	if(c->ev->ev == NULL)
1814 	{
1815 		log_err("could not basetset tcphdl event");
1816 		parent->tcp_free = c->tcp_free;
1817 		free(c->ev);
1818 		free(c);
1819 		return NULL;
1820 	}
1821 	return c;
1822 }
1823 
1824 struct comm_point*
1825 comm_point_create_tcp(struct comm_base *base, int fd, int num, size_t bufsize,
1826         comm_point_callback_type* callback, void* callback_arg)
1827 {
1828 	struct comm_point* c = (struct comm_point*)calloc(1,
1829 		sizeof(struct comm_point));
1830 	short evbits;
1831 	int i;
1832 	/* first allocate the TCP accept listener */
1833 	if(!c)
1834 		return NULL;
1835 	c->ev = (struct internal_event*)calloc(1,
1836 		sizeof(struct internal_event));
1837 	if(!c->ev) {
1838 		free(c);
1839 		return NULL;
1840 	}
1841 	c->ev->base = base;
1842 	c->fd = fd;
1843 	c->buffer = NULL;
1844 	c->timeout = NULL;
1845 	c->tcp_is_reading = 0;
1846 	c->tcp_byte_count = 0;
1847 	c->tcp_parent = NULL;
1848 	c->max_tcp_count = num;
1849 	c->cur_tcp_count = 0;
1850 	c->tcp_handlers = (struct comm_point**)calloc((size_t)num,
1851 		sizeof(struct comm_point*));
1852 	if(!c->tcp_handlers) {
1853 		free(c->ev);
1854 		free(c);
1855 		return NULL;
1856 	}
1857 	c->tcp_free = NULL;
1858 	c->type = comm_tcp_accept;
1859 	c->tcp_do_close = 0;
1860 	c->do_not_close = 0;
1861 	c->tcp_do_toggle_rw = 0;
1862 	c->tcp_check_nb_connect = 0;
1863 #ifdef USE_MSG_FASTOPEN
1864 	c->tcp_do_fastopen = 0;
1865 #endif
1866 #ifdef USE_DNSCRYPT
1867 	c->dnscrypt = 0;
1868 	c->dnscrypt_buffer = NULL;
1869 #endif
1870 	c->callback = NULL;
1871 	c->cb_arg = NULL;
1872 	evbits = UB_EV_READ | UB_EV_PERSIST;
1873 	/* ub_event stuff */
1874 	c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
1875 		comm_point_tcp_accept_callback, c);
1876 	if(c->ev->ev == NULL) {
1877 		log_err("could not baseset tcpacc event");
1878 		comm_point_delete(c);
1879 		return NULL;
1880 	}
1881 	if (ub_event_add(c->ev->ev, c->timeout) != 0) {
1882 		log_err("could not add tcpacc event");
1883 		comm_point_delete(c);
1884 		return NULL;
1885 	}
1886 	/* now prealloc the tcp handlers */
1887 	for(i=0; i<num; i++) {
1888 		c->tcp_handlers[i] = comm_point_create_tcp_handler(base,
1889 			c, bufsize, callback, callback_arg);
1890 		if(!c->tcp_handlers[i]) {
1891 			comm_point_delete(c);
1892 			return NULL;
1893 		}
1894 	}
1895 
1896 	return c;
1897 }
1898 
1899 struct comm_point*
1900 comm_point_create_tcp_out(struct comm_base *base, size_t bufsize,
1901         comm_point_callback_type* callback, void* callback_arg)
1902 {
1903 	struct comm_point* c = (struct comm_point*)calloc(1,
1904 		sizeof(struct comm_point));
1905 	short evbits;
1906 	if(!c)
1907 		return NULL;
1908 	c->ev = (struct internal_event*)calloc(1,
1909 		sizeof(struct internal_event));
1910 	if(!c->ev) {
1911 		free(c);
1912 		return NULL;
1913 	}
1914 	c->ev->base = base;
1915 	c->fd = -1;
1916 	c->buffer = sldns_buffer_new(bufsize);
1917 	if(!c->buffer) {
1918 		free(c->ev);
1919 		free(c);
1920 		return NULL;
1921 	}
1922 	c->timeout = NULL;
1923 	c->tcp_is_reading = 0;
1924 	c->tcp_byte_count = 0;
1925 	c->tcp_parent = NULL;
1926 	c->max_tcp_count = 0;
1927 	c->cur_tcp_count = 0;
1928 	c->tcp_handlers = NULL;
1929 	c->tcp_free = NULL;
1930 	c->type = comm_tcp;
1931 	c->tcp_do_close = 0;
1932 	c->do_not_close = 0;
1933 	c->tcp_do_toggle_rw = 1;
1934 	c->tcp_check_nb_connect = 1;
1935 #ifdef USE_MSG_FASTOPEN
1936 	c->tcp_do_fastopen = 1;
1937 #endif
1938 #ifdef USE_DNSCRYPT
1939 	c->dnscrypt = 0;
1940 	c->dnscrypt_buffer = c->buffer;
1941 #endif
1942 	c->repinfo.c = c;
1943 	c->callback = callback;
1944 	c->cb_arg = callback_arg;
1945 	evbits = UB_EV_PERSIST | UB_EV_WRITE;
1946 	c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
1947 		comm_point_tcp_handle_callback, c);
1948 	if(c->ev->ev == NULL)
1949 	{
1950 		log_err("could not baseset tcpout event");
1951 		sldns_buffer_free(c->buffer);
1952 		free(c->ev);
1953 		free(c);
1954 		return NULL;
1955 	}
1956 
1957 	return c;
1958 }
1959 
1960 struct comm_point*
1961 comm_point_create_local(struct comm_base *base, int fd, size_t bufsize,
1962         comm_point_callback_type* callback, void* callback_arg)
1963 {
1964 	struct comm_point* c = (struct comm_point*)calloc(1,
1965 		sizeof(struct comm_point));
1966 	short evbits;
1967 	if(!c)
1968 		return NULL;
1969 	c->ev = (struct internal_event*)calloc(1,
1970 		sizeof(struct internal_event));
1971 	if(!c->ev) {
1972 		free(c);
1973 		return NULL;
1974 	}
1975 	c->ev->base = base;
1976 	c->fd = fd;
1977 	c->buffer = sldns_buffer_new(bufsize);
1978 	if(!c->buffer) {
1979 		free(c->ev);
1980 		free(c);
1981 		return NULL;
1982 	}
1983 	c->timeout = NULL;
1984 	c->tcp_is_reading = 1;
1985 	c->tcp_byte_count = 0;
1986 	c->tcp_parent = NULL;
1987 	c->max_tcp_count = 0;
1988 	c->cur_tcp_count = 0;
1989 	c->tcp_handlers = NULL;
1990 	c->tcp_free = NULL;
1991 	c->type = comm_local;
1992 	c->tcp_do_close = 0;
1993 	c->do_not_close = 1;
1994 	c->tcp_do_toggle_rw = 0;
1995 	c->tcp_check_nb_connect = 0;
1996 #ifdef USE_MSG_FASTOPEN
1997 	c->tcp_do_fastopen = 0;
1998 #endif
1999 #ifdef USE_DNSCRYPT
2000 	c->dnscrypt = 0;
2001 	c->dnscrypt_buffer = c->buffer;
2002 #endif
2003 	c->callback = callback;
2004 	c->cb_arg = callback_arg;
2005 	/* ub_event stuff */
2006 	evbits = UB_EV_PERSIST | UB_EV_READ;
2007 	c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
2008 		comm_point_local_handle_callback, c);
2009 	if(c->ev->ev == NULL) {
2010 		log_err("could not baseset localhdl event");
2011 		free(c->ev);
2012 		free(c);
2013 		return NULL;
2014 	}
2015 	if (ub_event_add(c->ev->ev, c->timeout) != 0) {
2016 		log_err("could not add localhdl event");
2017 		ub_event_free(c->ev->ev);
2018 		free(c->ev);
2019 		free(c);
2020 		return NULL;
2021 	}
2022 	return c;
2023 }
2024 
2025 struct comm_point*
2026 comm_point_create_raw(struct comm_base* base, int fd, int writing,
2027 	comm_point_callback_type* callback, void* callback_arg)
2028 {
2029 	struct comm_point* c = (struct comm_point*)calloc(1,
2030 		sizeof(struct comm_point));
2031 	short evbits;
2032 	if(!c)
2033 		return NULL;
2034 	c->ev = (struct internal_event*)calloc(1,
2035 		sizeof(struct internal_event));
2036 	if(!c->ev) {
2037 		free(c);
2038 		return NULL;
2039 	}
2040 	c->ev->base = base;
2041 	c->fd = fd;
2042 	c->buffer = NULL;
2043 	c->timeout = NULL;
2044 	c->tcp_is_reading = 0;
2045 	c->tcp_byte_count = 0;
2046 	c->tcp_parent = NULL;
2047 	c->max_tcp_count = 0;
2048 	c->cur_tcp_count = 0;
2049 	c->tcp_handlers = NULL;
2050 	c->tcp_free = NULL;
2051 	c->type = comm_raw;
2052 	c->tcp_do_close = 0;
2053 	c->do_not_close = 1;
2054 	c->tcp_do_toggle_rw = 0;
2055 	c->tcp_check_nb_connect = 0;
2056 #ifdef USE_MSG_FASTOPEN
2057 	c->tcp_do_fastopen = 0;
2058 #endif
2059 #ifdef USE_DNSCRYPT
2060 	c->dnscrypt = 0;
2061 	c->dnscrypt_buffer = c->buffer;
2062 #endif
2063 	c->callback = callback;
2064 	c->cb_arg = callback_arg;
2065 	/* ub_event stuff */
2066 	if(writing)
2067 		evbits = UB_EV_PERSIST | UB_EV_WRITE;
2068 	else 	evbits = UB_EV_PERSIST | UB_EV_READ;
2069 	c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
2070 		comm_point_raw_handle_callback, c);
2071 	if(c->ev->ev == NULL) {
2072 		log_err("could not baseset rawhdl event");
2073 		free(c->ev);
2074 		free(c);
2075 		return NULL;
2076 	}
2077 	if (ub_event_add(c->ev->ev, c->timeout) != 0) {
2078 		log_err("could not add rawhdl event");
2079 		ub_event_free(c->ev->ev);
2080 		free(c->ev);
2081 		free(c);
2082 		return NULL;
2083 	}
2084 	return c;
2085 }
2086 
2087 void
2088 comm_point_close(struct comm_point* c)
2089 {
2090 	if(!c)
2091 		return;
2092 	if(c->fd != -1)
2093 		if(ub_event_del(c->ev->ev) != 0) {
2094 			log_err("could not event_del on close");
2095 		}
2096 	/* close fd after removing from event lists, or epoll.. is messed up */
2097 	if(c->fd != -1 && !c->do_not_close) {
2098 		verbose(VERB_ALGO, "close fd %d", c->fd);
2099 #ifndef USE_WINSOCK
2100 		close(c->fd);
2101 #else
2102 		closesocket(c->fd);
2103 #endif
2104 	}
2105 	c->fd = -1;
2106 }
2107 
2108 void
2109 comm_point_delete(struct comm_point* c)
2110 {
2111 	if(!c)
2112 		return;
2113 	if(c->type == comm_tcp && c->ssl) {
2114 #ifdef HAVE_SSL
2115 		SSL_shutdown(c->ssl);
2116 		SSL_free(c->ssl);
2117 #endif
2118 	}
2119 	comm_point_close(c);
2120 	if(c->tcp_handlers) {
2121 		int i;
2122 		for(i=0; i<c->max_tcp_count; i++)
2123 			comm_point_delete(c->tcp_handlers[i]);
2124 		free(c->tcp_handlers);
2125 	}
2126 	free(c->timeout);
2127 	if(c->type == comm_tcp || c->type == comm_local) {
2128 		sldns_buffer_free(c->buffer);
2129 #ifdef USE_DNSCRYPT
2130 		if(c->dnscrypt && c->dnscrypt_buffer != c->buffer) {
2131 			sldns_buffer_free(c->dnscrypt_buffer);
2132 		}
2133 #endif
2134 	}
2135 	ub_event_free(c->ev->ev);
2136 	free(c->ev);
2137 	free(c);
2138 }
2139 
2140 void
2141 comm_point_send_reply(struct comm_reply *repinfo)
2142 {
2143 	struct sldns_buffer* buffer;
2144 	log_assert(repinfo && repinfo->c);
2145 #ifdef USE_DNSCRYPT
2146 	buffer = repinfo->c->dnscrypt_buffer;
2147 	if(!dnsc_handle_uncurved_request(repinfo)) {
2148 		return;
2149 	}
2150 #else
2151 	buffer = repinfo->c->buffer;
2152 #endif
2153 	if(repinfo->c->type == comm_udp) {
2154 		if(repinfo->srctype)
2155 			comm_point_send_udp_msg_if(repinfo->c,
2156 			buffer, (struct sockaddr*)&repinfo->addr,
2157 			repinfo->addrlen, repinfo);
2158 		else
2159 			comm_point_send_udp_msg(repinfo->c, buffer,
2160 			(struct sockaddr*)&repinfo->addr, repinfo->addrlen);
2161 #ifdef USE_DNSTAP
2162 		if(repinfo->c->dtenv != NULL &&
2163 		   repinfo->c->dtenv->log_client_response_messages)
2164 			dt_msg_send_client_response(repinfo->c->dtenv,
2165 			&repinfo->addr, repinfo->c->type, repinfo->c->buffer);
2166 #endif
2167 	} else {
2168 #ifdef USE_DNSTAP
2169 		if(repinfo->c->tcp_parent->dtenv != NULL &&
2170 		   repinfo->c->tcp_parent->dtenv->log_client_response_messages)
2171 			dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv,
2172 			&repinfo->addr, repinfo->c->type, repinfo->c->buffer);
2173 #endif
2174 		comm_point_start_listening(repinfo->c, -1,
2175 			repinfo->c->tcp_timeout_msec);
2176 	}
2177 }
2178 
2179 void
2180 comm_point_drop_reply(struct comm_reply* repinfo)
2181 {
2182 	if(!repinfo)
2183 		return;
2184 	log_assert(repinfo && repinfo->c);
2185 	log_assert(repinfo->c->type != comm_tcp_accept);
2186 	if(repinfo->c->type == comm_udp)
2187 		return;
2188 	reclaim_tcp_handler(repinfo->c);
2189 }
2190 
2191 void
2192 comm_point_stop_listening(struct comm_point* c)
2193 {
2194 	verbose(VERB_ALGO, "comm point stop listening %d", c->fd);
2195 	if(ub_event_del(c->ev->ev) != 0) {
2196 		log_err("event_del error to stoplisten");
2197 	}
2198 }
2199 
2200 void
2201 comm_point_start_listening(struct comm_point* c, int newfd, int msec)
2202 {
2203 	verbose(VERB_ALGO, "comm point start listening %d",
2204 		c->fd==-1?newfd:c->fd);
2205 	if(c->type == comm_tcp_accept && !c->tcp_free) {
2206 		/* no use to start listening no free slots. */
2207 		return;
2208 	}
2209 	if(msec != -1 && msec != 0) {
2210 		if(!c->timeout) {
2211 			c->timeout = (struct timeval*)malloc(sizeof(
2212 				struct timeval));
2213 			if(!c->timeout) {
2214 				log_err("cpsl: malloc failed. No net read.");
2215 				return;
2216 			}
2217 		}
2218 		ub_event_add_bits(c->ev->ev, UB_EV_TIMEOUT);
2219 #ifndef S_SPLINT_S /* splint fails on struct timeval. */
2220 		c->timeout->tv_sec = msec/1000;
2221 		c->timeout->tv_usec = (msec%1000)*1000;
2222 #endif /* S_SPLINT_S */
2223 	}
2224 	if(c->type == comm_tcp) {
2225 		ub_event_del_bits(c->ev->ev, UB_EV_READ|UB_EV_WRITE);
2226 		if(c->tcp_is_reading)
2227 			ub_event_add_bits(c->ev->ev, UB_EV_READ);
2228 		else	ub_event_add_bits(c->ev->ev, UB_EV_WRITE);
2229 	}
2230 	if(newfd != -1) {
2231 		if(c->fd != -1) {
2232 #ifndef USE_WINSOCK
2233 			close(c->fd);
2234 #else
2235 			closesocket(c->fd);
2236 #endif
2237 		}
2238 		c->fd = newfd;
2239 		ub_event_set_fd(c->ev->ev, c->fd);
2240 	}
2241 	if(ub_event_add(c->ev->ev, msec==0?NULL:c->timeout) != 0) {
2242 		log_err("event_add failed. in cpsl.");
2243 	}
2244 }
2245 
2246 void comm_point_listen_for_rw(struct comm_point* c, int rd, int wr)
2247 {
2248 	verbose(VERB_ALGO, "comm point listen_for_rw %d %d", c->fd, wr);
2249 	if(ub_event_del(c->ev->ev) != 0) {
2250 		log_err("event_del error to cplf");
2251 	}
2252 	ub_event_del_bits(c->ev->ev, UB_EV_READ|UB_EV_WRITE);
2253 	if(rd) ub_event_add_bits(c->ev->ev, UB_EV_READ);
2254 	if(wr) ub_event_add_bits(c->ev->ev, UB_EV_WRITE);
2255 	if(ub_event_add(c->ev->ev, c->timeout) != 0) {
2256 		log_err("event_add failed. in cplf.");
2257 	}
2258 }
2259 
2260 size_t comm_point_get_mem(struct comm_point* c)
2261 {
2262 	size_t s;
2263 	if(!c)
2264 		return 0;
2265 	s = sizeof(*c) + sizeof(*c->ev);
2266 	if(c->timeout)
2267 		s += sizeof(*c->timeout);
2268 	if(c->type == comm_tcp || c->type == comm_local) {
2269 		s += sizeof(*c->buffer) + sldns_buffer_capacity(c->buffer);
2270 #ifdef USE_DNSCRYPT
2271 		s += sizeof(*c->dnscrypt_buffer);
2272 		if(c->buffer != c->dnscrypt_buffer) {
2273 			s += sldns_buffer_capacity(c->dnscrypt_buffer);
2274 		}
2275 #endif
2276 	}
2277 	if(c->type == comm_tcp_accept) {
2278 		int i;
2279 		for(i=0; i<c->max_tcp_count; i++)
2280 			s += comm_point_get_mem(c->tcp_handlers[i]);
2281 	}
2282 	return s;
2283 }
2284 
2285 struct comm_timer*
2286 comm_timer_create(struct comm_base* base, void (*cb)(void*), void* cb_arg)
2287 {
2288 	struct internal_timer *tm = (struct internal_timer*)calloc(1,
2289 		sizeof(struct internal_timer));
2290 	if(!tm) {
2291 		log_err("malloc failed");
2292 		return NULL;
2293 	}
2294 	tm->super.ev_timer = tm;
2295 	tm->base = base;
2296 	tm->super.callback = cb;
2297 	tm->super.cb_arg = cb_arg;
2298 	tm->ev = ub_event_new(base->eb->base, -1, UB_EV_TIMEOUT,
2299 		comm_timer_callback, &tm->super);
2300 	if(tm->ev == NULL) {
2301 		log_err("timer_create: event_base_set failed.");
2302 		free(tm);
2303 		return NULL;
2304 	}
2305 	return &tm->super;
2306 }
2307 
2308 void
2309 comm_timer_disable(struct comm_timer* timer)
2310 {
2311 	if(!timer)
2312 		return;
2313 	ub_timer_del(timer->ev_timer->ev);
2314 	timer->ev_timer->enabled = 0;
2315 }
2316 
2317 void
2318 comm_timer_set(struct comm_timer* timer, struct timeval* tv)
2319 {
2320 	log_assert(tv);
2321 	if(timer->ev_timer->enabled)
2322 		comm_timer_disable(timer);
2323 	if(ub_timer_add(timer->ev_timer->ev, timer->ev_timer->base->eb->base,
2324 		comm_timer_callback, timer, tv) != 0)
2325 		log_err("comm_timer_set: evtimer_add failed.");
2326 	timer->ev_timer->enabled = 1;
2327 }
2328 
2329 void
2330 comm_timer_delete(struct comm_timer* timer)
2331 {
2332 	if(!timer)
2333 		return;
2334 	comm_timer_disable(timer);
2335 	/* Free the sub struct timer->ev_timer derived from the super struct timer.
2336 	 * i.e. assert(timer == timer->ev_timer)
2337 	 */
2338 	ub_event_free(timer->ev_timer->ev);
2339 	free(timer->ev_timer);
2340 }
2341 
2342 void
2343 comm_timer_callback(int ATTR_UNUSED(fd), short event, void* arg)
2344 {
2345 	struct comm_timer* tm = (struct comm_timer*)arg;
2346 	if(!(event&UB_EV_TIMEOUT))
2347 		return;
2348 	ub_comm_base_now(tm->ev_timer->base);
2349 	tm->ev_timer->enabled = 0;
2350 	fptr_ok(fptr_whitelist_comm_timer(tm->callback));
2351 	(*tm->callback)(tm->cb_arg);
2352 }
2353 
2354 int
2355 comm_timer_is_set(struct comm_timer* timer)
2356 {
2357 	return (int)timer->ev_timer->enabled;
2358 }
2359 
2360 size_t
2361 comm_timer_get_mem(struct comm_timer* ATTR_UNUSED(timer))
2362 {
2363 	return sizeof(struct internal_timer);
2364 }
2365 
2366 struct comm_signal*
2367 comm_signal_create(struct comm_base* base,
2368         void (*callback)(int, void*), void* cb_arg)
2369 {
2370 	struct comm_signal* com = (struct comm_signal*)malloc(
2371 		sizeof(struct comm_signal));
2372 	if(!com) {
2373 		log_err("malloc failed");
2374 		return NULL;
2375 	}
2376 	com->base = base;
2377 	com->callback = callback;
2378 	com->cb_arg = cb_arg;
2379 	com->ev_signal = NULL;
2380 	return com;
2381 }
2382 
2383 void
2384 comm_signal_callback(int sig, short event, void* arg)
2385 {
2386 	struct comm_signal* comsig = (struct comm_signal*)arg;
2387 	if(!(event & UB_EV_SIGNAL))
2388 		return;
2389 	ub_comm_base_now(comsig->base);
2390 	fptr_ok(fptr_whitelist_comm_signal(comsig->callback));
2391 	(*comsig->callback)(sig, comsig->cb_arg);
2392 }
2393 
2394 int
2395 comm_signal_bind(struct comm_signal* comsig, int sig)
2396 {
2397 	struct internal_signal* entry = (struct internal_signal*)calloc(1,
2398 		sizeof(struct internal_signal));
2399 	if(!entry) {
2400 		log_err("malloc failed");
2401 		return 0;
2402 	}
2403 	log_assert(comsig);
2404 	/* add signal event */
2405 	entry->ev = ub_signal_new(comsig->base->eb->base, sig,
2406 		comm_signal_callback, comsig);
2407 	if(entry->ev == NULL) {
2408 		log_err("Could not create signal event");
2409 		free(entry);
2410 		return 0;
2411 	}
2412 	if(ub_signal_add(entry->ev, NULL) != 0) {
2413 		log_err("Could not add signal handler");
2414 		ub_event_free(entry->ev);
2415 		free(entry);
2416 		return 0;
2417 	}
2418 	/* link into list */
2419 	entry->next = comsig->ev_signal;
2420 	comsig->ev_signal = entry;
2421 	return 1;
2422 }
2423 
2424 void
2425 comm_signal_delete(struct comm_signal* comsig)
2426 {
2427 	struct internal_signal* p, *np;
2428 	if(!comsig)
2429 		return;
2430 	p=comsig->ev_signal;
2431 	while(p) {
2432 		np = p->next;
2433 		ub_signal_del(p->ev);
2434 		ub_event_free(p->ev);
2435 		free(p);
2436 		p = np;
2437 	}
2438 	free(comsig);
2439 }
2440