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