1/*
2 * dnstap/unbound-dnstap-socket.c - debug program that listens for DNSTAP logs.
3 *
4 * Copyright (c) 2020, 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 program listens on a DNSTAP socket for logged messages.
40 */
41#include "config.h"
42#ifdef HAVE_GETOPT_H
43#include <getopt.h>
44#endif
45#include <signal.h>
46#include <stdlib.h>
47#include <unistd.h>
48#include <signal.h>
49#include <ctype.h>
50#ifdef HAVE_SYS_UN_H
51#include <sys/un.h>
52#endif
53#include <openssl/ssl.h>
54#include <openssl/rand.h>
55#include <openssl/err.h>
56#include "dnstap/dtstream.h"
57#include "dnstap/dnstap_fstrm.h"
58#include "util/log.h"
59#include "util/ub_event.h"
60#include "util/net_help.h"
61#include "services/listen_dnsport.h"
62#include "sldns/sbuffer.h"
63#include "sldns/wire2str.h"
64#ifdef USE_DNSTAP
65#include <protobuf-c/protobuf-c.h>
66#include "dnstap/dnstap.pb-c.h"
67#endif /* USE_DNSTAP */
68#include "util/config_file.h"
69
70/** listen backlog on TCP connections for dnstap logs */
71#define LISTEN_BACKLOG 16
72
73/** usage information for streamtcp */
74static void usage(char* argv[])
75{
76	printf("usage: %s [options]\n", argv[0]);
77	printf(" 	Listen to dnstap messages\n");
78	printf("stdout has dnstap log, stderr has verbose server log\n");
79	printf("-u <socketpath> listen to unix socket with this file name\n");
80	printf("-s <serverip[@port]> listen for TCP on the IP and port\n");
81	printf("-t <serverip[@port]> listen for TLS on IP and port\n");
82	printf("-x <server.key> server key file for TLS service\n");
83	printf("-y <server.pem> server cert file for TLS service\n");
84	printf("-z <verify.pem> cert file to verify client connections\n");
85	printf("-l 		long format for DNS printout\n");
86	printf("-v 		more verbose log output\n");
87	printf("-h 		this help text\n");
88	exit(1);
89}
90
91/** long format option, for multiline printout per message */
92static int longformat = 0;
93
94struct tap_socket_list;
95struct tap_socket;
96/** main tap callback data */
97struct main_tap_data {
98	/** the event base (to loopexit) */
99	struct ub_event_base* base;
100	/** the list of accept sockets */
101	struct tap_socket_list* acceptlist;
102};
103
104/** tap callback variables */
105struct tap_data {
106	/** the fd */
107	int fd;
108	/** the ub event */
109	struct ub_event* ev;
110	/** the SSL for TLS streams */
111	SSL* ssl;
112	/** is the ssl handshake done */
113	int ssl_handshake_done;
114	/** we are briefly waiting to write (in the struct event) */
115	int ssl_brief_write;
116	/** string that identifies the socket (or NULL), like IP address */
117	char* id;
118	/** have we read the length, and how many bytes of it */
119	int len_done;
120	/** have we read the data, and how many bytes of it */
121	size_t data_done;
122	/** are we reading a control frame */
123	int control_frame;
124	/** are we bi-directional (if false, uni-directional) */
125	int is_bidirectional;
126	/** data of the frame */
127	uint8_t* frame;
128	/** length of this frame */
129	size_t len;
130};
131
132/** list of sockets */
133struct tap_socket_list {
134	/** next in list */
135	struct tap_socket_list* next;
136	/** the socket */
137	struct tap_socket* s;
138};
139
140/** tap socket */
141struct tap_socket {
142	/** fd of socket */
143	int fd;
144	/** the event for it */
145	struct ub_event *ev;
146	/** has the event been added */
147	int ev_added;
148	/** the callback, for the event, ev_cb(fd, bits, arg) */
149	void (*ev_cb)(int, short, void*);
150	/** data element, (arg for the tap_socket struct) */
151	void* data;
152	/** socketpath, if this is an AF_LOCAL socket */
153	char* socketpath;
154	/** IP, if this is a TCP socket */
155	char* ip;
156	/** for a TLS socket, the tls context */
157	SSL_CTX* sslctx;
158};
159
160/** del the tap event */
161static void tap_socket_delev(struct tap_socket* s)
162{
163	if(!s) return;
164	if(!s->ev) return;
165	if(!s->ev_added) return;
166	ub_event_del(s->ev);
167	s->ev_added = 0;
168}
169
170/** close the tap socket */
171static void tap_socket_close(struct tap_socket* s)
172{
173	if(!s) return;
174	if(s->fd == -1) return;
175	close(s->fd);
176	s->fd = -1;
177}
178
179/** delete tap socket */
180static void tap_socket_delete(struct tap_socket* s)
181{
182	if(!s) return;
183#ifdef HAVE_SSL
184	SSL_CTX_free(s->sslctx);
185#endif
186	ub_event_free(s->ev);
187	free(s->socketpath);
188	free(s->ip);
189	free(s);
190}
191
192/** create new socket (unconnected, not base-added), or NULL malloc fail */
193static struct tap_socket* tap_socket_new_local(char* socketpath,
194	void (*ev_cb)(int, short, void*), void* data)
195{
196	struct tap_socket* s = calloc(1, sizeof(*s));
197	if(!s) {
198		log_err("malloc failure");
199		return NULL;
200	}
201	s->socketpath = strdup(socketpath);
202	if(!s->socketpath) {
203		free(s);
204		log_err("malloc failure");
205		return NULL;
206	}
207	s->fd = -1;
208	s->ev_cb = ev_cb;
209	s->data = data;
210	return s;
211}
212
213/** create new socket (unconnected, not base-added), or NULL malloc fail */
214static struct tap_socket* tap_socket_new_tcpaccept(char* ip,
215	void (*ev_cb)(int, short, void*), void* data)
216{
217	struct tap_socket* s = calloc(1, sizeof(*s));
218	if(!s) {
219		log_err("malloc failure");
220		return NULL;
221	}
222	s->ip = strdup(ip);
223	if(!s->ip) {
224		free(s);
225		log_err("malloc failure");
226		return NULL;
227	}
228	s->fd = -1;
229	s->ev_cb = ev_cb;
230	s->data = data;
231	return s;
232}
233
234/** create new socket (unconnected, not base-added), or NULL malloc fail */
235static struct tap_socket* tap_socket_new_tlsaccept(char* ip,
236	void (*ev_cb)(int, short, void*), void* data, char* server_key,
237	char* server_cert, char* verifypem)
238{
239	struct tap_socket* s = calloc(1, sizeof(*s));
240	if(!s) {
241		log_err("malloc failure");
242		return NULL;
243	}
244	s->ip = strdup(ip);
245	if(!s->ip) {
246		free(s);
247		log_err("malloc failure");
248		return NULL;
249	}
250	s->fd = -1;
251	s->ev_cb = ev_cb;
252	s->data = data;
253	s->sslctx = listen_sslctx_create(server_key, server_cert, verifypem);
254	if(!s->sslctx) {
255		log_err("could not create ssl context");
256		free(s->ip);
257		free(s);
258		return NULL;
259	}
260	return s;
261}
262
263/** setup tcp accept socket on IP string */
264static int make_tcp_accept(char* ip)
265{
266#ifdef SO_REUSEADDR
267	int on = 1;
268#endif
269	struct sockaddr_storage addr;
270	socklen_t len;
271	int s;
272
273	memset(&addr, 0, sizeof(addr));
274	len = (socklen_t)sizeof(addr);
275	if(!extstrtoaddr(ip, &addr, &len)) {
276		log_err("could not parse IP '%s'", ip);
277		return -1;
278	}
279
280	if((s = socket(addr.ss_family, SOCK_STREAM, 0)) == -1) {
281		log_err("can't create socket: %s", sock_strerror(errno));
282		return -1;
283	}
284#ifdef SO_REUSEADDR
285	if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on,
286		(socklen_t)sizeof(on)) < 0) {
287		log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s",
288			sock_strerror(errno));
289		sock_close(s);
290		return -1;
291	}
292#endif /* SO_REUSEADDR */
293	if(bind(s, (struct sockaddr*)&addr, len) != 0) {
294		log_err_addr("can't bind socket", sock_strerror(errno),
295			&addr, len);
296		sock_close(s);
297		return -1;
298	}
299	if(!fd_set_nonblock(s)) {
300		sock_close(s);
301		return -1;
302	}
303	if(listen(s, LISTEN_BACKLOG) == -1) {
304		log_err("can't listen: %s", sock_strerror(errno));
305		sock_close(s);
306		return -1;
307	}
308	return s;
309}
310
311/** setup socket on event base */
312static int tap_socket_setup(struct tap_socket* s, struct ub_event_base* base)
313{
314	if(s->socketpath) {
315		/* AF_LOCAL accept socket */
316		s->fd = create_local_accept_sock(s->socketpath, NULL, 0);
317		if(s->fd == -1) {
318			log_err("could not create local socket");
319			return 0;
320		}
321	} else if(s->ip || s->sslctx) {
322		/* TCP accept socket */
323		s->fd = make_tcp_accept(s->ip);
324		if(s->fd == -1) {
325			log_err("could not create tcp socket");
326			return 0;
327		}
328	}
329	s->ev = ub_event_new(base, s->fd, UB_EV_READ | UB_EV_PERSIST,
330		s->ev_cb, s);
331	if(!s->ev) {
332		log_err("could not ub_event_new");
333		return 0;
334	}
335	if(ub_event_add(s->ev, NULL) != 0) {
336		log_err("could not ub_event_add");
337		return 0;
338	}
339	s->ev_added = 1;
340	return 1;
341}
342
343/** add tap socket to list */
344static int tap_socket_list_insert(struct tap_socket_list** liststart,
345	struct tap_socket* s)
346{
347	struct tap_socket_list* entry = (struct tap_socket_list*)
348		malloc(sizeof(*entry));
349	if(!entry)
350		return 0;
351	entry->next = *liststart;
352	entry->s = s;
353	*liststart = entry;
354	return 1;
355}
356
357/** delete the list */
358static void tap_socket_list_delete(struct tap_socket_list* list)
359{
360	struct tap_socket_list* e = list, *next;
361	while(e) {
362		next = e->next;
363		tap_socket_delev(e->s);
364		tap_socket_close(e->s);
365		tap_socket_delete(e->s);
366		free(e);
367		e = next;
368	}
369}
370
371/** setup accept events */
372static int tap_socket_list_addevs(struct tap_socket_list* list,
373	struct ub_event_base* base)
374{
375	struct tap_socket_list* entry;
376	for(entry = list; entry; entry = entry->next) {
377		if(!tap_socket_setup(entry->s, base)) {
378			log_err("could not setup socket");
379			return 0;
380		}
381	}
382	return 1;
383}
384
385#ifdef USE_DNSTAP
386/** log control frame contents */
387static void log_control_frame(uint8_t* pkt, size_t len)
388{
389	char* desc;
390	if(verbosity == 0) return;
391	desc = fstrm_describe_control(pkt, len);
392	if(!desc) {
393		log_err("out of memory");
394		return;
395	}
396	log_info("control frame %s", desc);
397	free(desc);
398}
399
400/** convert mtype to string */
401static const char* mtype_to_str(enum _Dnstap__Message__Type mtype)
402{
403	switch(mtype) {
404		case DNSTAP__MESSAGE__TYPE__AUTH_QUERY:
405			return "AUTH_QUERY";
406		case DNSTAP__MESSAGE__TYPE__AUTH_RESPONSE:
407			return "AUTH_RESPONSE";
408		case DNSTAP__MESSAGE__TYPE__RESOLVER_QUERY:
409			return "RESOLVER_QUERY";
410		case DNSTAP__MESSAGE__TYPE__RESOLVER_RESPONSE:
411			return "RESOLVER_RESPONSE";
412		case DNSTAP__MESSAGE__TYPE__CLIENT_QUERY:
413			return "CLIENT_QUERY";
414		case DNSTAP__MESSAGE__TYPE__CLIENT_RESPONSE:
415			return "CLIENT_RESPONSE";
416		case DNSTAP__MESSAGE__TYPE__FORWARDER_QUERY:
417			return "FORWARDER_QUERY";
418		case DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE:
419			return "FORWARDER_RESPONSE";
420		case DNSTAP__MESSAGE__TYPE__STUB_QUERY:
421			return "STUB_QUERY";
422		case DNSTAP__MESSAGE__TYPE__STUB_RESPONSE:
423			return "STUB_RESPONSE";
424		default: break;
425	}
426	return "unknown_message_type";
427}
428
429/** convert type address to a string ip4 or ip6, malloced or NULL on fail */
430static char* str_of_addr(ProtobufCBinaryData address)
431{
432	char buf[64];
433	socklen_t len = sizeof(buf);
434	if(address.len == 4) {
435		if(inet_ntop(AF_INET, address.data, buf, len)!=0)
436			return strdup(buf);
437	} else if(address.len == 16) {
438		if(inet_ntop(AF_INET6, address.data, buf, len)!=0)
439			return strdup(buf);
440	}
441	return NULL;
442}
443
444/** convert message buffer (of dns bytes) to the first qname, type, class,
445 * malloced or NULL on fail */
446static char* q_of_msg(ProtobufCBinaryData message)
447{
448	char buf[300];
449	/* header, name, type, class minimum to get the query tuple */
450	if(message.len < 12 + 1 + 4 + 4) return NULL;
451	if(sldns_wire2str_rrquestion_buf(message.data+12, message.len-12,
452		buf, sizeof(buf)) != 0) {
453		/* remove trailing newline, tabs to spaces */
454		/* remove the newline: */
455		if(buf[0] != 0) buf[strlen(buf)-1]=0;
456		/* remove first tab (before type) */
457		if(strrchr(buf, '\t')) *strrchr(buf, '\t')=' ';
458		/* remove second tab (before class) */
459		if(strrchr(buf, '\t')) *strrchr(buf, '\t')=' ';
460		return strdup(buf);
461	}
462	return NULL;
463}
464
465/** convert possible string or hex data to string. malloced or NULL */
466static char* possible_str(ProtobufCBinaryData str)
467{
468	int is_str = 1;
469	size_t i;
470	for(i=0; i<str.len; i++) {
471		if(!isprint((unsigned char)str.data[i]))
472			is_str = 0;
473	}
474	if(is_str) {
475		char* res = malloc(str.len+1);
476		if(res) {
477			memmove(res, str.data, str.len);
478			res[str.len] = 0;
479			return res;
480		}
481	} else {
482		const char* hex = "0123456789ABCDEF";
483		char* res = malloc(str.len*2+1);
484		if(res) {
485			for(i=0; i<str.len; i++) {
486				res[i*2] = hex[(str.data[i]&0xf0)>>4];
487				res[i*2+1] = hex[str.data[i]&0x0f];
488			}
489			res[str.len*2] = 0;
490			return res;
491		}
492	}
493	return NULL;
494}
495
496/** convert timeval to string, malloced or NULL */
497static char* tv_to_str(protobuf_c_boolean has_time_sec, uint64_t time_sec,
498	protobuf_c_boolean has_time_nsec, uint32_t time_nsec)
499{
500	char buf[64], buf2[256];
501	struct timeval tv;
502	time_t time_t_sec;
503	memset(&tv, 0, sizeof(tv));
504	if(has_time_sec) tv.tv_sec = time_sec;
505	if(has_time_nsec) tv.tv_usec = time_nsec;
506
507	buf[0]=0;
508	time_t_sec = tv.tv_sec;
509	(void)ctime_r(&time_t_sec, buf);
510	snprintf(buf2, sizeof(buf2), "%u.%9.9u %s",
511		(unsigned)time_sec, (unsigned)time_nsec, buf);
512	return strdup(buf2);
513}
514
515/** log data frame contents */
516static void log_data_frame(uint8_t* pkt, size_t len)
517{
518	Dnstap__Dnstap* d = dnstap__dnstap__unpack(NULL, len, pkt);
519	const char* mtype = NULL;
520	char* maddr=NULL, *qinf=NULL;
521	if(!d) {
522		log_err("could not unpack");
523		return;
524	}
525	if(d->base.descriptor != &dnstap__dnstap__descriptor) {
526		log_err("wrong base descriptor");
527		dnstap__dnstap__free_unpacked(d, NULL);
528		return;
529	}
530	if(d->type != DNSTAP__DNSTAP__TYPE__MESSAGE) {
531		log_err("dnstap type not type_message");
532		dnstap__dnstap__free_unpacked(d, NULL);
533		return;
534	}
535	if(d->message) {
536		mtype = mtype_to_str(d->message->type);
537		if(d->message->has_query_address)
538			maddr = str_of_addr(d->message->query_address);
539		else if(d->message->has_response_address)
540			maddr = str_of_addr(d->message->response_address);
541		if(d->message->has_query_message)
542			qinf = q_of_msg(d->message->query_message);
543		else if(d->message->has_response_message)
544			qinf = q_of_msg(d->message->response_message);
545
546	} else {
547		mtype = "nomessage";
548	}
549
550	printf("%s%s%s%s%s\n", mtype, (maddr?" ":""), (maddr?maddr:""),
551		(qinf?" ":""), (qinf?qinf:""));
552	free(maddr);
553	free(qinf);
554
555	if(longformat) {
556		char* id=NULL, *vs=NULL;
557		if(d->has_identity) {
558			id=possible_str(d->identity);
559		}
560		if(d->has_version) {
561			vs=possible_str(d->version);
562		}
563		if(id || vs)
564			printf("identity: %s%s%s\n", (id?id:""),
565				(id&&vs?" ":""), (vs?vs:""));
566		free(id);
567		free(vs);
568
569		if(d->message && d->message->has_query_message &&
570			d->message->query_message.data) {
571			char* qmsg = sldns_wire2str_pkt(
572				d->message->query_message.data,
573				d->message->query_message.len);
574			if(qmsg) {
575				printf("query_message:\n%s", qmsg);
576				free(qmsg);
577			}
578		}
579		if(d->message && d->message->has_query_time_sec) {
580			char* qtv = tv_to_str(d->message->has_query_time_sec,
581				d->message->query_time_sec,
582				d->message->has_query_time_nsec,
583				d->message->query_time_nsec);
584			if(qtv) {
585				printf("query_time: %s\n", qtv);
586				free(qtv);
587			}
588		}
589		if(d->message && d->message->has_response_message &&
590			d->message->response_message.data) {
591			char* rmsg = sldns_wire2str_pkt(
592				d->message->response_message.data,
593				d->message->response_message.len);
594			if(rmsg) {
595				printf("response_message:\n%s", rmsg);
596				free(rmsg);
597			}
598		}
599		if(d->message && d->message->has_response_time_sec) {
600			char* rtv = tv_to_str(d->message->has_response_time_sec,
601				d->message->response_time_sec,
602				d->message->has_response_time_nsec,
603				d->message->response_time_nsec);
604			if(rtv) {
605				printf("response_time: %s\n", rtv);
606				free(rtv);
607			}
608		}
609	}
610	fflush(stdout);
611	dnstap__dnstap__free_unpacked(d, NULL);
612}
613#endif /* USE_DNSTAP */
614
615/** receive bytes from fd, prints errors if bad,
616 * returns 0: closed/error, -1: continue, >0 number of bytes */
617static ssize_t receive_bytes(struct tap_data* data, int fd, void* buf,
618	size_t len)
619{
620	ssize_t ret = recv(fd, buf, len, 0);
621	if(ret == 0) {
622		/* closed */
623		if(verbosity) log_info("dnstap client stream closed from %s",
624			(data->id?data->id:""));
625		return 0;
626	} else if(ret == -1) {
627		/* error */
628#ifndef USE_WINSOCK
629		if(errno == EINTR || errno == EAGAIN)
630			return -1;
631#else /* USE_WINSOCK */
632		if(WSAGetLastError() == WSAEINPROGRESS)
633			return -1;
634		if(WSAGetLastError() == WSAEWOULDBLOCK) {
635			ub_winsock_tcp_wouldblock(data->ev, UB_EV_READ);
636			return -1;
637		}
638#endif
639		log_err("could not recv: %s", sock_strerror(errno));
640		if(verbosity) log_info("dnstap client stream closed from %s",
641			(data->id?data->id:""));
642		return 0;
643	}
644	return ret;
645}
646
647/* define routine for have_ssl only to avoid unused function warning */
648#ifdef HAVE_SSL
649/** set to wait briefly for a write event, for one event call */
650static void tap_enable_brief_write(struct tap_data* data)
651{
652	ub_event_del(data->ev);
653	ub_event_del_bits(data->ev, UB_EV_READ);
654	ub_event_add_bits(data->ev, UB_EV_WRITE);
655	if(ub_event_add(data->ev, NULL) != 0)
656		log_err("could not ub_event_add in tap_enable_brief_write");
657	data->ssl_brief_write = 1;
658}
659#endif /* HAVE_SSL */
660
661/* define routine for have_ssl only to avoid unused function warning */
662#ifdef HAVE_SSL
663/** stop the brief wait for a write event. back to reading. */
664static void tap_disable_brief_write(struct tap_data* data)
665{
666	ub_event_del(data->ev);
667	ub_event_del_bits(data->ev, UB_EV_WRITE);
668	ub_event_add_bits(data->ev, UB_EV_READ);
669	if(ub_event_add(data->ev, NULL) != 0)
670		log_err("could not ub_event_add in tap_disable_brief_write");
671	data->ssl_brief_write = 0;
672}
673#endif /* HAVE_SSL */
674
675#ifdef HAVE_SSL
676/** receive bytes over ssl stream, prints errors if bad,
677 * returns 0: closed/error, -1: continue, >0 number of bytes */
678static ssize_t ssl_read_bytes(struct tap_data* data, void* buf, size_t len)
679{
680	int r;
681	ERR_clear_error();
682	r = SSL_read(data->ssl, buf, len);
683	if(r <= 0) {
684		int want = SSL_get_error(data->ssl, r);
685		if(want == SSL_ERROR_ZERO_RETURN) {
686			/* closed */
687			if(verbosity) log_info("dnstap client stream closed from %s",
688				(data->id?data->id:""));
689			return 0;
690		} else if(want == SSL_ERROR_WANT_READ) {
691			/* continue later */
692			return -1;
693		} else if(want == SSL_ERROR_WANT_WRITE) {
694			/* set to briefly write */
695			tap_enable_brief_write(data);
696			return -1;
697		} else if(want == SSL_ERROR_SYSCALL) {
698#ifdef ECONNRESET
699			if(errno == ECONNRESET && verbosity < 2)
700				return 0; /* silence reset by peer */
701#endif
702			if(errno != 0)
703				log_err("SSL_read syscall: %s",
704					strerror(errno));
705			if(verbosity) log_info("dnstap client stream closed from %s",
706				(data->id?data->id:""));
707			return 0;
708		}
709		log_crypto_err("could not SSL_read");
710		if(verbosity) log_info("dnstap client stream closed from %s",
711			(data->id?data->id:""));
712		return 0;
713	}
714	return r;
715}
716#endif /* HAVE_SSL */
717
718/** receive bytes on the tap connection, prints errors if bad,
719 * returns 0: closed/error, -1: continue, >0 number of bytes */
720static ssize_t tap_receive(struct tap_data* data, void* buf, size_t len)
721{
722#ifdef HAVE_SSL
723	if(data->ssl)
724		return ssl_read_bytes(data, buf, len);
725#endif
726	return receive_bytes(data, data->fd, buf, len);
727}
728
729/** delete the tap structure */
730static void tap_data_free(struct tap_data* data)
731{
732	ub_event_del(data->ev);
733	ub_event_free(data->ev);
734#ifdef HAVE_SSL
735	SSL_free(data->ssl);
736#endif
737	close(data->fd);
738	free(data->id);
739	free(data->frame);
740	free(data);
741}
742
743/** reply with ACCEPT control frame to bidirectional client,
744 * returns 0 on error */
745static int reply_with_accept(struct tap_data* data)
746{
747#ifdef USE_DNSTAP
748	/* len includes the escape and framelength */
749	int r;
750	size_t len = 0;
751	void* acceptframe = fstrm_create_control_frame_accept(
752		DNSTAP_CONTENT_TYPE, &len);
753	if(!acceptframe) {
754		log_err("out of memory");
755		return 0;
756	}
757
758	fd_set_block(data->fd);
759	if(data->ssl) {
760		if((r=SSL_write(data->ssl, acceptframe, len)) <= 0) {
761			if(SSL_get_error(data->ssl, r) == SSL_ERROR_ZERO_RETURN)
762				log_err("SSL_write, peer closed connection");
763			else
764				log_err("could not SSL_write");
765			fd_set_nonblock(data->fd);
766			free(acceptframe);
767			return 0;
768		}
769	} else {
770		if(send(data->fd, acceptframe, len, 0) == -1) {
771			log_err("send failed: %s", sock_strerror(errno));
772			fd_set_nonblock(data->fd);
773			free(acceptframe);
774			return 0;
775		}
776	}
777	if(verbosity) log_info("sent control frame(accept) content-type:(%s)",
778			DNSTAP_CONTENT_TYPE);
779
780	fd_set_nonblock(data->fd);
781	free(acceptframe);
782	return 1;
783#else
784	log_err("no dnstap compiled, no reply");
785	(void)data;
786	return 0;
787#endif
788}
789
790/** reply with FINISH control frame to bidirectional client,
791 * returns 0 on error */
792static int reply_with_finish(int fd)
793{
794#ifdef USE_DNSTAP
795	size_t len = 0;
796	void* finishframe = fstrm_create_control_frame_finish(&len);
797	if(!finishframe) {
798		log_err("out of memory");
799		return 0;
800	}
801
802	fd_set_block(fd);
803	if(send(fd, finishframe, len, 0) == -1) {
804		log_err("send failed: %s", sock_strerror(errno));
805		fd_set_nonblock(fd);
806		free(finishframe);
807		return 0;
808	}
809	if(verbosity) log_info("sent control frame(finish)");
810
811	fd_set_nonblock(fd);
812	free(finishframe);
813	return 1;
814#else
815	log_err("no dnstap compiled, no reply");
816	(void)fd;
817	return 0;
818#endif
819}
820
821#ifdef HAVE_SSL
822/** check SSL peer certificate, return 0 on fail */
823static int tap_check_peer(struct tap_data* data)
824{
825	if((SSL_get_verify_mode(data->ssl)&SSL_VERIFY_PEER)) {
826		/* verification */
827		if(SSL_get_verify_result(data->ssl) == X509_V_OK) {
828			X509* x = SSL_get_peer_certificate(data->ssl);
829			if(!x) {
830				if(verbosity) log_info("SSL connection %s"
831					" failed no certificate", data->id);
832				return 0;
833			}
834			if(verbosity)
835				log_cert(VERB_ALGO, "peer certificate", x);
836#ifdef HAVE_SSL_GET0_PEERNAME
837			if(SSL_get0_peername(data->ssl)) {
838				if(verbosity) log_info("SSL connection %s "
839					"to %s authenticated", data->id,
840					SSL_get0_peername(data->ssl));
841			} else {
842#endif
843				if(verbosity) log_info("SSL connection %s "
844					"authenticated", data->id);
845#ifdef HAVE_SSL_GET0_PEERNAME
846			}
847#endif
848			X509_free(x);
849		} else {
850			X509* x = SSL_get_peer_certificate(data->ssl);
851			if(x) {
852				if(verbosity)
853					log_cert(VERB_ALGO, "peer certificate", x);
854				X509_free(x);
855			}
856			if(verbosity) log_info("SSL connection %s failed: "
857				"failed to authenticate", data->id);
858			return 0;
859		}
860	} else {
861		/* unauthenticated, the verify peer flag was not set
862		 * in ssl when the ssl object was created from ssl_ctx */
863		if(verbosity) log_info("SSL connection %s", data->id);
864	}
865	return 1;
866}
867#endif /* HAVE_SSL */
868
869#ifdef HAVE_SSL
870/** perform SSL handshake, return 0 to wait for events, 1 if done */
871static int tap_handshake(struct tap_data* data)
872{
873	int r;
874	if(data->ssl_brief_write) {
875		/* write condition has been satisfied, back to reading */
876		tap_disable_brief_write(data);
877	}
878	if(data->ssl_handshake_done)
879		return 1;
880
881	ERR_clear_error();
882	r = SSL_do_handshake(data->ssl);
883	if(r != 1) {
884		int want = SSL_get_error(data->ssl, r);
885		if(want == SSL_ERROR_WANT_READ) {
886			return 0;
887		} else if(want == SSL_ERROR_WANT_WRITE) {
888			tap_enable_brief_write(data);
889			return 0;
890		} else if(r == 0) {
891			/* closed */
892			tap_data_free(data);
893			return 0;
894		} else if(want == SSL_ERROR_SYSCALL) {
895			/* SYSCALL and errno==0 means closed uncleanly */
896			int silent = 0;
897#ifdef EPIPE
898			if(errno == EPIPE && verbosity < 2)
899				silent = 1; /* silence 'broken pipe' */
900#endif
901#ifdef ECONNRESET
902			if(errno == ECONNRESET && verbosity < 2)
903				silent = 1; /* silence reset by peer */
904#endif
905			if(errno == 0)
906				silent = 1;
907			if(!silent)
908				log_err("SSL_handshake syscall: %s",
909					strerror(errno));
910			tap_data_free(data);
911			return 0;
912		} else {
913			unsigned long err = ERR_get_error();
914			if(!squelch_err_ssl_handshake(err)) {
915				log_crypto_err_code("ssl handshake failed",
916					err);
917				verbose(VERB_OPS, "ssl handshake failed "
918					"from %s", data->id);
919			}
920			tap_data_free(data);
921			return 0;
922		}
923	}
924	/* check peer verification */
925	data->ssl_handshake_done = 1;
926	if(!tap_check_peer(data)) {
927		/* closed */
928		tap_data_free(data);
929		return 0;
930	}
931	return 1;
932}
933#endif /* HAVE_SSL */
934
935/** callback for dnstap listener */
936void dtio_tap_callback(int fd, short ATTR_UNUSED(bits), void* arg)
937{
938	struct tap_data* data = (struct tap_data*)arg;
939	if(verbosity>=3) log_info("tap callback");
940#ifdef HAVE_SSL
941	if(data->ssl && (!data->ssl_handshake_done ||
942		data->ssl_brief_write)) {
943		if(!tap_handshake(data))
944			return;
945	}
946#endif
947	while(data->len_done < 4) {
948		uint32_t l = (uint32_t)data->len;
949		ssize_t ret = tap_receive(data,
950			((uint8_t*)&l)+data->len_done, 4-data->len_done);
951		if(verbosity>=4) log_info("s recv %d", (int)ret);
952		if(ret == 0) {
953			/* closed or error */
954			tap_data_free(data);
955			return;
956		} else if(ret == -1) {
957			/* continue later */
958			return;
959		}
960		data->len_done += ret;
961		data->len = (size_t)l;
962		if(data->len_done < 4)
963			return; /* continue later */
964		data->len = (size_t)(ntohl(l));
965		if(verbosity>=3) log_info("length is %d", (int)data->len);
966		if(data->len == 0) {
967			/* it is a control frame */
968			data->control_frame = 1;
969			/* read controlframelen */
970			data->len_done = 0;
971		} else {
972			/* allocate frame size */
973			data->frame = calloc(1, data->len);
974			if(!data->frame) {
975				log_err("out of memory");
976				tap_data_free(data);
977				return;
978			}
979		}
980	}
981
982	/* we want to read the full length now */
983	if(data->data_done < data->len) {
984		ssize_t r = tap_receive(data, data->frame + data->data_done,
985			data->len - data->data_done);
986		if(verbosity>=4) log_info("f recv %d", (int)r);
987		if(r == 0) {
988			/* closed or error */
989			tap_data_free(data);
990			return;
991		} else if(r == -1) {
992			/* continue later */
993			return;
994		}
995		data->data_done += r;
996		if(data->data_done < data->len)
997			return; /* continue later */
998	}
999
1000	/* we are done with a frame */
1001	if(verbosity>=3) log_info("received %sframe len %d",
1002		(data->control_frame?"control ":""), (int)data->len);
1003#ifdef USE_DNSTAP
1004	if(data->control_frame)
1005		log_control_frame(data->frame, data->len);
1006	else	log_data_frame(data->frame, data->len);
1007#endif
1008
1009	if(data->len >= 4 && sldns_read_uint32(data->frame) ==
1010		FSTRM_CONTROL_FRAME_READY) {
1011		data->is_bidirectional = 1;
1012		if(verbosity) log_info("bidirectional stream");
1013		if(!reply_with_accept(data)) {
1014			tap_data_free(data);
1015		}
1016	} else if(data->len >= 4 && sldns_read_uint32(data->frame) ==
1017		FSTRM_CONTROL_FRAME_STOP && data->is_bidirectional) {
1018		if(!reply_with_finish(fd)) {
1019			tap_data_free(data);
1020			return;
1021		}
1022	}
1023
1024	/* prepare for next frame */
1025	free(data->frame);
1026	data->frame = NULL;
1027	data->control_frame = 0;
1028	data->len = 0;
1029	data->len_done = 0;
1030	data->data_done = 0;
1031
1032}
1033
1034/** callback for main listening file descriptor */
1035void dtio_mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg)
1036{
1037	struct tap_socket* tap_sock = (struct tap_socket*)arg;
1038	struct main_tap_data* maindata = (struct main_tap_data*)
1039		tap_sock->data;
1040	struct tap_data* data;
1041	char* id = NULL;
1042	struct sockaddr_storage addr;
1043	socklen_t addrlen = (socklen_t)sizeof(addr);
1044	int s = accept(fd, (struct sockaddr*)&addr, &addrlen);
1045	if(s == -1) {
1046#ifndef USE_WINSOCK
1047		/* EINTR is signal interrupt. others are closed connection. */
1048		if(     errno == EINTR || errno == EAGAIN
1049#ifdef EWOULDBLOCK
1050			|| errno == EWOULDBLOCK
1051#endif
1052#ifdef ECONNABORTED
1053			|| errno == ECONNABORTED
1054#endif
1055#ifdef EPROTO
1056			|| errno == EPROTO
1057#endif /* EPROTO */
1058			)
1059			return;
1060#else /* USE_WINSOCK */
1061		if(WSAGetLastError() == WSAEINPROGRESS ||
1062			WSAGetLastError() == WSAECONNRESET)
1063			return;
1064		if(WSAGetLastError() == WSAEWOULDBLOCK) {
1065			ub_winsock_tcp_wouldblock(maindata->ev, UB_EV_READ);
1066			return;
1067		}
1068#endif
1069		log_err_addr("accept failed", sock_strerror(errno), &addr,
1070			addrlen);
1071		return;
1072	}
1073	fd_set_nonblock(s);
1074	if(verbosity) {
1075		if(addr.ss_family == AF_LOCAL) {
1076#ifdef HAVE_SYS_UN_H
1077			struct sockaddr_un* usock = calloc(1, sizeof(struct sockaddr_un) + 1);
1078			if(usock) {
1079				socklen_t ulen = sizeof(struct sockaddr_un);
1080				if(getsockname(fd, (struct sockaddr*)usock, &ulen) != -1) {
1081					log_info("accepted new dnstap client from %s", usock->sun_path);
1082					id = strdup(usock->sun_path);
1083				} else {
1084					log_info("accepted new dnstap client");
1085				}
1086				free(usock);
1087			} else {
1088				log_info("accepted new dnstap client");
1089			}
1090#endif /* HAVE_SYS_UN_H */
1091		} else if(addr.ss_family == AF_INET ||
1092			addr.ss_family == AF_INET6) {
1093			char ip[256];
1094			addr_to_str(&addr, addrlen, ip, sizeof(ip));
1095			log_info("accepted new dnstap client from %s", ip);
1096			id = strdup(ip);
1097		} else {
1098			log_info("accepted new dnstap client");
1099		}
1100	}
1101
1102	data = calloc(1, sizeof(*data));
1103	if(!data) fatal_exit("out of memory");
1104	data->fd = s;
1105	data->id = id;
1106	if(tap_sock->sslctx) {
1107		data->ssl = incoming_ssl_fd(tap_sock->sslctx, data->fd);
1108		if(!data->ssl) fatal_exit("could not SSL_new");
1109	}
1110	data->ev = ub_event_new(maindata->base, s, UB_EV_READ | UB_EV_PERSIST,
1111		&dtio_tap_callback, data);
1112	if(!data->ev) fatal_exit("could not ub_event_new");
1113	if(ub_event_add(data->ev, NULL) != 0) fatal_exit("could not ub_event_add");
1114}
1115
1116/** setup local accept sockets */
1117static void setup_local_list(struct main_tap_data* maindata,
1118	struct config_strlist_head* local_list)
1119{
1120	struct config_strlist* item;
1121	for(item = local_list->first; item; item = item->next) {
1122		struct tap_socket* s;
1123		s = tap_socket_new_local(item->str, &dtio_mainfdcallback,
1124			maindata);
1125		if(!s) fatal_exit("out of memory");
1126		if(!tap_socket_list_insert(&maindata->acceptlist, s))
1127			fatal_exit("out of memory");
1128	}
1129}
1130
1131/** setup tcp accept sockets */
1132static void setup_tcp_list(struct main_tap_data* maindata,
1133	struct config_strlist_head* tcp_list)
1134{
1135	struct config_strlist* item;
1136	for(item = tcp_list->first; item; item = item->next) {
1137		struct tap_socket* s;
1138		s = tap_socket_new_tcpaccept(item->str, &dtio_mainfdcallback,
1139			maindata);
1140		if(!s) fatal_exit("out of memory");
1141		if(!tap_socket_list_insert(&maindata->acceptlist, s))
1142			fatal_exit("out of memory");
1143	}
1144}
1145
1146/** setup tls accept sockets */
1147static void setup_tls_list(struct main_tap_data* maindata,
1148	struct config_strlist_head* tls_list, char* server_key,
1149	char* server_cert, char* verifypem)
1150{
1151	struct config_strlist* item;
1152	for(item = tls_list->first; item; item = item->next) {
1153		struct tap_socket* s;
1154		s = tap_socket_new_tlsaccept(item->str, &dtio_mainfdcallback,
1155			maindata, server_key, server_cert, verifypem);
1156		if(!s) fatal_exit("out of memory");
1157		if(!tap_socket_list_insert(&maindata->acceptlist, s))
1158			fatal_exit("out of memory");
1159	}
1160}
1161
1162/** signal variable */
1163static struct ub_event_base* sig_base = NULL;
1164/** do we have to quit */
1165int sig_quit = 0;
1166/** signal handler for user quit */
1167static RETSIGTYPE main_sigh(int sig)
1168{
1169	if(!sig_quit)
1170		fprintf(stderr, "exit on signal %d\n", sig);
1171	if(sig_base) {
1172		ub_event_base_loopexit(sig_base);
1173		sig_base = NULL;
1174	}
1175	sig_quit = 1;
1176}
1177
1178/** setup and run the server to listen to DNSTAP messages */
1179static void
1180setup_and_run(struct config_strlist_head* local_list,
1181	struct config_strlist_head* tcp_list,
1182	struct config_strlist_head* tls_list, char* server_key,
1183	char* server_cert, char* verifypem)
1184{
1185	time_t secs = 0;
1186	struct timeval now;
1187	struct main_tap_data* maindata;
1188	struct ub_event_base* base;
1189	const char *evnm="event", *evsys="", *evmethod="";
1190
1191	maindata = calloc(1, sizeof(*maindata));
1192	if(!maindata) fatal_exit("out of memory");
1193	memset(&now, 0, sizeof(now));
1194	base = ub_default_event_base(1, &secs, &now);
1195	if(!base) fatal_exit("could not create ub_event base");
1196	maindata->base = base;
1197	sig_base = base;
1198	if(sig_quit) {
1199		ub_event_base_free(base);
1200		free(maindata);
1201		return;
1202	}
1203	ub_get_event_sys(base, &evnm, &evsys, &evmethod);
1204	if(verbosity) log_info("%s %s uses %s method", evnm, evsys, evmethod);
1205
1206	setup_local_list(maindata, local_list);
1207	setup_tcp_list(maindata, tcp_list);
1208	setup_tls_list(maindata, tls_list, server_key, server_cert,
1209		verifypem);
1210	if(!tap_socket_list_addevs(maindata->acceptlist, base))
1211		fatal_exit("could not setup accept events");
1212	if(verbosity) log_info("start of service");
1213
1214	ub_event_base_dispatch(base);
1215	sig_base = NULL;
1216
1217	if(verbosity) log_info("end of service");
1218	tap_socket_list_delete(maindata->acceptlist);
1219	ub_event_base_free(base);
1220	free(maindata);
1221}
1222
1223/** getopt global, in case header files fail to declare it. */
1224extern int optind;
1225/** getopt global, in case header files fail to declare it. */
1226extern char* optarg;
1227
1228/** main program for streamtcp */
1229int main(int argc, char** argv)
1230{
1231	int c;
1232	int usessl = 0;
1233	struct config_strlist_head local_list;
1234	struct config_strlist_head tcp_list;
1235	struct config_strlist_head tls_list;
1236	char* server_key = NULL, *server_cert = NULL, *verifypem = NULL;
1237#ifdef USE_WINSOCK
1238	WSADATA wsa_data;
1239	if(WSAStartup(MAKEWORD(2,2), &wsa_data) != 0) {
1240		printf("WSAStartup failed\n");
1241		return 1;
1242	}
1243#endif
1244	if(signal(SIGINT, main_sigh) == SIG_ERR ||
1245#ifdef SIGQUIT
1246		signal(SIGQUIT, main_sigh) == SIG_ERR ||
1247#endif
1248#ifdef SIGHUP
1249		signal(SIGHUP, main_sigh) == SIG_ERR ||
1250#endif
1251#ifdef SIGBREAK
1252		signal(SIGBREAK, main_sigh) == SIG_ERR ||
1253#endif
1254		signal(SIGTERM, main_sigh) == SIG_ERR)
1255		fatal_exit("could not bind to signal");
1256	memset(&local_list, 0, sizeof(local_list));
1257	memset(&tcp_list, 0, sizeof(tcp_list));
1258	memset(&tls_list, 0, sizeof(tls_list));
1259
1260	/* lock debug start (if any) */
1261	log_ident_set("unbound-dnstap-socket");
1262	log_init(0, 0, 0);
1263	checklock_start();
1264
1265#ifdef SIGPIPE
1266	if(signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
1267		perror("could not install signal handler for SIGPIPE");
1268		return 1;
1269	}
1270#endif
1271
1272	/* command line options */
1273	while( (c=getopt(argc, argv, "hls:t:u:vx:y:z:")) != -1) {
1274		switch(c) {
1275			case 'u':
1276				if(!cfg_strlist_append(&local_list,
1277					strdup(optarg)))
1278					fatal_exit("out of memory");
1279				break;
1280			case 's':
1281				if(!cfg_strlist_append(&tcp_list,
1282					strdup(optarg)))
1283					fatal_exit("out of memory");
1284				break;
1285			case 't':
1286				if(!cfg_strlist_append(&tls_list,
1287					strdup(optarg)))
1288					fatal_exit("out of memory");
1289				usessl = 1;
1290				break;
1291			case 'x':
1292				server_key = optarg;
1293				usessl = 1;
1294				break;
1295			case 'y':
1296				server_cert = optarg;
1297				usessl = 1;
1298				break;
1299			case 'z':
1300				verifypem = optarg;
1301				usessl = 1;
1302				break;
1303			case 'l':
1304				longformat = 1;
1305				break;
1306			case 'v':
1307				verbosity++;
1308				break;
1309			case 'h':
1310			case '?':
1311			default:
1312				usage(argv);
1313		}
1314	}
1315	argc -= optind;
1316	argv += optind;
1317
1318	if(usessl) {
1319#ifdef HAVE_SSL
1320#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
1321		ERR_load_SSL_strings();
1322#endif
1323#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
1324#  ifndef S_SPLINT_S
1325		OpenSSL_add_all_algorithms();
1326#  endif
1327#else
1328		OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
1329			| OPENSSL_INIT_ADD_ALL_DIGESTS
1330			| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
1331#endif
1332#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
1333		(void)SSL_library_init();
1334#else
1335		(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
1336#endif
1337#endif /* HAVE_SSL */
1338	}
1339	setup_and_run(&local_list, &tcp_list, &tls_list, server_key,
1340		server_cert, verifypem);
1341	config_delstrlist(local_list.first);
1342	config_delstrlist(tcp_list.first);
1343	config_delstrlist(tls_list.first);
1344
1345	checklock_stop();
1346#ifdef USE_WINSOCK
1347	WSACleanup();
1348#endif
1349	return 0;
1350}
1351
1352/***--- definitions to make fptr_wlist work. ---***/
1353/* These are callbacks, similar to smallapp callbacks, except the debug
1354 * tool callbacks are not in it */
1355struct tube;
1356struct query_info;
1357#include "util/data/packed_rrset.h"
1358#include "daemon/worker.h"
1359#include "daemon/remote.h"
1360#include "util/fptr_wlist.h"
1361#include "libunbound/context.h"
1362
1363void worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
1364	uint8_t* ATTR_UNUSED(buffer), size_t ATTR_UNUSED(len),
1365	int ATTR_UNUSED(error), void* ATTR_UNUSED(arg))
1366{
1367	log_assert(0);
1368}
1369
1370int worker_handle_request(struct comm_point* ATTR_UNUSED(c),
1371	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
1372        struct comm_reply* ATTR_UNUSED(repinfo))
1373{
1374	log_assert(0);
1375	return 0;
1376}
1377
1378int worker_handle_reply(struct comm_point* ATTR_UNUSED(c),
1379	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
1380        struct comm_reply* ATTR_UNUSED(reply_info))
1381{
1382	log_assert(0);
1383	return 0;
1384}
1385
1386int worker_handle_service_reply(struct comm_point* ATTR_UNUSED(c),
1387	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
1388        struct comm_reply* ATTR_UNUSED(reply_info))
1389{
1390	log_assert(0);
1391	return 0;
1392}
1393
1394int remote_accept_callback(struct comm_point* ATTR_UNUSED(c),
1395	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
1396        struct comm_reply* ATTR_UNUSED(repinfo))
1397{
1398	log_assert(0);
1399	return 0;
1400}
1401
1402int remote_control_callback(struct comm_point* ATTR_UNUSED(c),
1403	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
1404        struct comm_reply* ATTR_UNUSED(repinfo))
1405{
1406	log_assert(0);
1407	return 0;
1408}
1409
1410void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg))
1411{
1412	log_assert(0);
1413}
1414
1415struct outbound_entry* worker_send_query(
1416	struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags),
1417	int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
1418	int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
1419	socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
1420	size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream),
1421	char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q))
1422{
1423	log_assert(0);
1424	return 0;
1425}
1426
1427#ifdef UB_ON_WINDOWS
1428void
1429worker_win_stop_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), void*
1430	ATTR_UNUSED(arg)) {
1431	log_assert(0);
1432}
1433
1434void
1435wsvc_cron_cb(void* ATTR_UNUSED(arg))
1436{
1437	log_assert(0);
1438}
1439#endif /* UB_ON_WINDOWS */
1440
1441void
1442worker_alloc_cleanup(void* ATTR_UNUSED(arg))
1443{
1444	log_assert(0);
1445}
1446
1447struct outbound_entry* libworker_send_query(
1448	struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags),
1449	int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
1450	int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
1451	socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
1452	size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream),
1453	char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q))
1454{
1455	log_assert(0);
1456	return 0;
1457}
1458
1459int libworker_handle_reply(struct comm_point* ATTR_UNUSED(c),
1460	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
1461        struct comm_reply* ATTR_UNUSED(reply_info))
1462{
1463	log_assert(0);
1464	return 0;
1465}
1466
1467int libworker_handle_service_reply(struct comm_point* ATTR_UNUSED(c),
1468	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
1469        struct comm_reply* ATTR_UNUSED(reply_info))
1470{
1471	log_assert(0);
1472	return 0;
1473}
1474
1475void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
1476        uint8_t* ATTR_UNUSED(buffer), size_t ATTR_UNUSED(len),
1477        int ATTR_UNUSED(error), void* ATTR_UNUSED(arg))
1478{
1479        log_assert(0);
1480}
1481
1482void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
1483	struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
1484	char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
1485{
1486	log_assert(0);
1487}
1488
1489void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
1490	struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
1491	char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
1492{
1493	log_assert(0);
1494}
1495
1496void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
1497	struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
1498	char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
1499{
1500	log_assert(0);
1501}
1502
1503int context_query_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
1504{
1505	log_assert(0);
1506	return 0;
1507}
1508
1509void worker_stat_timer_cb(void* ATTR_UNUSED(arg))
1510{
1511	log_assert(0);
1512}
1513
1514void worker_probe_timer_cb(void* ATTR_UNUSED(arg))
1515{
1516	log_assert(0);
1517}
1518
1519void worker_start_accept(void* ATTR_UNUSED(arg))
1520{
1521	log_assert(0);
1522}
1523
1524void worker_stop_accept(void* ATTR_UNUSED(arg))
1525{
1526	log_assert(0);
1527}
1528
1529/** keep track of lock id in lock-verify application */
1530struct order_id {
1531        /** the thread id that created it */
1532        int thr;
1533        /** the instance number of creation */
1534        int instance;
1535};
1536
1537int order_lock_cmp(const void* e1, const void* e2)
1538{
1539        const struct order_id* o1 = e1;
1540        const struct order_id* o2 = e2;
1541        if(o1->thr < o2->thr) return -1;
1542        if(o1->thr > o2->thr) return 1;
1543        if(o1->instance < o2->instance) return -1;
1544        if(o1->instance > o2->instance) return 1;
1545        return 0;
1546}
1547
1548int
1549codeline_cmp(const void* a, const void* b)
1550{
1551        return strcmp(a, b);
1552}
1553
1554int replay_var_compare(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
1555{
1556        log_assert(0);
1557        return 0;
1558}
1559
1560void remote_get_opt_ssl(char* ATTR_UNUSED(str), void* ATTR_UNUSED(arg))
1561{
1562        log_assert(0);
1563}
1564