From b7e08045b18d065e6fbb5055359f1c8b88f22d01 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Mon, 20 Jan 2020 11:04:06 +0100 Subject: [PATCH 01/96] git branch to track feature for framestreams. The aim is to make reconnecting work, TLS support and not depend on the libfstrm library, but keep compatibility with the Frame Streams protocol spec for existing DNSTAP tools. --- Makefile.in | 1 + configure | 4 +- configure.ac | 4 +- dnstap/dtstream.c | 46 +++++++++++++++ dnstap/dtstream.h | 139 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 190 insertions(+), 4 deletions(-) create mode 100644 dnstap/dtstream.c create mode 100644 dnstap/dtstream.h diff --git a/Makefile.in b/Makefile.in index 1a2e2c548..b7961b2b9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1059,6 +1059,7 @@ respip.lo respip.o: $(srcdir)/respip/respip.c config.h $(srcdir)/services/localz $(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/respip/respip.h checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/testcode/checklocks.h +dtstream.lo dtstream.o: $(srcdir)/dnstap/dtstream.c config.h $(srcdir)/dnstap/dtstream.h dnstap.lo dnstap.o: $(srcdir)/dnstap/dnstap.c config.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \ diff --git a/configure b/configure index eb855554d..12d042492 100755 --- a/configure +++ b/configure @@ -20936,9 +20936,9 @@ cat >>confdefs.h <<_ACEOF _ACEOF - DNSTAP_SRC="dnstap/dnstap.c dnstap/dnstap.pb-c.c" + DNSTAP_SRC="dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dtstream.c" - DNSTAP_OBJ="dnstap.lo dnstap.pb-c.lo" + DNSTAP_OBJ="dnstap.lo dnstap.pb-c.lo dtstream.lo" else diff --git a/configure.ac b/configure.ac index 4ed9bb872..e1cddc35d 100644 --- a/configure.ac +++ b/configure.ac @@ -1637,8 +1637,8 @@ dt_DNSTAP([$UNBOUND_RUN_DIR/dnstap.sock], AC_DEFINE_UNQUOTED(DNSTAP_SOCKET_PATH, ["$hdr_dnstap_socket_path"], [default dnstap socket path]) - AC_SUBST([DNSTAP_SRC], ["dnstap/dnstap.c dnstap/dnstap.pb-c.c"]) - AC_SUBST([DNSTAP_OBJ], ["dnstap.lo dnstap.pb-c.lo"]) + AC_SUBST([DNSTAP_SRC], ["dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dtstream.c"]) + AC_SUBST([DNSTAP_OBJ], ["dnstap.lo dnstap.pb-c.lo dtstream.lo"]) ], [ AC_SUBST([ENABLE_DNSTAP], [0]) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c new file mode 100644 index 000000000..cad4d1f48 --- /dev/null +++ b/dnstap/dtstream.c @@ -0,0 +1,46 @@ +/* + * dnstap/dtstream.c - Frame Streams implementation for unbound DNSTAP + * + * Copyright (c) 2020, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** + * \file + * + * An implementation of the Frame Streams data transport protocol for + * the Unbound DNSTAP message logging facility. + */ + +#include "config.h" +#include "dnstap/dtstream.h" + diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h new file mode 100644 index 000000000..1b7af2371 --- /dev/null +++ b/dnstap/dtstream.h @@ -0,0 +1,139 @@ +/* + * dnstap/dtstream.h - Frame Streams implementation for unbound DNSTAP + * + * Copyright (c) 2020, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** + * \file + * + * An implementation of the Frame Streams data transport protocol for + * the Unbound DNSTAP message logging facility. + */ + +#ifndef DTSTREAM_H +#define DTSTREAM_H + +#include "util/locks.h" +struct dt_msg_entry; +struct dt_io_list_item; + +/** + * A message buffer with dnstap messages queued up. It is per-worker. + * It has locks to synchronize. If the buffer is full, a new message + * cannot be added and is discarded. A thread reads the messages and sends + * them. + */ +struct dt_msg_queue { + /** lock of the buffer structure. Hold this lock to add or remove + * entries to the buffer. Release it so that other threads can also + * put messages to log, or a message can be taken out to send away + * by the writer thread. + */ + lock_basic_type lock; + /** the maximum size of the buffer, in bytes */ + size_t maxsize; + /** current size of the buffer, in bytes. data bytes of messages. + * If a new message make it more than maxsize, the buffer is full */ + size_t cursize; + /** list of messages. The messages are added to the back and taken + * out from the front. */ + struct dt_msg_entry* first, *last; +}; + +/** + * An entry in the dt_msg_queue. contains one DNSTAP message. + * It is malloced. + */ +struct dt_msg_entry { + /** next in the list. */ + struct dt_msg_entry* next; + /** the buffer with the data to send, an encoded DNSTAP message */ + void* buf; + /** the length to send. */ + size_t len; +}; + +/** + * IO thread that reads from the queues and writes them. + */ +struct dt_io_thread { + /** event base, for event handling */ + void* event_base; + /** list of queues that is registered to get written */ + struct dt_io_list_item* io_list; + /** file descriptor that the thread writes to */ + int fd; + /** event structure that the thread uses */ + void* event; + + /** command pipe that stops the pipe if closed. Used to quit + * the program. [0] is read, [1] is written to. */ + int commandpipe[2]; + /** the event to listen to the commandpipe */ + void* command_event; + + /** If the log server is connected to over unix domain sockets, + * eg. a file is named that is created to log onto. */ + int upstream_is_unix; + /** if the log server is connected to over TCP. The ip address and + * port are used */ + int upstream_is_tcp; + /** if the log server is connected to over TLS. ip address, port, + * and client certificates can be used for authentication. */ + int upstream_is_tls; + + /** the file path for unix socket (or NULL) */ + char* socket_path; + /** the ip address and port number (or NULL) */ + char* ip_str; + /** is the TLS upstream authenticated by name, if nonNULL, + * we use the same cert bundle as used by other TLS streams. */ + char* tls_server_name; + /** are client certificates in use */ + int use_client_certs; + /** client cert files: the .key file */ + char* client_key_file; + /** client cert files: the .pem file */ + char* client_cert_file; +}; + +/* Frame Streams data transfer protocol encode for DNSTAP messages. + * The protocol looks to be specified in the libfstrm library. + */ +/* routine to send START message. */ +/* routine to send a frame. */ +/* routine to send STOP message. */ + + +#endif /* DTSTREAM_H */ From c6534ac6b3f235bbca89a29ed6b620a6c40c3d6f Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Mon, 20 Jan 2020 11:44:45 +0100 Subject: [PATCH 02/96] Writeup of FrameStreams protocol. --- dnstap/dtstream.h | 58 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 1b7af2371..0edd219ea 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -71,7 +71,7 @@ struct dt_msg_queue { struct dt_msg_entry* first, *last; }; -/** +/** * An entry in the dt_msg_queue. contains one DNSTAP message. * It is malloced. */ @@ -130,8 +130,62 @@ struct dt_io_thread { /* Frame Streams data transfer protocol encode for DNSTAP messages. * The protocol looks to be specified in the libfstrm library. + * + * Quick writeup for DNSTAP usage, from reading fstrm/control.h eloquent + * comments and fstrm/control.c for some bytesize details (the content type + * length). + * + * The Frame Streams can be unidirectional or bi-directional. + * bi-directional streams use control frame types READY, ACCEPT and FINISH. + * uni-directional streams use control frame types START and STOP. + * unknown control frame types should be ignored by the receiver, they + * do not change the data frame encoding. + * + * bi-directional control frames implement a simple handshake protocol + * between sender and receiver. + * + * The uni-directional control frames have one start and one stop frame, + * before and after the data. The start frame can have a content type. + * The start and stop frames are not optional. + * + * data frames are preceded by 4byte length, bigendian. + * zero length data frames are not possible, they are an escape that + * signals the presence of a control frame. + * + * a control frame consists of 0 value in 4byte bigendian, this is really + * the data frame length, with 0 the escape sequence that indicates one + * control frame follows. + * Then, 4byte bigendian, length of the control frame message. + * Then, the control frame payload (of that length). with in it: + * 4byte bigendian, control type (eg. START, STOP, READY, ACCEPT, FINISH). + * perhaps nothing more (STOP, FINISH), but for other types maybe + * content type fields + * 4byte bigendian, the control-field-type, currently only content-type. + * 4byte bigendian, length of the string for this option. + * .. bytes of that string. + * + * The START type can have only one field. Field max len 256. + * control frame max frame length 512 (excludes the 0-escape and control + * frame length bytes). */ -/* routine to send START message. */ + +/** max length of Frame Streams content type field string */ +#define FSTRM_CONTENT_TYPE_LENGTH_MAX 256 +/** control frame value to denote the control frame ACCEPT */ +#define FSTRM_CONTROL_FRAME_ACCEPT 0x01 +/** control frame value to denote the control frame START */ +#define FSTRM_CONTROL_FRAME_START 0x02 +/** control frame value to denote the control frame STOP */ +#define FSTRM_CONTROL_FRAME_STOP 0x03 +/** control frame value to denote the control frame READY */ +#define FSTRM_CONTROL_FRAME_READY 0x04 +/** control frame value to denote the control frame FINISH */ +#define FSTRM_CONTROL_FRAME_FINISH 0x05 +/** the constant that denotes the control field type that is the + * string for the content type of the stream. */ +#define FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE 0x01 + +/* routine to send START message, with content type. */ /* routine to send a frame. */ /* routine to send STOP message. */ From 9285e10fef0a3327e11385b8f3fed7f5f7e27e30 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Mon, 20 Jan 2020 12:12:27 +0100 Subject: [PATCH 03/96] iolist item added. --- dnstap/dtstream.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 0edd219ea..41114c836 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -128,6 +128,17 @@ struct dt_io_thread { char* client_cert_file; }; +/** + * IO thread list of queues list item + * lists a worker queue that should be looked at and sent to the log server. + */ +struct dt_io_list_item { + /** next in the list of buffers to inspect */ + struct dt_io_list_item* next; + /** buffer of this worker */ + struct dt_msg_queue* queue; +}; + /* Frame Streams data transfer protocol encode for DNSTAP messages. * The protocol looks to be specified in the libfstrm library. * @@ -159,7 +170,7 @@ struct dt_io_thread { * Then, the control frame payload (of that length). with in it: * 4byte bigendian, control type (eg. START, STOP, READY, ACCEPT, FINISH). * perhaps nothing more (STOP, FINISH), but for other types maybe - * content type fields + * control fields * 4byte bigendian, the control-field-type, currently only content-type. * 4byte bigendian, length of the string for this option. * .. bytes of that string. From 90a9de9d527f33abc919b36bd0609073f6a83794 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Mon, 20 Jan 2020 15:45:31 +0100 Subject: [PATCH 04/96] unbound-dnstap-socket debug test program. --- .gitignore | 1 + Makefile.in | 16 +- dnstap/dtstream.h | 9 + dnstap/unbound-dnstap-socket.c | 387 +++++++++++++++++++++++++++++++++ 4 files changed, 409 insertions(+), 4 deletions(-) create mode 100644 dnstap/unbound-dnstap-socket.c diff --git a/.gitignore b/.gitignore index 22fedf0d7..6f26d217c 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ /petal /pktview /streamtcp +/unbound-dnstap-socket /testbound /unittest /contrib/libunbound.pc diff --git a/Makefile.in b/Makefile.in index b7961b2b9..65dc20663 100644 --- a/Makefile.in +++ b/Makefile.in @@ -232,6 +232,10 @@ DELAYER_OBJ_LINK=$(DELAYER_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \ $(SLDNS_OBJ) IPSET_SRC=@IPSET_SRC@ IPSET_OBJ=@IPSET_OBJ@ +DNSTAP_SOCKET_SRC=dnstap/unbound-dnstap-socket.c +DNSTAP_SOCKET_OBJ=unbound-dnstap-socket.lo +DNSTAP_SOCKET_OBJ_LINK=$(DNSTAP_SOCKET_OBJ) worker_cb.lo $(COMMON_OBJ) \ +$(COMPAT_OBJ) $(SLDNS_OBJ) LIBUNBOUND_SRC=libunbound/context.c libunbound/libunbound.c \ libunbound/libworker.c LIBUNBOUND_OBJ=context.lo libunbound.lo libworker.lo ub_event_pluggable.lo @@ -258,7 +262,7 @@ ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \ $(TESTBOUND_SRC) $(LOCKVERIFY_SRC) $(PKTVIEW_SRC) \ $(MEMSTATS_SRC) $(CHECKCONF_SRC) $(LIBUNBOUND_SRC) $(HOST_SRC) \ $(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC) \ - $(CONTROL_SRC) $(UBANCHOR_SRC) $(PETAL_SRC) \ + $(CONTROL_SRC) $(UBANCHOR_SRC) $(PETAL_SRC) $(DNSTAP_SOCKET_SRC)\ $(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC) \ $(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC) @@ -266,7 +270,7 @@ ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \ $(TESTBOUND_OBJ) $(LOCKVERIFY_OBJ) $(PKTVIEW_OBJ) \ $(MEMSTATS_OBJ) $(CHECKCONF_OBJ) $(LIBUNBOUND_OBJ) $(HOST_OBJ) \ $(ASYNCLOOK_OBJ) $(STREAMTCP_OBJ) $(PERF_OBJ) $(DELAYER_OBJ) \ - $(CONTROL_OBJ) $(UBANCHOR_OBJ) $(PETAL_OBJ) \ + $(CONTROL_OBJ) $(UBANCHOR_OBJ) $(PETAL_OBJ) $(DNSTAP_SOCKET_OBJ)\ $(COMPAT_OBJ) $(PYUNBOUND_OBJ) \ $(SVCINST_OBJ) $(SVCUNINST_OBJ) $(ANCHORUPD_OBJ) $(SLDNS_OBJ) @@ -305,7 +309,7 @@ rsrc_unbound_checkconf.o: $(srcdir)/winrc/rsrc_unbound_checkconf.rc config.h TEST_BIN=asynclook$(EXEEXT) delayer$(EXEEXT) \ lock-verify$(EXEEXT) memstats$(EXEEXT) perf$(EXEEXT) \ petal$(EXEEXT) pktview$(EXEEXT) streamtcp$(EXEEXT) \ - testbound$(EXEEXT) unittest$(EXEEXT) + testbound$(EXEEXT) unittest$(EXEEXT) unbound-dnstap-socket$(EXEEXT) tests: all $(TEST_BIN) check: test @@ -400,7 +404,12 @@ dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h: $(srcdir)/dnstap/dnstap.proto @-if test ! -d dnstap; then $(INSTALL) -d dnstap; fi $(PROTOC_C) --c_out=. --proto_path=$(srcdir) $(srcdir)/dnstap/dnstap.proto +unbound-dnstap-socket$(EXEEXT): $(DNSTAP_SOCKET_OBJ_LINK) + $(LINK) -o $@ $(DNSTAP_SOCKET_OBJ_LINK) $(SSLLIB) $(LIBS) + dnstap.pb-c.lo dnstap.pb-c.o: dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h +dtstream.lo dtstream.o: $(srcdir)/dnstap/dtstream.c config.h $(srcdir)/dnstap/dtstream.h +unbound-dnstap-socket.lo unbound-dnstap-socket.o: $(srcdir)/dnstap/unbound-dnstap-socket.c config.h $(srcdir)/dnstap/dtstream.h # dnscrypt dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \ @@ -1059,7 +1068,6 @@ respip.lo respip.o: $(srcdir)/respip/respip.c config.h $(srcdir)/services/localz $(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/respip/respip.h checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/testcode/checklocks.h -dtstream.lo dtstream.o: $(srcdir)/dnstap/dtstream.c config.h $(srcdir)/dnstap/dtstream.h dnstap.lo dnstap.o: $(srcdir)/dnstap/dnstap.c config.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \ diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 41114c836..e76264f50 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -178,6 +178,15 @@ struct dt_io_list_item { * The START type can have only one field. Field max len 256. * control frame max frame length 512 (excludes the 0-escape and control * frame length bytes). + * + * the bidirectional type of transmission is like this: + * client sends READY (with content type included), + * client waits for ACCEPT (with content type included), + * client sends START (with matched content type from ACCEPT) + * .. data frames + * client sends STOP. + * client waits for FINISH frame. + * */ /** max length of Frame Streams content type field string */ diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c new file mode 100644 index 000000000..30412fb3b --- /dev/null +++ b/dnstap/unbound-dnstap-socket.c @@ -0,0 +1,387 @@ +/* + * dnstap/unbound-dnstap-socket.c - debug program that listens for DNSTAP logs. + * + * Copyright (c) 2020, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \file + * + * This program listens on a DNSTAP socket for logged messages. + */ +#include "config.h" +#ifdef HAVE_GETOPT_H +#include +#endif +#include +#include +#include +#ifdef HAVE_SYS_UN_H +#include +#endif +#include +#include +#include +#include "dnstap/dtstream.h" +#include "util/log.h" +#include "util/ub_event.h" +#include "util/net_help.h" +#include "services/listen_dnsport.h" + +/** usage information for streamtcp */ +static void usage(char* argv[]) +{ + printf("usage: %s [options]\n", argv[0]); + printf(" Listen to dnstap messages\n"); + printf("-u use unix socket with this file name\n"); + printf("-l long format for DNS printout\n"); + printf("-v more verbose log output\n"); + printf("-h this help text\n"); + exit(1); +} + +/** tap callback variables */ +struct tap_data { + /** the fd */ + int fd; + /** the ub event */ + struct ub_event* ev; + /** have we read the length, and how many bytes of it */ + int len_done; + /** have we read the data, and how many bytes of it */ + size_t data_done; + /** are we bi-directional (if false, uni-directional) */ + int is_bidirectional; + /** are we reading a control frame */ + int control_frame; + /** data of the frame */ + uint8_t* frame; + /** length of this frame */ + size_t len; +}; + +/** receive bytes from fd, prints errors if bad, + * returns 0: closed/error, -1: continue, >0 number of bytes */ +static ssize_t receive_bytes(int fd, void* buf, size_t len) +{ + ssize_t ret = recv(fd, buf, len, 0); + if(ret == 0) { + /* closed */ + if(verbosity) log_info("dnstap client stream closed"); + return 0; + } else if(ret == -1) { + /* error */ +#ifndef USE_WINSOCK + if(errno == EINTR || errno == EAGAIN) + return -1; + log_err("could not recv: %s", strerror(errno)); +#else /* USE_WINSOCK */ + if(WSAGetLastError() == WSAEINPROGRESS) + return -1; + if(WSAGetLastError() == WSAEWOULDBLOCK) { + ub_winsock_tcp_wouldblock(data->ev, + UB_EV_READ); + return -1; + } + log_err("could not recv: %s", + wsa_strerror(WSAGetLastError())); +#endif + if(verbosity) log_info("dnstap client stream closed"); + return 0; + } + return ret; +} + +/** delete the tap structure */ +void tap_data_free(struct tap_data* data) +{ + ub_event_del(data->ev); + ub_event_free(data->ev); + close(data->fd); + free(data->frame); + free(data); +} + +/** callback for dnstap listener */ +static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) +{ + struct tap_data* data = (struct tap_data*)arg; + if(verbosity) log_info("tap callback"); + while(data->len_done < 4) { + uint32_t l = (uint32_t)data->len; + ssize_t ret = receive_bytes(fd, + ((uint8_t*)&l)+data->len_done, 4-data->len_done); + log_info("s recv %d got %d %d", (int)ret, (int)l, (int)ntohl(l)); + if(ret == 0) { + /* closed or error */ + tap_data_free(data); + return; + } else if(ret == -1) { + /* continue later */ + return; + } + data->len_done += ret; + data->len = (size_t)l; + if(data->len_done < 4) + return; /* continue later */ + data->len = (size_t)(ntohl(l)); + if(verbosity) log_info("length is %d", (int)data->len); + if(data->len == 0) { + /* it is a control frame */ + data->control_frame = 1; + /* read controlframelen */ + data->len_done = 0; + } else { + /* allocate frame size */ + data->frame = calloc(1, data->len); + if(!data->frame) { + log_err("out of memory"); + tap_data_free(data); + return; + } + } + } + /* we want to read the full length now */ + if(data->data_done < data->len) { + ssize_t r = receive_bytes(fd, data->frame + data->data_done, + data->len - data->data_done); + if(r == 0) { + /* closed or error */ + tap_data_free(data); + return; + } else if(r == -1) { + /* continue later */ + return; + } + data->data_done += r; + if(data->data_done < data->len) + return; /* continue later */ + } + /* we are done with a frame */ + if(verbosity) log_info("received %sframe len %d", + (data->control_frame?"control ":""), (int)data->len); + if(data->len >= 4 && ntohl(*(uint32_t*)data->frame) == + FSTRM_CONTROL_FRAME_READY) { + data->is_bidirectional = 1; + if(verbosity) log_info("bidirectional stream"); + } + + /* prepare for next frame */ + free(data->frame); + data->frame = NULL; + data->control_frame = 0; + data->len = 0; + data->len_done = 0; + data->data_done = 0; +} + +/** callback for main listening file descriptor */ +void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) +{ + struct tap_data* data; + struct sockaddr_storage addr; + socklen_t addrlen = (socklen_t)sizeof(addr); + struct ub_event_base* base = (struct ub_event_base*)arg; + int s = accept(fd, (struct sockaddr*)&addr, &addrlen); + if(s == -1) { +#ifndef USE_WINSOCK + /* EINTR is signal interrupt. others are closed connection. */ + if( errno == EINTR || errno == EAGAIN +#ifdef EWOULDBLOCK + || errno == EWOULDBLOCK +#endif +#ifdef ECONNABORTED + || errno == ECONNABORTED +#endif +#ifdef EPROTO + || errno == EPROTO +#endif /* EPROTO */ + ) + return; + log_err_addr("accept failed", strerror(errno), &addr, addrlen); +#else /* USE_WINSOCK */ + if(WSAGetLastError() == WSAEINPROGRESS || + WSAGetLastError() == WSAECONNRESET) + return; + if(WSAGetLastError() == WSAEWOULDBLOCK) { + ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ); + return; + } + log_err_addr("accept failed", wsa_strerror(WSAGetLastError()), + addr, *addrlen); +#endif + return; + } + fd_set_nonblock(s); + if(verbosity) { + if(addr.ss_family == AF_LOCAL) { + struct sockaddr_un* usock = calloc(1, sizeof(struct sockaddr_un) + 1); + if(usock) { + socklen_t ulen = sizeof(struct sockaddr_un); + if(getsockname(fd, (struct sockaddr*)usock, &ulen) != -1) { + log_info("accepted new dnstap client from %s", usock->sun_path); + } else { + log_info("accepted new dnstap client"); + } + free(usock); + } else { + log_info("accepted new dnstap client"); + } + } else { + log_info("accepted new dnstap client"); + } + } + + data = calloc(1, sizeof(*data)); + if(!data) fatal_exit("out of memory"); + data->fd = s; + data->ev = ub_event_new(base, s, UB_EV_READ | UB_EV_PERSIST, + &tap_callback, data); + if(!data->ev) fatal_exit("could not ub_event_new"); + if(ub_event_add(data->ev, NULL) != 0) fatal_exit("could not ub_event_add"); +} + +/** create file descriptor to listen on */ +static int +setup_fd(char* socketpath) +{ + return create_local_accept_sock(socketpath, NULL, 0); +} + +/** setup and run the server to listen to DNSTAP messages */ +static void +setup_and_run(char* socketpath, int longformat) +{ + int fd; + time_t secs = 0; + struct timeval now; + struct ub_event_base* base; + const char *evnm="event", *evsys="", *evmethod=""; + struct ub_event *ev; + + memset(&now, 0, sizeof(now)); + base = ub_default_event_base(1, &secs, &now); + if(!base) fatal_exit("could not create ub_event base"); + fd = setup_fd(socketpath); + ub_get_event_sys(base, &evnm, &evsys, &evmethod); + if(verbosity) log_info("%s %s uses %s method", evnm, evsys, evmethod); + ev = ub_event_new(base, fd, UB_EV_READ | UB_EV_PERSIST, + &mainfdcallback, base); + if(!ev) fatal_exit("could not ub_event_new"); + if(ub_event_add(ev, NULL) != 0) fatal_exit("could not ub_event_add"); + + ub_event_base_dispatch(base); + + ub_event_del(ev); + ub_event_free(ev); + ub_event_base_free(base); + close(fd); +} + +/** getopt global, in case header files fail to declare it. */ +extern int optind; +/** getopt global, in case header files fail to declare it. */ +extern char* optarg; + +/** main program for streamtcp */ +int main(int argc, char** argv) +{ + int c; + int usessl = 0, longformat = 0; + char* socketpath = NULL; +#ifdef USE_WINSOCK + WSADATA wsa_data; + if(WSAStartup(MAKEWORD(2,2), &wsa_data) != 0) { + printf("WSAStartup failed\n"); + return 1; + } +#endif + + /* lock debug start (if any) */ + log_ident_set("unbound-dnstap-socket"); + log_init(0, 0, 0); + checklock_start(); + +#ifdef SIGPIPE + if(signal(SIGPIPE, SIG_IGN) == SIG_ERR) { + perror("could not install signal handler for SIGPIPE"); + return 1; + } +#endif + + /* command line options */ + while( (c=getopt(argc, argv, "hlu:v")) != -1) { + switch(c) { + case 'u': + socketpath = optarg; + break; + case 'l': + longformat = 1; + break; + case 'v': + verbosity++; + break; + case 'h': + case '?': + default: + usage(argv); + } + } + argc -= optind; + argv += optind; + + if(usessl) { +#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL) + ERR_load_SSL_strings(); +#endif +#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO) +# ifndef S_SPLINT_S + OpenSSL_add_all_algorithms(); +# endif +#else + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS + | OPENSSL_INIT_ADD_ALL_DIGESTS + | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); +#endif +#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL) + (void)SSL_library_init(); +#else + (void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); +#endif + } + setup_and_run(socketpath, longformat); + checklock_stop(); +#ifdef USE_WINSOCK + WSACleanup(); +#endif + return 0; +} From ac362625c3886d31799ae1854ee98155e0c33e34 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Mon, 20 Jan 2020 17:23:01 +0100 Subject: [PATCH 05/96] dnstap test progam can log on one line type,ip,qname,qtype,qclass --- dnstap/unbound-dnstap-socket.c | 290 +++++++++++++++++++++++++++++++-- 1 file changed, 280 insertions(+), 10 deletions(-) diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index 30412fb3b..4b8ef1dad 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -56,12 +56,19 @@ #include "util/ub_event.h" #include "util/net_help.h" #include "services/listen_dnsport.h" +#include "sldns/sbuffer.h" +#include "sldns/wire2str.h" +#include +#include "dnstap/dnstap.pb-c.h" + +#define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap" /** usage information for streamtcp */ static void usage(char* argv[]) { printf("usage: %s [options]\n", argv[0]); printf(" Listen to dnstap messages\n"); + printf("stdout has dnstap log, stderr has verbose server log\n"); printf("-u use unix socket with this file name\n"); printf("-l long format for DNS printout\n"); printf("-v more verbose log output\n"); @@ -69,6 +76,9 @@ static void usage(char* argv[]) exit(1); } +/** long format option, for multiline printout per message */ +static int longformat = 0; + /** tap callback variables */ struct tap_data { /** the fd */ @@ -79,16 +89,180 @@ struct tap_data { int len_done; /** have we read the data, and how many bytes of it */ size_t data_done; - /** are we bi-directional (if false, uni-directional) */ - int is_bidirectional; /** are we reading a control frame */ int control_frame; + /** are we bi-directional (if false, uni-directional) */ + int is_bidirectional; /** data of the frame */ uint8_t* frame; /** length of this frame */ size_t len; }; +/** log control frame contents */ +static void log_control_frame(uint8_t* pkt, size_t len) +{ + uint32_t frametype = 0; + char buf[256]; + size_t at = 0, remain; + uint8_t* pos; + if(verbosity == 0) return; + if(len < 4) { + log_err("malformed control frame, too short, len=%d", (int)len); + return; + } + buf[0]=0; + frametype = sldns_read_uint32(pkt); + if(frametype == FSTRM_CONTROL_FRAME_ACCEPT) { + at+=snprintf(buf+at, sizeof(buf)-at, "accept"); + } else if(frametype == FSTRM_CONTROL_FRAME_START) { + at+=snprintf(buf+at, sizeof(buf)-at, "start"); + } else if(frametype == FSTRM_CONTROL_FRAME_STOP) { + at+=snprintf(buf+at, sizeof(buf)-at, "stop"); + } else if(frametype == FSTRM_CONTROL_FRAME_READY) { + at+=snprintf(buf+at, sizeof(buf)-at, "ready"); + } else if(frametype == FSTRM_CONTROL_FRAME_FINISH) { + at+=snprintf(buf+at, sizeof(buf)-at, "finish"); + } else { + at+=snprintf(buf+at, sizeof(buf)-at, "type%d", + (int)frametype); + } + + /* show the content type options */ + pos = pkt + 4; + remain = len - 4; + while(remain >= 8) { + uint32_t field_type = sldns_read_uint32(pos); + uint32_t field_len = sldns_read_uint32(pos+4); + if(remain < field_len) { + at+=snprintf(buf+at, sizeof(buf)-at, "malformed_field"); + break; + } + if(field_type == FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE) { + at+=snprintf(buf+at, sizeof(buf)-at, " content-type("); + if(at+field_len < sizeof(buf)) { + memmove(buf+at, pos+8, field_len); + at += field_len; + } + at+=snprintf(buf+at, sizeof(buf)-at, ")"); + } + pos += 8 + field_len; + remain -= (8 + field_len); + } + log_info("control frame %s", buf); +} + +/** convert mtype to string */ +static const char* mtype_to_str(enum _Dnstap__Message__Type mtype) +{ + switch(mtype) { + case DNSTAP__MESSAGE__TYPE__AUTH_QUERY: + return "AUTH_QUERY"; + case DNSTAP__MESSAGE__TYPE__AUTH_RESPONSE: + return "AUTH_RESPONSE"; + case DNSTAP__MESSAGE__TYPE__RESOLVER_QUERY: + return "RESOLVER_QUERY"; + case DNSTAP__MESSAGE__TYPE__RESOLVER_RESPONSE: + return "RESOLVER_RESPONSE"; + case DNSTAP__MESSAGE__TYPE__CLIENT_QUERY: + return "CLIENT_QUERY"; + case DNSTAP__MESSAGE__TYPE__CLIENT_RESPONSE: + return "CLIENT_RESPONSE"; + case DNSTAP__MESSAGE__TYPE__FORWARDER_QUERY: + return "FORWARDER_QUERY"; + case DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE: + return "FORWARDER_RESPONSE"; + case DNSTAP__MESSAGE__TYPE__STUB_QUERY: + return "STUB_QUERY"; + case DNSTAP__MESSAGE__TYPE__STUB_RESPONSE: + return "STUB_RESPONSE"; + default: break; + } + return "unknown_message_type"; +} + +/** convert type address to a string ip4 or ip6, malloced or NULL on fail */ +static char* str_of_addr(ProtobufCBinaryData address) +{ + char buf[64]; + socklen_t len = sizeof(buf); + if(address.len == 4) { + if(inet_ntop(AF_INET, address.data, buf, len)!=0) + return strdup(buf); + } else if(address.len == 16) { + if(inet_ntop(AF_INET6, address.data, buf, len)!=0) + return strdup(buf); + } + return NULL; +} + +/** convert message buffer (of dns bytes) to the first qname, type, class, + * malloced or NULL on fail */ +static char* q_of_msg(ProtobufCBinaryData message) +{ + char buf[300]; + /* header, name, type, class minimum to get the query tuple */ + if(message.len < 12 + 1 + 4 + 4) return NULL; + if(sldns_wire2str_rrquestion_buf(message.data+12, message.len-12, + buf, sizeof(buf)) != 0) { + /* remove trailing newline, tabs to spaces */ + if(buf[0] != 0) buf[strlen(buf)-1]=0; + if(strrchr(buf, '\t')) *strrchr(buf, '\t')=' '; + if(strrchr(buf, '\t')) *strrchr(buf, '\t')=' '; + return strdup(buf); + } + return NULL; +} + +/** log data frame contents */ +static void log_data_frame(uint8_t* pkt, size_t len) +{ + Dnstap__Dnstap* d = dnstap__dnstap__unpack(NULL, len, pkt); + const char* mtype = NULL; + char* maddr=NULL, *qinf=NULL; + if(!d) { + log_err("could not unpack"); + return; + } + if(d->base.descriptor != &dnstap__dnstap__descriptor) { + log_err("wrong base descriptor"); + dnstap__dnstap__free_unpacked(d, NULL); + return; + } + if(d->type != DNSTAP__DNSTAP__TYPE__MESSAGE) { + log_err("dnstap type not type_message"); + dnstap__dnstap__free_unpacked(d, NULL); + return; + } + if(d->message) { + mtype = mtype_to_str(d->message->type); + if(d->message->has_query_address) + maddr = str_of_addr(d->message->query_address); + else if(d->message->has_response_address) + maddr = str_of_addr(d->message->response_address); + if(d->message->has_query_message) + qinf = q_of_msg(d->message->query_message); + else if(d->message->has_response_message) + qinf = q_of_msg(d->message->response_message); + + } else { + mtype = "nomessage"; + } + + printf("%s%s%s%s%s\n", mtype, (maddr?" ":""), (maddr?maddr:""), + (qinf?" ":""), (qinf?qinf:"")); + free(maddr); + free(qinf); + + if(longformat) { + if(d->has_identity) { + } + if(d->has_version) { + } + } + dnstap__dnstap__free_unpacked(d, NULL); +} + /** receive bytes from fd, prints errors if bad, * returns 0: closed/error, -1: continue, >0 number of bytes */ static ssize_t receive_bytes(int fd, void* buf, size_t len) @@ -131,16 +305,95 @@ void tap_data_free(struct tap_data* data) free(data); } +/** reply with ACCEPT control frame to bidirectional client, + * returns 0 on error */ +static int reply_with_accept(int fd) +{ + /* control frame on reply: + * 4 bytes 0 escape + * 4 bytes bigendian length of frame + * 4 bytes bigendian type ACCEPT + * 4 bytes bigendian frame option content type + * 4 bytes bigendian length of string + * string of content type. + */ + uint32_t* acceptframe; + /* len includes the escape and framelength */ + size_t len = 4+4+4+4+4+strlen(DNSTAP_CONTENT_TYPE); + acceptframe = calloc(1, len); + if(!acceptframe) { + log_err("out of memory"); + return 0; + } + acceptframe[0] = 0; + acceptframe[1] = htonl(4+4+4+strlen(DNSTAP_CONTENT_TYPE)); + acceptframe[2] = htonl(FSTRM_CONTROL_FRAME_ACCEPT); + acceptframe[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE); + acceptframe[4] = htonl(strlen(DNSTAP_CONTENT_TYPE)); + memmove(&acceptframe[5], DNSTAP_CONTENT_TYPE, + strlen(DNSTAP_CONTENT_TYPE)); + + fd_set_block(fd); + if(send(fd, acceptframe, len, 0) == -1) { +#ifndef USE_WINSOCK + log_err("send failed: %s", strerror(errno)); +#else + log_err("send failed: %s", wsa_strerror(WSAGetLastError())); +#endif + fd_set_nonblock(fd); + free(acceptframe); + return 0; + } + if(verbosity) log_info("sent control frame(accept) content-type:(%s)", + DNSTAP_CONTENT_TYPE); + + fd_set_nonblock(fd); + free(acceptframe); + return 1; +} + +/** reply with FINISH control frame to bidirectional client, + * returns 0 on error */ +static int reply_with_finish(int fd) +{ + /* control frame on reply: + * 4 bytes 0 escape + * 4 bytes bigendian length of frame + * 4 bytes bigendian type FINISH + */ + uint32_t finishframe[3]; + /* len includes the escape and framelength */ + size_t len = 4+4+4; + finishframe[0] = 0; + finishframe[1] = htonl(4); + finishframe[2] = htonl(FSTRM_CONTROL_FRAME_FINISH); + + fd_set_block(fd); + if(send(fd, finishframe, len, 0) == -1) { +#ifndef USE_WINSOCK + log_err("send failed: %s", strerror(errno)); +#else + log_err("send failed: %s", wsa_strerror(WSAGetLastError())); +#endif + fd_set_nonblock(fd); + return 0; + } + if(verbosity) log_info("sent control frame(finish)"); + + fd_set_nonblock(fd); + return 1; +} + /** callback for dnstap listener */ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) { struct tap_data* data = (struct tap_data*)arg; - if(verbosity) log_info("tap callback"); + if(verbosity>=3) log_info("tap callback"); while(data->len_done < 4) { uint32_t l = (uint32_t)data->len; ssize_t ret = receive_bytes(fd, ((uint8_t*)&l)+data->len_done, 4-data->len_done); - log_info("s recv %d got %d %d", (int)ret, (int)l, (int)ntohl(l)); + if(verbosity>=4) log_info("s recv %d", (int)ret); if(ret == 0) { /* closed or error */ tap_data_free(data); @@ -154,7 +407,7 @@ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) if(data->len_done < 4) return; /* continue later */ data->len = (size_t)(ntohl(l)); - if(verbosity) log_info("length is %d", (int)data->len); + if(verbosity>=3) log_info("length is %d", (int)data->len); if(data->len == 0) { /* it is a control frame */ data->control_frame = 1; @@ -170,10 +423,12 @@ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) } } } + /* we want to read the full length now */ if(data->data_done < data->len) { ssize_t r = receive_bytes(fd, data->frame + data->data_done, data->len - data->data_done); + if(verbosity>=4) log_info("f recv %d", (int)r); if(r == 0) { /* closed or error */ tap_data_free(data); @@ -186,13 +441,27 @@ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) if(data->data_done < data->len) return; /* continue later */ } + /* we are done with a frame */ - if(verbosity) log_info("received %sframe len %d", + if(verbosity>=3) log_info("received %sframe len %d", (data->control_frame?"control ":""), (int)data->len); - if(data->len >= 4 && ntohl(*(uint32_t*)data->frame) == + if(data->control_frame) + log_control_frame(data->frame, data->len); + else log_data_frame(data->frame, data->len); + + if(data->len >= 4 && sldns_read_uint32(data->frame) == FSTRM_CONTROL_FRAME_READY) { data->is_bidirectional = 1; if(verbosity) log_info("bidirectional stream"); + if(!reply_with_accept(fd)) { + tap_data_free(data); + } + } else if(data->len >= 4 && sldns_read_uint32(data->frame) == + FSTRM_CONTROL_FRAME_STOP && data->is_bidirectional) { + if(!reply_with_finish(fd)) { + tap_data_free(data); + return; + } } /* prepare for next frame */ @@ -202,6 +471,7 @@ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) data->len = 0; data->len_done = 0; data->data_done = 0; + } /** callback for main listening file descriptor */ @@ -279,7 +549,7 @@ setup_fd(char* socketpath) /** setup and run the server to listen to DNSTAP messages */ static void -setup_and_run(char* socketpath, int longformat) +setup_and_run(char* socketpath) { int fd; time_t secs = 0; @@ -316,7 +586,7 @@ extern char* optarg; int main(int argc, char** argv) { int c; - int usessl = 0, longformat = 0; + int usessl = 0; char* socketpath = NULL; #ifdef USE_WINSOCK WSADATA wsa_data; @@ -378,7 +648,7 @@ int main(int argc, char** argv) (void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); #endif } - setup_and_run(socketpath, longformat); + setup_and_run(socketpath); checklock_stop(); #ifdef USE_WINSOCK WSACleanup(); From 7bddf97450fe4695fb310e7ff1ff53ba624f83da Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 21 Jan 2020 09:56:28 +0100 Subject: [PATCH 06/96] dnstap test program prints identity and version. --- dnstap/unbound-dnstap-socket.c | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index 4b8ef1dad..3b01506c3 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -45,6 +45,7 @@ #include #include #include +#include #ifdef HAVE_SYS_UN_H #include #endif @@ -214,6 +215,37 @@ static char* q_of_msg(ProtobufCBinaryData message) return NULL; } +/** convert possible string or hex data to string. malloced or NULL */ +static char* possible_str(ProtobufCBinaryData str) +{ + int is_str = 1; + size_t i; + for(i=0; i>4]; + res[i*2+1] = hex[str.data[i]&0x0f]; + } + res[str.len*2] = 0; + return res; + } + } + return NULL; +} + /** log data frame contents */ static void log_data_frame(uint8_t* pkt, size_t len) { @@ -255,10 +287,18 @@ static void log_data_frame(uint8_t* pkt, size_t len) free(qinf); if(longformat) { + char* id=NULL, *vs=NULL; if(d->has_identity) { + id=possible_str(d->identity); } if(d->has_version) { + vs=possible_str(d->version); } + if(id || vs) + printf("identity: %s%s%s\n", (id?id:""), + (id&&vs?" ":""), (vs?vs:"")); + free(id); + free(vs); } dnstap__dnstap__free_unpacked(d, NULL); } From ade0ba63ff9dcc8296928828f4be4e9bee570c4c Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 21 Jan 2020 10:14:30 +0100 Subject: [PATCH 07/96] dnstap test program prints messages and timestamps in long format. --- dnstap/unbound-dnstap-socket.c | 58 ++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index 3b01506c3..4d58d4db9 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -246,6 +246,23 @@ static char* possible_str(ProtobufCBinaryData str) return NULL; } +/** convert timeval to string, malloced or NULL */ +static char* tv_to_str(protobuf_c_boolean has_time_sec, uint64_t time_sec, + protobuf_c_boolean has_time_nsec, uint32_t time_nsec) +{ + char buf[64], buf2[256]; + struct timeval tv; + memset(&tv, 0, sizeof(tv)); + if(has_time_sec) tv.tv_sec = time_sec; + if(has_time_nsec) tv.tv_usec = time_nsec; + + buf[0]=0; + (void)ctime_r(&tv.tv_sec, buf); + snprintf(buf2, sizeof(buf2), "%u.%9.9u %s", + (unsigned)time_sec, (unsigned)time_nsec, buf); + return strdup(buf2); +} + /** log data frame contents */ static void log_data_frame(uint8_t* pkt, size_t len) { @@ -299,6 +316,47 @@ static void log_data_frame(uint8_t* pkt, size_t len) (id&&vs?" ":""), (vs?vs:"")); free(id); free(vs); + + if(d->message && d->message->has_query_message && + d->message->query_message.data) { + char* qmsg = sldns_wire2str_pkt( + d->message->query_message.data, + d->message->query_message.len); + if(qmsg) { + printf("query_message:\n%s", qmsg); + free(qmsg); + } + } + if(d->message && d->message->has_query_time_sec) { + char* qtv = tv_to_str(d->message->has_query_time_sec, + d->message->query_time_sec, + d->message->has_query_time_nsec, + d->message->query_time_nsec); + if(qtv) { + printf("query_time: %s\n", qtv); + free(qtv); + } + } + if(d->message && d->message->has_response_message && + d->message->response_message.data) { + char* rmsg = sldns_wire2str_pkt( + d->message->response_message.data, + d->message->response_message.len); + if(rmsg) { + printf("response_message:\n%s", rmsg); + free(rmsg); + } + } + if(d->message && d->message->has_response_time_sec) { + char* rtv = tv_to_str(d->message->has_response_time_sec, + d->message->response_time_sec, + d->message->has_response_time_nsec, + d->message->response_time_nsec); + if(rtv) { + printf("response_time: %s\n", rtv); + free(rtv); + } + } } dnstap__dnstap__free_unpacked(d, NULL); } From bb55cc16859013988e9fccb64dc6430fc1d2c065 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 21 Jan 2020 14:02:45 +0100 Subject: [PATCH 08/96] dnstap unit test. --- dnstap/unbound-dnstap-socket.c | 1 + testdata/dnstap.tdir/dnstap.conf | 38 ++++++++++++++++ testdata/dnstap.tdir/dnstap.dsc | 16 +++++++ testdata/dnstap.tdir/dnstap.post | 15 +++++++ testdata/dnstap.tdir/dnstap.pre | 55 ++++++++++++++++++++++++ testdata/dnstap.tdir/dnstap.test | 53 +++++++++++++++++++++++ testdata/dnstap.tdir/dnstap.testns | 22 ++++++++++ testdata/dnstap.tdir/unbound_control.key | 15 +++++++ testdata/dnstap.tdir/unbound_control.pem | 11 +++++ testdata/dnstap.tdir/unbound_server.key | 15 +++++++ testdata/dnstap.tdir/unbound_server.pem | 11 +++++ 11 files changed, 252 insertions(+) create mode 100644 testdata/dnstap.tdir/dnstap.conf create mode 100644 testdata/dnstap.tdir/dnstap.dsc create mode 100644 testdata/dnstap.tdir/dnstap.post create mode 100644 testdata/dnstap.tdir/dnstap.pre create mode 100644 testdata/dnstap.tdir/dnstap.test create mode 100644 testdata/dnstap.tdir/dnstap.testns create mode 100644 testdata/dnstap.tdir/unbound_control.key create mode 100644 testdata/dnstap.tdir/unbound_control.pem create mode 100644 testdata/dnstap.tdir/unbound_server.key create mode 100644 testdata/dnstap.tdir/unbound_server.pem diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index 4d58d4db9..96e798282 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -358,6 +358,7 @@ static void log_data_frame(uint8_t* pkt, size_t len) } } } + fflush(stdout); dnstap__dnstap__free_unpacked(d, NULL); } diff --git a/testdata/dnstap.tdir/dnstap.conf b/testdata/dnstap.tdir/dnstap.conf new file mode 100644 index 000000000..82250ec2d --- /dev/null +++ b/testdata/dnstap.tdir/dnstap.conf @@ -0,0 +1,38 @@ +server: + verbosity: 2 + num-threads: 1 + outgoing-range: 16 + interface: 127.0.0.1 + port: @PORT@ + use-syslog: no + directory: "" + pidfile: "unbound.pid" + chroot: "" + username: "" + do-not-query-localhost: no +remote-control: + control-enable: yes + control-interface: 127.0.0.1 + # control-interface: ::1 + control-port: @CONTROL_PORT@ + server-key-file: "unbound_server.key" + server-cert-file: "unbound_server.pem" + control-key-file: "unbound_control.key" + control-cert-file: "unbound_control.pem" +forward-zone: + name: "." + forward-addr: "127.0.0.1@@TOPORT@" +dnstap: + dnstap-enable: yes + dnstap-socket-path: "dnstap.socket" + dnstap-send-identity: yes + dnstap-send-version: yes + #dnstap-identity + #dnstap-version + dnstap-log-resolver-query-messages: yes + dnstap-log-resolver-response-messages: yes + dnstap-log-client-query-messages: yes + dnstap-log-client-response-messages: yes + dnstap-log-forwarder-query-messages: yes + dnstap-log-forwarder-response-messages: yes + diff --git a/testdata/dnstap.tdir/dnstap.dsc b/testdata/dnstap.tdir/dnstap.dsc new file mode 100644 index 000000000..92a67ef2e --- /dev/null +++ b/testdata/dnstap.tdir/dnstap.dsc @@ -0,0 +1,16 @@ +BaseName: dnstap +Version: 1.0 +Description: test dnstap socket communication +CreationDate: Tue Jan 21 13:00:38 CET 2020 +Maintainer: dr. W.C.A. Wijngaards +Category: +Component: +CmdDepends: +Depends: +Help: +Pre: dnstap.pre +Post: dnstap.post +Test: dnstap.test +AuxFiles: +Passed: +Failure: diff --git a/testdata/dnstap.tdir/dnstap.post b/testdata/dnstap.tdir/dnstap.post new file mode 100644 index 000000000..ec79e0427 --- /dev/null +++ b/testdata/dnstap.tdir/dnstap.post @@ -0,0 +1,15 @@ +# #-- dnstap.post --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# source the test var file when it's there +[ -f .tpkg.var.test ] && source .tpkg.var.test +# +# do your teardown here +. ../common.sh +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi +kill_pid $DNSTAP_SOCKET_PID +kill_pid $FWD_PID +kill $UNBOUND_PID +kill $UNBOUND_PID >/dev/null 2>&1 +exit 0 diff --git a/testdata/dnstap.tdir/dnstap.pre b/testdata/dnstap.tdir/dnstap.pre new file mode 100644 index 000000000..95216949c --- /dev/null +++ b/testdata/dnstap.tdir/dnstap.pre @@ -0,0 +1,55 @@ +# #-- dnstap.pre--# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +. ../common.sh + +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi + +get_random_port 3 +UNBOUND_PORT=$RND_PORT +FWD_PORT=$(($RND_PORT + 1)) +CONTROL_PORT=$(($RND_PORT + 2)) +echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test +echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test +echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test + +# start forwarder +get_ldns_testns +$LDNS_TESTNS -p $FWD_PORT dnstap.testns >fwd.log 2>&1 & +FWD_PID=$! +echo "FWD_PID=$FWD_PID" >> .tpkg.var.test + +# start the dnstap log server +# the -vvvv flag prints protocol and connection information from the +# unbound-dnstap-socket server. +# the -l flag prints the DNS info in the DNSTAP packet in multiline output. +# stderr is the '-vvvv' server logs and errors. +# stdout is the one-line packet logs (or with -l, multiline). +$PRE/unbound-dnstap-socket -u dnstap.socket -l -vvvv 2>tap.errlog >tap.log & +if test $? -ne 0; then + echo "could not start unbound-dnstap-socket server" + exit 1 +fi +DNSTAP_SOCKET_PID=$! +echo "DNSTAP_SOCKET_PID=$DNSTAP_SOCKET_PID" >> .tpkg.var.test +# wait for the server to go up and make the dnstap.socket file +wait_server_up "tap.errlog" "creating unix socket" +if test ! -S dnstap.socket; then + echo "the dnstap.socket file does not exist!" +fi + +# make config file +sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < dnstap.conf > ub.conf +# start unbound in the background +$PRE/unbound -d -c ub.conf >unbound.log 2>&1 & +UNBOUND_PID=$! +echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test + +cat .tpkg.var.test +wait_ldns_testns_up fwd.log +wait_unbound_up unbound.log + diff --git a/testdata/dnstap.tdir/dnstap.test b/testdata/dnstap.tdir/dnstap.test new file mode 100644 index 000000000..49f1d42a6 --- /dev/null +++ b/testdata/dnstap.tdir/dnstap.test @@ -0,0 +1,53 @@ +# #-- dnstap.test --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi + +# test if the server is up. +echo "> dig www.example.com." +dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile +echo "> check answer" +if grep "10.20.30.40" outfile; then + echo "OK" +else + echo "> cat logfiles" + cat tap.log + cat tap.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 +fi + +echo "> check tap.log for dnstap info" +# see if it logged the information in tap.log +# wait for a moment for filesystem to catch up. +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 10; fi +if grep "www.example.com" tap.log; then echo "yes it is in tap.log"; +else + echo "information not in tap.log" + echo "failed" + echo "> cat logfiles" + cat tap.log + cat tap.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 +fi + + +echo "> cat logfiles" +cat tap.log +cat tap.errlog +cat fwd.log +cat unbound.log +echo "> OK" +exit 0 diff --git a/testdata/dnstap.tdir/dnstap.testns b/testdata/dnstap.tdir/dnstap.testns new file mode 100644 index 000000000..0c911ca5b --- /dev/null +++ b/testdata/dnstap.tdir/dnstap.testns @@ -0,0 +1,22 @@ +; nameserver test file +$ORIGIN example.com. +$TTL 3600 + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA NOERROR +ADJUST copy_id +SECTION QUESTION +www IN A +SECTION ANSWER +www IN A 10.20.30.40 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA SERVFAIL +ADJUST copy_id +SECTION QUESTION +www.example.net. IN A +ENTRY_END + diff --git a/testdata/dnstap.tdir/unbound_control.key b/testdata/dnstap.tdir/unbound_control.key new file mode 100644 index 000000000..d7c43a06b --- /dev/null +++ b/testdata/dnstap.tdir/unbound_control.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDD6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBa +rzPA0vlyuNtUsEN3qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvH +ST6JwUdIg0Lzg/USJ81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQAB +AoGAFT3e35MIgI4uDJJ8X0RfHp2NCO2LUg4TKbWical/C0W9vlR1/x80G1pE1d2Z +WotqJVWTrOq6eBox19RCgtLg2wPGk9uD62+9SDT37heWFlUCElWq50pQG6k9ThiG +DDypkZyZ/52+DdWybiaQJkuK6O5qQXuNAtVJMpghu4GnHAECQQDsupnZUQDpapzr +4FC4MSkL2+A1PRt6g4VhwoqOpJXaHfVnH6F7AwUuOLNwGdR5Cvv70pfJ7Jqg8L2m +Kxyl5bORAkEA09rn34YQ0pHJdHidbl2kInIuYTz09+TO3LWwan17nISH9aaYvVDr +p9x1B4Qzw9qyxT9oll7ze/5Rw/7C3AQj4QJAT2B2a+b8bkgAXBs4FbruL3rHoDJg +P2FQXSpVOWU4lg2LlsuFYvDtUMVUbZdLplanjZXcral3Y9W1Ub2M+ped8QJAYQN+ +aRpge7ys7vwIw7B36Bo3aOncF+ScYe+FkM5Tm7II/JHEofT7ZQwMP1vnxIlSkgbe +YvWqNB6a3NC99LikoQJBAM4UhDdRg63Tr6Idky6CQaH///zAN7nArJfffKGWFdw9 +DKrWpNqvYZtX/cfEJucKcRCm5YL8CKFYbQy4VoCxUcE= +-----END RSA PRIVATE KEY----- diff --git a/testdata/dnstap.tdir/unbound_control.pem b/testdata/dnstap.tdir/unbound_control.pem new file mode 100644 index 000000000..8f1ba87f1 --- /dev/null +++ b/testdata/dnstap.tdir/unbound_control.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBozCCAQwCCQD6XaN6FzW/4DANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1 +bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowGjEYMBYGA1UE +AxMPdW5ib3VuZC1jb250cm9sMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDD +6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBarzPA0vlyuNtUsEN3 +qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvHST6JwUdIg0Lzg/US +J81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQABMA0GCSqGSIb3DQEB +BQUAA4GBAGFAXmaQHuFgAuc6HVhYZJdToxLBhfxGpot4oZNjcb1Cdoz3OL34MU1B +9E5psj2PpGPIi8/RwoqBtAJHJ+J5cWngo03o4ZmdwKNSzaxlp141z/3rUtFqEHEC +iO6gPCT3U7dt6MyC7r6vdMqyW6aldP3CtwD0gQziKAMoj+TAfAcq +-----END CERTIFICATE----- diff --git a/testdata/dnstap.tdir/unbound_server.key b/testdata/dnstap.tdir/unbound_server.key new file mode 100644 index 000000000..4256c421d --- /dev/null +++ b/testdata/dnstap.tdir/unbound_server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQC3F7Jsv2u01pLL9rFnjsMU/IaCFUIz/624DcaE84Z4gjMl5kWA +3axQcqul1wlwSrbKwrony+d9hH/+MX0tZwvl8w3OmhmOAiaQ+SHCsIuOjVwQjX0s +RLB61Pz5+PAiVvnPa9JIYB5QrK6DVEsxIHj8MOc5JKORrnESsFDh6yeMeQIDAQAB +AoGAAuWoGBprTOA8UGfl5LqYkaNxSWumsYXxLMFjC8WCsjN1NbtQDDr1uAwodSZS +6ujzvX+ZTHnofs7y64XC8k34HTOCD2zlW7kijWbT8YjRYFU6o9F5zUGD9RCan0ds +sVscT2psLSzfdsmFAcbmnGdxYkXk2PC1FHtaqExxehralGUCQQDcqrg9uQKXlhQi +XAaPr8SiWvtRm2a9IMMZkRfUWZclPHq6fCWNuUaCD+cTat4wAuqeknAz33VEosw3 +fXGsok//AkEA1GjIHXrOcSlpfVJb6NeOBugjRtZ7ZDT5gbtnMS9ob0qntKV6saaL +CNmJwuD9Q3XkU5j1+uHvYGP2NzcJd2CjhwJACV0hNlVMe9w9fHvFN4Gw6WbM9ViP +0oS6YrJafYNTu5vGZXVxLoNnL4u3NYa6aPUmuZXjNwBLfJ8f5VboZPf6RwJAINd2 +oYA8bSi/A755MX4qmozH74r4Fx1Nuq5UHTm8RwDe/0Javx8F/j9MWpJY9lZDEF3l +In5OebPa/NyInSmW/wJAZuP9aRn0nDBkHYri++1A7NykMiJ/nH0mDECbnk+wxx0S +LwqIetBhxb8eQwMg45+iAH7CHAMQ8BQuF/nFE6eotg== +-----END RSA PRIVATE KEY----- diff --git a/testdata/dnstap.tdir/unbound_server.pem b/testdata/dnstap.tdir/unbound_server.pem new file mode 100644 index 000000000..aeda3ff11 --- /dev/null +++ b/testdata/dnstap.tdir/unbound_server.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBmzCCAQQCCQDsNJ1UmphEFzANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1 +bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowEjEQMA4GA1UE +AxMHdW5ib3VuZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtxeybL9rtNaS +y/axZ47DFPyGghVCM/+tuA3GhPOGeIIzJeZFgN2sUHKrpdcJcEq2ysK6J8vnfYR/ +/jF9LWcL5fMNzpoZjgImkPkhwrCLjo1cEI19LESwetT8+fjwIlb5z2vSSGAeUKyu +g1RLMSB4/DDnOSSjka5xErBQ4esnjHkCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAZ +9N0lnLENs4JMvPS+mn8C5m9bkkFITd32IiLjf0zgYpIUbFXH6XaEr9GNZBUG8feG +l/6WRXnbnVSblI5odQ4XxGZ9inYY6qtW30uv76HvoKp+QZ1c3460ddR8NauhcCHH +Z7S+QbLXi+r2JAhpPozZCjBHlRD0ixzA1mKQTJhJZg== +-----END CERTIFICATE----- From 57ad1696051874348cbd85bbd8b8a768c0abadb8 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 21 Jan 2020 14:50:37 +0100 Subject: [PATCH 09/96] the framestream queue. --- daemon/worker.c | 3 ++ dnstap/dnstap.c | 20 +++++++---- dnstap/dnstap.h | 9 +++++ dnstap/dtstream.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++ dnstap/dtstream.h | 26 ++++++++++++++ 5 files changed, 142 insertions(+), 7 deletions(-) diff --git a/daemon/worker.c b/daemon/worker.c index aa16650ec..382bbd384 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -1924,6 +1924,9 @@ worker_delete(struct worker* worker) #endif /* UB_ON_WINDOWS */ } comm_base_delete(worker->base); +#ifdef USE_DNSTAP + dt_deinit(&worker->dtenv); +#endif ub_randfree(worker->rndstate); alloc_clear(&worker->alloc); regional_destroy(worker->env.scratch); diff --git a/dnstap/dnstap.c b/dnstap/dnstap.c index aabf8eec9..fccf4a721 100644 --- a/dnstap/dnstap.c +++ b/dnstap/dnstap.c @@ -53,6 +53,7 @@ #include #include "dnstap/dnstap.h" +#include "dnstap/dtstream.h" #include "dnstap/dnstap.pb-c.h" #define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap" @@ -90,13 +91,7 @@ dt_pack(const Dnstap__Dnstap *d, void **buf, size_t *sz) static void dt_send(const struct dt_env *env, void *buf, size_t len_buf) { - fstrm_res res; - if (!buf) - return; - res = fstrm_iothr_submit(env->iothr, env->ioq, buf, len_buf, - fstrm_free_wrapper, NULL); - if (res != fstrm_res_success) - free(buf); + dt_msg_queue_submit(env->msgqueue, buf, len_buf); } static void @@ -275,9 +270,20 @@ dt_init(struct dt_env *env) env->ioq = fstrm_iothr_get_input_queue(env->iothr); if (env->ioq == NULL) return 0; + env->msgqueue = dt_msg_queue_create(); + if(!env->msgqueue) { + log_err("malloc failure"); + return 0; + } return 1; } +void +dt_deinit(struct dt_env* env) +{ + dt_msg_queue_delete(env->msgqueue); +} + void dt_delete(struct dt_env *env) { diff --git a/dnstap/dnstap.h b/dnstap/dnstap.h index 0103c1c0e..6183300b6 100644 --- a/dnstap/dnstap.h +++ b/dnstap/dnstap.h @@ -43,6 +43,7 @@ struct config_file; struct fstrm_io; struct fstrm_queue; struct sldns_buffer; +struct dt_msg_queue; struct dt_env { /** dnstap I/O thread */ @@ -50,6 +51,9 @@ struct dt_env { /** dnstap I/O thread input queue */ struct fstrm_iothr_queue *ioq; + /** valid in worker struct, not in daemon struct, the per-worker + * message list */ + struct dt_msg_queue* msgqueue; /** dnstap "identity" field, NULL if disabled */ char *identity; @@ -107,6 +111,11 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg); int dt_init(struct dt_env *env); +/** + * Deletes the per-worker state created by dt_init + */ +void dt_deinit(struct dt_env *env); + /** * Delete dnstap environment object. Closes dnstap I/O socket and deletes all * per-worker I/O queues. diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index cad4d1f48..6d28f4c67 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -44,3 +44,94 @@ #include "config.h" #include "dnstap/dtstream.h" +struct dt_msg_queue* +dt_msg_queue_create(void) +{ + struct dt_msg_queue* mq = calloc(1, sizeof(*mq)); + if(!mq) return NULL; + mq->maxsize = 1*1024*1024; /* set max size of buffer, per worker, + about 1 M should contain 64K messages with some overhead, + or a whole bunch smaller ones */ + lock_basic_init(&mq->lock); + lock_protect(&mq->lock, mq, sizeof(*mq)); + return mq; +} + +/** clear the message list, caller must hold the lock */ +static void +dt_msg_queue_clear(struct dt_msg_queue* mq) +{ + struct dt_msg_entry* e = mq->first, *next=NULL; + while(e) { + next = e->next; + free(e->buf); + free(e); + e = next; + } + mq->first = NULL; + mq->last = NULL; + mq->cursize = 0; +} + +void +dt_msg_queue_delete(struct dt_msg_queue* mq) +{ + if(!mq) return; + lock_basic_destroy(&mq->lock); + dt_msg_queue_clear(mq); + free(mq); +} + +void +dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len) +{ + struct dt_msg_entry* entry; + + /* check conditions */ + if(!buf) return; + if(len == 0) { + /* it is not possible to log entries with zero length, + * because the framestream protocol does not carry it. + * However the protobuf serialization does not create zero + * length datagrams for dnstap, so this should not happen. */ + free(buf); + return; + } + if(!mq) { + free(buf); + return; + } + + /* allocate memory for queue entry */ + entry = malloc(sizeof(*entry)); + if(!entry) { + log_err("out of memory logging dnstap"); + free(buf); + return; + } + entry->next = NULL; + entry->buf = buf; + entry->len = len; + + /* aqcuire lock */ + lock_basic_lock(&mq->lock); + /* see if it is going to fit */ + if(mq->cursize + len > mq->maxsize) { + /* buffer full, or congested. */ + /* drop */ + lock_basic_unlock(&mq->lock); + free(buf); + return; + } + mq->cursize += len; + /* append to list */ + if(mq->last) { + mq->last->next = entry; + } else { + mq->first = entry; + } + mq->last = entry; + /* release lock */ + lock_basic_unlock(&mq->lock); +} + diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index e76264f50..6030b86d6 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -209,5 +209,31 @@ struct dt_io_list_item { /* routine to send a frame. */ /* routine to send STOP message. */ +/** + * Create new (empty) worker message queue. Limit set to default on max. + * @return NULL on malloc failure or a new queue (not locked). + */ +struct dt_msg_queue* dt_msg_queue_create(void); + +/** + * Delete a worker message queue. It has to be unlinked from access, + * so it can be deleted without lock worries. The queue is emptied (deleted). + * @param mq: message queue. + */ +void dt_msg_queue_delete(struct dt_msg_queue* mq); + +/** + * Submit a message to the queue. The queue is locked by the routine, + * the message is inserted, and then the queue is unlocked so the + * message can be picked up by the writer thread. + * @param mq: message queue. + * @param buf: buffer with message (dnstap contents). + * The buffer must have been malloced by caller. It is linked in + * the queue, and is free()d after use. If the routine fails + * the buffer is freed as well (and nothing happens, the item + * could not be logged). + * @param len: length of buffer. + */ +void dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len); #endif /* DTSTREAM_H */ From efc79beb2d8bae70c62fa4ca703587bd810590ff Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 21 Jan 2020 17:01:25 +0100 Subject: [PATCH 10/96] iothread work. --- daemon/daemon.c | 3 +- daemon/worker.c | 23 +++- dnstap/.dtstream.h.swp | Bin 0 -> 28672 bytes dnstap/dnstap.c | 18 ++- dnstap/dnstap.h | 5 +- dnstap/dtstream.c | 288 +++++++++++++++++++++++++++++++++++++++++ dnstap/dtstream.h | 66 ++++++++++ 7 files changed, 398 insertions(+), 5 deletions(-) create mode 100644 dnstap/.dtstream.h.swp diff --git a/daemon/daemon.c b/daemon/daemon.c index 0b1200a2e..65d51e182 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -452,10 +452,9 @@ daemon_create_workers(struct daemon* daemon) if(daemon->cfg->dnstap) { #ifdef USE_DNSTAP daemon->dtenv = dt_create(daemon->cfg->dnstap_socket_path, - (unsigned int)daemon->num); + (unsigned int)daemon->num, daemon->cfg); if (!daemon->dtenv) fatal_exit("dt_create failed"); - dt_apply_cfg(daemon->dtenv, daemon->cfg); #else fatal_exit("dnstap enabled in config but not built with dnstap support"); #endif diff --git a/daemon/worker.c b/daemon/worker.c index 382bbd384..d14409570 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -78,6 +78,7 @@ #include "sldns/wire2str.h" #include "util/shm_side/shm_main.h" #include "dnscrypt/dnscrypt.h" +#include "dnstap/dtstream.h" #ifdef HAVE_SYS_TYPES_H # include @@ -1876,6 +1877,19 @@ worker_init(struct worker* worker, struct config_file *cfg, ) { auth_xfer_pickup_initial(worker->env.auth_zones, &worker->env); } +#ifdef USE_DNSTAP + if(worker->daemon->cfg->dnstap +#ifndef THREADS_DISABLED + && worker->thread_num == 0 +#endif + ) { + if(!dt_io_thread_start(dtenv->dtio)) { + log_err("could not start dnstap io thread"); + worker_delete(worker); + return 0; + } + } +#endif /* USE_DNSTAP */ if(!worker->env.mesh || !worker->env.scratch_buffer) { worker_delete(worker); return 0; @@ -1925,8 +1939,15 @@ worker_delete(struct worker* worker) } comm_base_delete(worker->base); #ifdef USE_DNSTAP - dt_deinit(&worker->dtenv); + if(worker->daemon->cfg->dnstap +#ifndef THREADS_DISABLED + && worker->thread_num == 0 #endif + ) { + dt_io_thread_stop(worker->dtenv.dtio); + } + dt_deinit(&worker->dtenv); +#endif /* USE_DNSTAP */ ub_randfree(worker->rndstate); alloc_clear(&worker->alloc); regional_destroy(worker->env.scratch); diff --git a/dnstap/.dtstream.h.swp b/dnstap/.dtstream.h.swp new file mode 100644 index 0000000000000000000000000000000000000000..22f3859addf6106a6718d567664f7a22a1b7e0ba GIT binary patch literal 28672 zcmeI5du(LaUB@SnHeH&8s#QhPKj383fbGuOn@vKiU7(q@$Lndmwlg!{2WdLFGjqqj z*_nGMbMLIzDSaeG4KzxVKnZD+mPj;}+KT*99u>4oLR$z>Qc*xWk|Nqvk*E+6grM=Izt_a{Rn5m;3!6|Ec$U z`;zN&mD_T;ji{gaJ$Z5FAFoZaW)x0`?a)u!UOncw9kRUN7C0048Z-T{9`(a!t>eXH zo@s`0;&o@5Nu2b2uQR>AL-y=Z#z4lvxiZjCT6^ApN$%=>SM8M|uGoFKdBf{h&$YBH zU&cVjK*m7EK*m7EK*m7EK*m7E!2d%AlJ2W=AHeSOo$YDheV+TA{`+e8dDm&uUFe>_ z%KaO-f7ATw^BdgraLfA(+~=FzzfWv=?>=V#WDH~sWDH~sWDH~sWDH~sWDH~sWDH~s zWDH~soC5=1Gne}b@;xnqI_Ljs{Qu&Q=5oIWejB_OoB~Hd1zZB2xHOmh68IwMfNQ{B z@ZC#tx%#fzp1vrTyBmBM+z#4c0z8Ab@hR|& z-~(VCybb&$cn0C(L2xIS2X6%zfeXO};AMo5KLn3}&w-DDTfuw4o57{vdBlxp!871H z;2*%J!9(C9paE9EkAW8uV!jE!3_b#G1642&-U==Q(pQf=VP%(@G80{|mjqsW(scYd z_SSr}(F>B?u9>MRldSuu-fy-19>02tY4m$NKTO)2X3bBMAY9Y5i67=o)H6$~i;E^` znJ~)j3c|$rCrMlLnoYlXU|60$H9>6jg_)Yk?K&9+%_*DQCA5jS&e3lq{hn`Y7i*Gr zZg@0JKlWqID)qF|;#)!6H%&io^nz}JL2C0zE@>F~l1Q`m>or?iE!pf+a*!6|>Ij;& zszo8b38J)OG1r=9nn^8)YV9EA-^A}skxDUXAdH~^yv3*z8bzm}M`A3Ae{5(YkU51Z2?*5fcE>74s)1d^D1O)v4% zTzTV##t$129%AN}D%HZuzzN5R?!;>~oT;}tWkUZ{;>wp_O%Q6iLbqBmWMYuX44KeA z=y>gR)bN|rLQX+Upyae5x>YhNE7PVCg^3r0v57)|i;1HQsiTTV4Csq^zGc{p zhf^=xJO{;4JBSlqP=Cm?K32W z&sh3|0UnVcH6Yfay>`rWC@hN2)isEnYw|_|}jOsY6_b5k2Z}I=<4<)0IT00()gIeHGhTl6k!=CF>yV`n^3HQSXG` za|6u{Y(``&SgXlge_(`^(W!X!`CvdE$XyYHjds83o8A2+XwL}E@$~v`t}`|LRv_cM zTB(+cg~PQ4(zZgLjy|F>GtwYw^{TyqxMfBV?^=@yx#cy2c93kQ6HL(Qw*3x%<^TN0r^%B$VMM>0%+A`l$t5p1MX|tV{tts-bvOHfsS|}Iu zrg)^dWJ>dDbAVYc~e~|nw8~BrF5{gSgIbEN0rst1v6JTTsTxz>z0a#7E6bU zOS46@TsF((C?6&Jq$!k3mD187Q(7{GrQ_ykf$Xc*wA9rK>7{~FMXXpX6>JrGb9A97 zg-E{H<)v!5Fk8(VcrDFVN0U)mb-7$M6Q!lu#nm}#l5$qc%k!mb<$&07aFzOtl?o+Q zi{Q8kr? z0^2k3h}q?pnmwN@z_dPdXENeFH;)kx_!Wt6e9jKaA}H@E<8fB=gh(5G5s$p8`1aZtTRQG41WG|_EF{Zt!$8=6&245#ieEGM@4wS*^ z_kxoobDJh+yEtkk8?q?NbjHFiRWAAbuJgZdLK)j`pf4>h6>)>Y!3uk0Ssv_bHWe)v z57r5G0==N#XU`h5AaABkU^bp1y9JUKGLS9Pa8t$RM+-=sW!Dk61Eu(8 zAQKOJZrLwTeJf%Iv>{WKtPE{0=wPcd4FOK@XhSbHp?ktfF+u4{Q zz1Q)R{bEulYKpVy{LCW88+8<1ra9z$5Kj#08*;myDPKg zBPppW8-an3@q5(8d2J~|g`}As@H^3%H2e1M+nYB_i(H~Ni*k$J6xhNk{}Oe?eh&vu zvu?XFZ}yn+CEE zPk~3ko!}0z0*#QvfQ+zq}+|RJZgNTfUt$eG9fx{$Dr$G}N03E5D>& zF*(|vZH<+fJ*|2)p*Yq~KEz7d>xUsb8%-_SF}5SR(5twaZh<1)ftR5wa5lnj>UvG| zi)gbUuVg1<9a&b}vJ>tM(m}lDXvI27H6&J}*NuRcmz`yoU6$Qj#y*K!Hg-!{9|>g5 zRHL=Fqu+SlZhN!F+p~8V67QESB~daO6pE)o}o`Pq$WqCNEUw6 z4#HjH%TBOmAhmiv-irdX;p5K}vUerZx;<4W& zjIf;W(oQVOlgMWMP=qMTR1MLWW>nMzWTJ5=GH&!aORSASR@Jo0F$$$6~;+MqOo35g{nFynY+OSQU6T7qHh#M+HelhebGB9-N8j@x~5m zJVq*N!|7ggtb)$wT*(ETZU7iL`O7mF30Se5trNSF0XhDe5ESC;edd zp4xkrcq){u-U&(K_M^q7;s;6OZ?a`mBfB}5jD?0xolf&jA4=`1lNQhu(KGNx4cBuy zw-k`^bVim7hl`lHRH`h9W!Gv&Vv81~D(gwF-Dfoy;-$9KjFA*BKW3(K@D?hx7Ubc% z<5I~r=TwQ!{t9(ypHs!v=TwE}e#IKZC8%QGIaVRrsYBxbcM#u4K;nNwSN-{CK7Sc} z2HXzh{SDv>a50ec|1W?C!7*?dxB#3F{*t)=QE(S{KR5_P3-}&!zvuy<2e*TpK>8V+G26(P<5epxNywuyY{EG9?tqk_9NqB)7ZRW$G)3csD^oF2FP^NXa_9YX2TQJ zR3s@kXzlzrl0wh0bn?^%YkJxquV^~mY`BurbmGqwcB|kejdhl&ag*e%+%|l2q?Vx_ zjuczOSXOuD)SOiHbF5lB8N6a1nKA1@Gw8A9M8x&lc3u>1Sx$?bnk`$2cEIVbh^r!L zik;ftlyyCswQJV++$cRWmh#%G_OX_o(!(-)K)81gw<&J0hk!)%xqY<1=Pk3)6~}*a?4a+7c~iX;Q8_Pu@A@pc*xj zPJyA3Cc573dYkQt%QF+o8UdEQ!!bE+MQBv&z>49vfNd7JD<6*Y)IRGuZhN8ikH4{6 zd8}{5COzjIbvL&q*{c>iH;a9CTOqo>4Fu_Qq@telB;z(gycS?AVdENQGN7QYn{Fm~+^}Ta#@K_)O~XQn_TMXK;28T}lR`=x&yQ zp#|3Uy|$WL_whJ8Xl(?Rc7WTM+oEh|492c)x6HHRdRmTD+Yf_1qm$5BFURSyA2mrm4(yR8)2 ztuG-SV$&F1%53arPGLaC^iHjRr4q(w0p-%Jh=X36AG>4VLN@Fi?MWu3andEXbVWKp z$nTA)BZq=kKWkxEXT~*Yx}o!09C6^Ov$)(6YWkeQF{mblDM^_6lazIRpD5a1HY1Rh zNzq;Y>dXB@uDHo^%NT8HY%x~Xy7AkQ%ndS7@i+TMoT+Wa_FaR~`q&+AC_KhPvsFSk}sRK%#|7|{;Yq1Kk(UDNVp8xnJaM?@i2-sB1)W3ZQQ-)ar?5O;q^ zFGjgdkvvwxGPc6*bl2}#0aJJyE8&E{c{T-*Y*>IO+6=^+txb)HUGK>3Jz|7C2xjQx zI5KpH)hF$^W*Ml-`M%yjLmksp;^?s)`fEGtd_5V`E3yS8=#*jC{pwh{bSrx2(l;dmMLrf+I>Er@GyWO)(y z*@@M35)xiy?2oimHf=*z?A~tZb;1)+5b1O6nn5R=Wp%SFZt)yeDI;ZjeZrZoP&RLfG@`}R1nEe*g<%zLD@kc{q@~Q1 z(U1Zsm8KMElQs}eYDrY{PX*~cSnc#wmnS-sX&QPYg|cZCW0}D*w5FGbM|#>`CMLa% zTNY-1lLB4xZosZzI1)NXp53tT#seDv$3*-;l(>`lKmGgsmx=Ko1s?_y`%i&4f|rT! z<=+1VN_;9~Ia#PweT z4}&|v&0r0*z;5te;(WOq@ay1R;2q#+z)QsWayK9X6W}G{`yYbe0UrbRf(4KR-z3ie z2DlGg53U5e!QT<*-vdqpx&QwI;{4A7A6yUQzW>*V^M4bhvHzR+JqKRA0G$Ec3yy&| zgV%uPiS7RaJPH03{0X=dc;E`4yi>&g!A~YJuz!^;oZGl%5(7&`CNZP|+gSXaNer39 zkVy<|DN=bblNg)|kx2}yrKPHLCNT`PkW6A2{lmpfVz3w1GKnFR7_34hlE(kM#DJi( zqspQJP&4YtpH^5Mh+8)r|9_O&{To2ye?n*dd74=N>)>H<4>$%6f&w@nNctxwPxg~B zkTH-kkTH-kkTH-kkTH-kkTH-kkTH-k@W0K#F8RJ7Ir-+^&l=aJrp*m|Z_9Z@-K!{mTwLq<3G{m6pZ@E_cxH?kwsBB!u`K YvbswG)((4bVdt-glRE<3mXrGa6Lv6hg8%>k literal 0 HcmV?d00001 diff --git a/dnstap/dnstap.c b/dnstap/dnstap.c index fccf4a721..e942c4194 100644 --- a/dnstap/dnstap.c +++ b/dnstap/dnstap.c @@ -130,7 +130,7 @@ check_socket_file(const char* socket_path) } struct dt_env * -dt_create(const char *socket_path, unsigned num_workers) +dt_create(const char *socket_path, unsigned num_workers, struct config_file* cfg) { #ifdef UNBOUND_DEBUG fstrm_res res; @@ -180,6 +180,16 @@ dt_create(const char *socket_path, unsigned num_workers) fstrm_unix_writer_options_destroy(&fuwopt); fstrm_writer_options_destroy(&fwopt); + env->dtio = dt_io_thread_create(); + if(!env->dtio) { + log_err("malloc failure"); + fstrm_writer_destroy(&fw); + fstrm_iothr_destroy(&env->iothr); + free(env); + return NULL; + } + dt_io_thread_apply_cfg(env->dtio, cfg); + dt_apply_cfg(env, cfg); return env; } @@ -275,12 +285,17 @@ dt_init(struct dt_env *env) log_err("malloc failure"); return 0; } + if(!dt_io_thread_register_queue(env->dtio, env->msgqueue)) { + log_err("malloc failure"); + return 0; + } return 1; } void dt_deinit(struct dt_env* env) { + dt_io_thread_unregister_queue(env->dtio, env->msgqueue); dt_msg_queue_delete(env->msgqueue); } @@ -291,6 +306,7 @@ dt_delete(struct dt_env *env) return; verbose(VERB_OPS, "closing dnstap socket"); fstrm_iothr_destroy(&env->iothr); + dt_io_thread_delete(env->dtio); free(env->identity); free(env->version); free(env); diff --git a/dnstap/dnstap.h b/dnstap/dnstap.h index 6183300b6..428691ed9 100644 --- a/dnstap/dnstap.h +++ b/dnstap/dnstap.h @@ -48,6 +48,8 @@ struct dt_msg_queue; struct dt_env { /** dnstap I/O thread */ struct fstrm_iothr *iothr; + /** the io thread (made by the struct daemon) */ + struct dt_io_thread* dtio; /** dnstap I/O thread input queue */ struct fstrm_iothr_queue *ioq; @@ -90,10 +92,11 @@ struct dt_env { * share access to the dnstap I/O socket. * @param socket_path: path to dnstap logging socket, must be non-NULL. * @param num_workers: number of worker threads, must be > 0. + * @param cfg: with config settings. * @return dt_env object, NULL on failure. */ struct dt_env * -dt_create(const char *socket_path, unsigned num_workers); +dt_create(const char *socket_path, unsigned num_workers, struct config_file* cfg); /** * Apply config settings. diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 6d28f4c67..318e04bfc 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -43,6 +43,12 @@ #include "config.h" #include "dnstap/dtstream.h" +#include "util/config_file.h" +#include "util/ub_event.h" +#include "util/net_help.h" +#ifdef HAVE_SYS_UN_H +#include +#endif struct dt_msg_queue* dt_msg_queue_create(void) @@ -135,3 +141,285 @@ dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len) lock_basic_unlock(&mq->lock); } +struct dt_io_thread* dt_io_thread_create(void) +{ + struct dt_io_thread* dtio = calloc(1, sizeof(*dtio)); + return dtio; +} + +void dt_io_thread_delete(struct dt_io_thread* dtio) +{ + struct dt_io_list_item* item, *nextitem; + if(!dtio) return; + item=dtio->io_list; + while(item) { + nextitem = item->next; + free(item); + item = nextitem; + } + free(dtio->socket_path); + free(dtio); +} + +void dt_io_thread_apply_cfg(struct dt_io_thread* dtio, struct config_file *cfg) +{ + dtio->upstream_is_unix = 1; + dtio->socket_path = strdup(cfg->dnstap_socket_path); +} + +int dt_io_thread_register_queue(struct dt_io_thread* dtio, + struct dt_msg_queue* mq) +{ + struct dt_io_list_item* item = malloc(sizeof(*item)); + if(!item) return 0; + item->queue = mq; + item->next = dtio->io_list; + dtio->io_list = item; + return 1; +} + +void dt_io_thread_unregister_queue(struct dt_io_thread* dtio, + struct dt_msg_queue* mq) +{ + struct dt_io_list_item* item=dtio->io_list, *prev=NULL; + while(item) { + if(item->queue == mq) { + /* found it */ + if(prev) prev->next = item->next; + else dtio->io_list = item->next; + /* the queue itself only registered, not deleted */ + free(item); + return; + } + prev = item; + item = item->next; + } +} + +/** find a new message to write, search message queues, false if none */ +static int dtio_find_msg(struct dt_io_thread* dtio) +{ +} + +/** write more of the current messsage. false if incomplete, true if + * the message is done */ +static int dtio_write_more(struct dt_io_thread* dtio) +{ +} + +/** callback for the dnstap events, to write to the output */ +static void dtio_output_cb(int fd, short ATTR_UNUSED(bits), void* arg) +{ + struct dt_io_thread* dtio = (struct dt_io_thread*)arg; + + /* see if there are messages that need writing */ + if(!dtio->cur_msg) { + if(!dtio_find_msg(dtio)) + return; /* nothing to do */ + } + + /* write it */ + if(dtio->cur_msg_done < dtio->cur_msg_len) { + if(!dtio_write_more(dtio)) + return; + } + + /* done with the current message */ + free(dtio->cur_msg); + dtio->cur_msg = NULL; + dtio->cur_msg_len = 0; + dtio->cur_msg_done = 0; +} + +/** callback for the dnstap commandpipe, to stop the dnstap IO */ +static void dtio_cmd_cb(int fd, short ATTR_UNUSED(bits), void* arg) +{ + struct dt_io_thread* dtio = (struct dt_io_thread*)arg; + uint8_t cmd; + ssize_t r; + if(dtio->want_to_exit) + return; + r = read(fd, &cmd, sizeof(cmd)); + if(r == -1) { + if(errno == EINTR || errno == EAGAIN) + return; /* ignore this */ + log_err("dnstap io: failed to read: %s", strerror(errno)); + /* and then fall through to quit the thread */ + } + if(r == 0) { + verbose(VERB_ALGO, "dnstap io: cmd channel closed"); + } else if(r == 1 && cmd == 0) { + verbose(VERB_ALGO, "dnstap io: cmd channel cmd quit"); + } + dtio->want_to_exit = 1; + if(ub_event_base_loopexit((struct ub_event_base*)dtio->event_base) + != 0) { + log_err("dnstap io: could not loopexit"); + } +} + +/** setup the event base for the dnstap io thread */ +static void dtio_setup_base(struct dt_io_thread* dtio, time_t* secs, + struct timeval* now) +{ + memset(now, 0, sizeof(*now)); + dtio->event_base = ub_default_event_base(0, secs, now); + if(!dtio->event_base) { + fatal_exit("dnstap io: could not create event_base"); + } +} + +/** setup the cmd event for dnstap io */ +static void dtio_setup_cmd(struct dt_io_thread* dtio) +{ + struct ub_event* cmdev; + fd_set_nonblock(dtio->commandpipe[0]); + cmdev = ub_event_new(dtio->event_base, dtio->commandpipe[0], + UB_EV_READ | UB_EV_PERSIST, &dtio_cmd_cb, dtio); + if(!cmdev) { + fatal_exit("dnstap io: out of memory"); + } + dtio->command_event = cmdev; + if(ub_event_add(cmdev, NULL) != 0) { + fatal_exit("dnstap io: out of memory (adding event)"); + } +} + +/** del the output file descriptor event for listening */ +static void dtio_del_output_event(struct dt_io_thread* dtio) +{ + if(!dtio->event_added) + return; + ub_event_del(dtio->event); + dtio->event_added = 0; +} + +/** close and stop the output file descriptor event */ +static void dtio_close_output(struct dt_io_thread* dtio) +{ + if(!dtio->event) + return; + ub_event_free(dtio->event); + dtio->event = NULL; + close(dtio->fd); + dtio->fd = -1; +} + +/** perform desetup and free stuff when the dnstap io thread exits */ +static void dtio_desetup(struct dt_io_thread* dtio) +{ + dtio_del_output_event(dtio); + dtio_close_output(dtio); + ub_event_del(dtio->command_event); + ub_event_free(dtio->command_event); + close(dtio->commandpipe[0]); + dtio->commandpipe[0] = -1; + ub_event_base_free(dtio->event_base); +} + +/** open the output file descriptor */ +static void dtio_open_output(struct dt_io_thread* dtio) +{ + struct ub_event* ev; + struct sockaddr_un s; + dtio->fd = socket(AF_LOCAL, SOCK_STREAM, SOCK_CLOEXEC); + if(dtio->fd == -1) { + log_err("dnstap io: failed to create socket: %s", + strerror(errno)); + return; + } + memset(&s, 0, sizeof(s)); +#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN + /* this member exists on BSDs, not Linux */ + s.sun_len = (unsigned)sizeof(usock); +#endif + s.sun_family = AF_LOCAL; + /* length is 92-108, 104 on FreeBSD */ + (void)strlcpy(s.sun_path, dtio->socket_path, sizeof(s.sun_path)); + if(connect(dtio->fd, (struct sockaddr*)&s, (socklen_t)sizeof(s)) + == -1) { + log_err("dnstap io: failed to connect: %s", strerror(errno)); + return; + } + fd_set_nonblock(dtio->fd); + + /* the EV_READ is to catch channel close, write to write packets */ + ev = ub_event_new(dtio->event_base, dtio->fd, + UB_EV_READ | UB_EV_WRITE | UB_EV_PERSIST, &dtio_output_cb, + dtio); + if(!ev) { + fatal_exit("dnstap io: out of memory"); + } + dtio->event = ev; + +} + +/** add the output file descriptor event for listening */ +static void dtio_add_output_event(struct dt_io_thread* dtio) +{ + if(ub_event_add(dtio->event, NULL) != 0) { + fatal_exit("dnstap io: out of memory (adding event)"); + } + dtio->event_added = 1; +} + +/** the IO thread function for the DNSTAP IO */ +static void* dnstap_io(void* arg) +{ + struct dt_io_thread* dtio = (struct dt_io_thread*)arg; + time_t secs = 0; + struct timeval now; + + /* setup */ + dtio_setup_base(dtio, &secs, &now); + dtio_setup_cmd(dtio); + dtio_open_output(dtio); + dtio_add_output_event(dtio); + verbose(VERB_ALGO, "start dnstap io thread"); + + /* run */ + if(ub_event_base_dispatch(dtio->event_base) < 0) { + log_err("dnstap io: dispatch failed, errno is %s", + strerror(errno)); + } + + /* cleanup */ + verbose(VERB_ALGO, "stop dnstap io thread"); + dtio_desetup(dtio); + return NULL; +} + +int dt_io_thread_start(struct dt_io_thread* dtio) +{ + /* set up the thread, can fail */ + if(pipe(dtio->commandpipe) == -1) { + log_err("failed to create pipe: %s", strerror(errno)); + return 0; + } + + /* start the thread */ + ub_thread_create(&dtio->tid, dnstap_io, dtio); + return 1; +} + +void dt_io_thread_stop(struct dt_io_thread* dtio) +{ + uint8_t cmd = 0; + if(!dtio) return; + if(!dtio->event_base) return; /* not started */ + + while(1) { + ssize_t r = write(dtio->commandpipe[1], &cmd, sizeof(cmd)); + if(r == -1) { + if(errno == EINTR || errno == EAGAIN) + continue; + log_err("dnstap io stop: write: %s", strerror(errno)); + break; + } + break; + } + + close(dtio->commandpipe[1]); + dtio->commandpipe[1] = -1; + ub_thread_join(dtio->tid); +} diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 6030b86d6..5d4e57646 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -47,6 +47,7 @@ #include "util/locks.h" struct dt_msg_entry; struct dt_io_list_item; +struct config_file; /** * A message buffer with dnstap messages queued up. It is per-worker. @@ -92,16 +93,29 @@ struct dt_io_thread { void* event_base; /** list of queues that is registered to get written */ struct dt_io_list_item* io_list; + /** thread id, of the io thread */ + ub_thread_type tid; /** file descriptor that the thread writes to */ int fd; /** event structure that the thread uses */ void* event; + /** the event is added */ + int event_added; + /** the buffer that currently getting written, or NULL if no + * (partial) message written now */ + void* cur_msg; + /** length of the current message */ + size_t cur_msg_len; + /** number of bytes written for the current message */ + size_t cur_msg_done; /** command pipe that stops the pipe if closed. Used to quit * the program. [0] is read, [1] is written to. */ int commandpipe[2]; /** the event to listen to the commandpipe */ void* command_event; + /** the io thread wants to exit */ + int want_to_exit; /** If the log server is connected to over unix domain sockets, * eg. a file is named that is created to log onto. */ @@ -236,4 +250,56 @@ void dt_msg_queue_delete(struct dt_msg_queue* mq); */ void dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len); +/** + * Create IO thread. + * @return new io thread object. not yet started. or NULL malloc failure. + */ +struct dt_io_thread* dt_io_thread_create(void); + +/** + * Delete the IO thread structure. + * @param dtio: the io thread that is deleted. It must not be running. + */ +void dt_io_thread_delete(struct dt_io_thread* dtio); + +/** + * Apply config to the dtio thread + * @param dtio: io thread, not yet started. + * @param cfg: config file struct. + */ +void dt_io_thread_apply_cfg(struct dt_io_thread* dtio, + struct config_file *cfg); + +/** + * Register a msg queue to the io thread. It will be polled to see if + * there are messages and those then get removed and sent, when the thread + * is running. + * @param dtio: the io thread. + * @param mq: message queue to register. + * @return false on failure (malloc failure). + */ +int dt_io_thread_register_queue(struct dt_io_thread* dtio, + struct dt_msg_queue* mq); + +/** + * Unregister queue from io thread. + * @param dtio: the io thread. + * @param mq: message queue. + */ +void dt_io_thread_unregister_queue(struct dt_io_thread* dtio, + struct dt_msg_queue* mq); + +/** + * Start the io thread + * @param dtio: the io thread. + * @return false on failure. + */ +int dt_io_thread_start(struct dt_io_thread* dtio); + +/** + * Stop the io thread + * @param dtio: the io thread. + */ +void dt_io_thread_stop(struct dt_io_thread* dtio); + #endif /* DTSTREAM_H */ From 351e0e69862e9f0fcbd44244dfdbfe8da4af12a3 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 21 Jan 2020 17:14:47 +0100 Subject: [PATCH 11/96] iothread find msg. --- dnstap/dtstream.c | 48 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 318e04bfc..db3cac475 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -196,15 +196,59 @@ void dt_io_thread_unregister_queue(struct dt_io_thread* dtio, } } +/** pick a message from the queue, lock and unlock, true if a message */ +static int pick_msg_from_queue(struct dt_msg_queue* mq, void** buf, + size_t* len) +{ + lock_basic_lock(&mq->lock); + if(mq->first) { + struct dt_msg_entry* entry = mq->first; + mq->first = entry->next; + if(!entry->next) mq->last = NULL; + mq->cursize -= entry->len; + lock_basic_unlock(&mq->lock); + + *buf = entry->buf; + *len = entry->len; + free(entry); + return 1; + } + lock_basic_unlock(&mq->lock); + return 0; +} + +/** find message in queue, false if no message, true if message to send */ +static int dtio_find_in_queue(struct dt_io_thread* dtio, + struct dt_msg_queue* mq) +{ + void* buf=NULL; + size_t len=0; + if(pick_msg_from_queue(mq, &buf, &len)) { + dtio->cur_msg = buf; + dtio->cur_msg_len = len; + dtio->cur_msg_done = 0; + return 1; + } + return 0; +} + /** find a new message to write, search message queues, false if none */ static int dtio_find_msg(struct dt_io_thread* dtio) { + struct dt_io_list_item* item = dtio->io_list; + while(item) { + if(dtio_find_in_queue(dtio, item->queue)) + return 1; + item = item->next; + } + return 0; } /** write more of the current messsage. false if incomplete, true if * the message is done */ -static int dtio_write_more(struct dt_io_thread* dtio) +static int dtio_write_more(int fd, struct dt_io_thread* dtio) { + return 0; } /** callback for the dnstap events, to write to the output */ @@ -220,7 +264,7 @@ static void dtio_output_cb(int fd, short ATTR_UNUSED(bits), void* arg) /* write it */ if(dtio->cur_msg_done < dtio->cur_msg_len) { - if(!dtio_write_more(dtio)) + if(!dtio_write_more(fd, dtio)) return; } From 3e7758ee5881aec9c3e9fd5ef00b061e30707d84 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 21 Jan 2020 17:15:37 +0100 Subject: [PATCH 12/96] Remove editor file that was added by mistake. --- dnstap/.dtstream.h.swp | Bin 28672 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 dnstap/.dtstream.h.swp diff --git a/dnstap/.dtstream.h.swp b/dnstap/.dtstream.h.swp deleted file mode 100644 index 22f3859addf6106a6718d567664f7a22a1b7e0ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28672 zcmeI5du(LaUB@SnHeH&8s#QhPKj383fbGuOn@vKiU7(q@$Lndmwlg!{2WdLFGjqqj z*_nGMbMLIzDSaeG4KzxVKnZD+mPj;}+KT*99u>4oLR$z>Qc*xWk|Nqvk*E+6grM=Izt_a{Rn5m;3!6|Ec$U z`;zN&mD_T;ji{gaJ$Z5FAFoZaW)x0`?a)u!UOncw9kRUN7C0048Z-T{9`(a!t>eXH zo@s`0;&o@5Nu2b2uQR>AL-y=Z#z4lvxiZjCT6^ApN$%=>SM8M|uGoFKdBf{h&$YBH zU&cVjK*m7EK*m7EK*m7EK*m7E!2d%AlJ2W=AHeSOo$YDheV+TA{`+e8dDm&uUFe>_ z%KaO-f7ATw^BdgraLfA(+~=FzzfWv=?>=V#WDH~sWDH~sWDH~sWDH~sWDH~sWDH~s zWDH~soC5=1Gne}b@;xnqI_Ljs{Qu&Q=5oIWejB_OoB~Hd1zZB2xHOmh68IwMfNQ{B z@ZC#tx%#fzp1vrTyBmBM+z#4c0z8Ab@hR|& z-~(VCybb&$cn0C(L2xIS2X6%zfeXO};AMo5KLn3}&w-DDTfuw4o57{vdBlxp!871H z;2*%J!9(C9paE9EkAW8uV!jE!3_b#G1642&-U==Q(pQf=VP%(@G80{|mjqsW(scYd z_SSr}(F>B?u9>MRldSuu-fy-19>02tY4m$NKTO)2X3bBMAY9Y5i67=o)H6$~i;E^` znJ~)j3c|$rCrMlLnoYlXU|60$H9>6jg_)Yk?K&9+%_*DQCA5jS&e3lq{hn`Y7i*Gr zZg@0JKlWqID)qF|;#)!6H%&io^nz}JL2C0zE@>F~l1Q`m>or?iE!pf+a*!6|>Ij;& zszo8b38J)OG1r=9nn^8)YV9EA-^A}skxDUXAdH~^yv3*z8bzm}M`A3Ae{5(YkU51Z2?*5fcE>74s)1d^D1O)v4% zTzTV##t$129%AN}D%HZuzzN5R?!;>~oT;}tWkUZ{;>wp_O%Q6iLbqBmWMYuX44KeA z=y>gR)bN|rLQX+Upyae5x>YhNE7PVCg^3r0v57)|i;1HQsiTTV4Csq^zGc{p zhf^=xJO{;4JBSlqP=Cm?K32W z&sh3|0UnVcH6Yfay>`rWC@hN2)isEnYw|_|}jOsY6_b5k2Z}I=<4<)0IT00()gIeHGhTl6k!=CF>yV`n^3HQSXG` za|6u{Y(``&SgXlge_(`^(W!X!`CvdE$XyYHjds83o8A2+XwL}E@$~v`t}`|LRv_cM zTB(+cg~PQ4(zZgLjy|F>GtwYw^{TyqxMfBV?^=@yx#cy2c93kQ6HL(Qw*3x%<^TN0r^%B$VMM>0%+A`l$t5p1MX|tV{tts-bvOHfsS|}Iu zrg)^dWJ>dDbAVYc~e~|nw8~BrF5{gSgIbEN0rst1v6JTTsTxz>z0a#7E6bU zOS46@TsF((C?6&Jq$!k3mD187Q(7{GrQ_ykf$Xc*wA9rK>7{~FMXXpX6>JrGb9A97 zg-E{H<)v!5Fk8(VcrDFVN0U)mb-7$M6Q!lu#nm}#l5$qc%k!mb<$&07aFzOtl?o+Q zi{Q8kr? z0^2k3h}q?pnmwN@z_dPdXENeFH;)kx_!Wt6e9jKaA}H@E<8fB=gh(5G5s$p8`1aZtTRQG41WG|_EF{Zt!$8=6&245#ieEGM@4wS*^ z_kxoobDJh+yEtkk8?q?NbjHFiRWAAbuJgZdLK)j`pf4>h6>)>Y!3uk0Ssv_bHWe)v z57r5G0==N#XU`h5AaABkU^bp1y9JUKGLS9Pa8t$RM+-=sW!Dk61Eu(8 zAQKOJZrLwTeJf%Iv>{WKtPE{0=wPcd4FOK@XhSbHp?ktfF+u4{Q zz1Q)R{bEulYKpVy{LCW88+8<1ra9z$5Kj#08*;myDPKg zBPppW8-an3@q5(8d2J~|g`}As@H^3%H2e1M+nYB_i(H~Ni*k$J6xhNk{}Oe?eh&vu zvu?XFZ}yn+CEE zPk~3ko!}0z0*#QvfQ+zq}+|RJZgNTfUt$eG9fx{$Dr$G}N03E5D>& zF*(|vZH<+fJ*|2)p*Yq~KEz7d>xUsb8%-_SF}5SR(5twaZh<1)ftR5wa5lnj>UvG| zi)gbUuVg1<9a&b}vJ>tM(m}lDXvI27H6&J}*NuRcmz`yoU6$Qj#y*K!Hg-!{9|>g5 zRHL=Fqu+SlZhN!F+p~8V67QESB~daO6pE)o}o`Pq$WqCNEUw6 z4#HjH%TBOmAhmiv-irdX;p5K}vUerZx;<4W& zjIf;W(oQVOlgMWMP=qMTR1MLWW>nMzWTJ5=GH&!aORSASR@Jo0F$$$6~;+MqOo35g{nFynY+OSQU6T7qHh#M+HelhebGB9-N8j@x~5m zJVq*N!|7ggtb)$wT*(ETZU7iL`O7mF30Se5trNSF0XhDe5ESC;edd zp4xkrcq){u-U&(K_M^q7;s;6OZ?a`mBfB}5jD?0xolf&jA4=`1lNQhu(KGNx4cBuy zw-k`^bVim7hl`lHRH`h9W!Gv&Vv81~D(gwF-Dfoy;-$9KjFA*BKW3(K@D?hx7Ubc% z<5I~r=TwQ!{t9(ypHs!v=TwE}e#IKZC8%QGIaVRrsYBxbcM#u4K;nNwSN-{CK7Sc} z2HXzh{SDv>a50ec|1W?C!7*?dxB#3F{*t)=QE(S{KR5_P3-}&!zvuy<2e*TpK>8V+G26(P<5epxNywuyY{EG9?tqk_9NqB)7ZRW$G)3csD^oF2FP^NXa_9YX2TQJ zR3s@kXzlzrl0wh0bn?^%YkJxquV^~mY`BurbmGqwcB|kejdhl&ag*e%+%|l2q?Vx_ zjuczOSXOuD)SOiHbF5lB8N6a1nKA1@Gw8A9M8x&lc3u>1Sx$?bnk`$2cEIVbh^r!L zik;ftlyyCswQJV++$cRWmh#%G_OX_o(!(-)K)81gw<&J0hk!)%xqY<1=Pk3)6~}*a?4a+7c~iX;Q8_Pu@A@pc*xj zPJyA3Cc573dYkQt%QF+o8UdEQ!!bE+MQBv&z>49vfNd7JD<6*Y)IRGuZhN8ikH4{6 zd8}{5COzjIbvL&q*{c>iH;a9CTOqo>4Fu_Qq@telB;z(gycS?AVdENQGN7QYn{Fm~+^}Ta#@K_)O~XQn_TMXK;28T}lR`=x&yQ zp#|3Uy|$WL_whJ8Xl(?Rc7WTM+oEh|492c)x6HHRdRmTD+Yf_1qm$5BFURSyA2mrm4(yR8)2 ztuG-SV$&F1%53arPGLaC^iHjRr4q(w0p-%Jh=X36AG>4VLN@Fi?MWu3andEXbVWKp z$nTA)BZq=kKWkxEXT~*Yx}o!09C6^Ov$)(6YWkeQF{mblDM^_6lazIRpD5a1HY1Rh zNzq;Y>dXB@uDHo^%NT8HY%x~Xy7AkQ%ndS7@i+TMoT+Wa_FaR~`q&+AC_KhPvsFSk}sRK%#|7|{;Yq1Kk(UDNVp8xnJaM?@i2-sB1)W3ZQQ-)ar?5O;q^ zFGjgdkvvwxGPc6*bl2}#0aJJyE8&E{c{T-*Y*>IO+6=^+txb)HUGK>3Jz|7C2xjQx zI5KpH)hF$^W*Ml-`M%yjLmksp;^?s)`fEGtd_5V`E3yS8=#*jC{pwh{bSrx2(l;dmMLrf+I>Er@GyWO)(y z*@@M35)xiy?2oimHf=*z?A~tZb;1)+5b1O6nn5R=Wp%SFZt)yeDI;ZjeZrZoP&RLfG@`}R1nEe*g<%zLD@kc{q@~Q1 z(U1Zsm8KMElQs}eYDrY{PX*~cSnc#wmnS-sX&QPYg|cZCW0}D*w5FGbM|#>`CMLa% zTNY-1lLB4xZosZzI1)NXp53tT#seDv$3*-;l(>`lKmGgsmx=Ko1s?_y`%i&4f|rT! z<=+1VN_;9~Ia#PweT z4}&|v&0r0*z;5te;(WOq@ay1R;2q#+z)QsWayK9X6W}G{`yYbe0UrbRf(4KR-z3ie z2DlGg53U5e!QT<*-vdqpx&QwI;{4A7A6yUQzW>*V^M4bhvHzR+JqKRA0G$Ec3yy&| zgV%uPiS7RaJPH03{0X=dc;E`4yi>&g!A~YJuz!^;oZGl%5(7&`CNZP|+gSXaNer39 zkVy<|DN=bblNg)|kx2}yrKPHLCNT`PkW6A2{lmpfVz3w1GKnFR7_34hlE(kM#DJi( zqspQJP&4YtpH^5Mh+8)r|9_O&{To2ye?n*dd74=N>)>H<4>$%6f&w@nNctxwPxg~B zkTH-kkTH-kkTH-kkTH-kkTH-kkTH-k@W0K#F8RJ7Ir-+^&l=aJrp*m|Z_9Z@-K!{mTwLq<3G{m6pZ@E_cxH?kwsBB!u`K YvbswG)((4bVdt-glRE<3mXrGa6Lv6hg8%>k From 9f2ac374f4bdf3c25199f32518b26e76cb498bf6 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 22 Jan 2020 11:44:11 +0100 Subject: [PATCH 13/96] fstrm routines for start and stop, fstrm_create_control_frame_start and fstrm_create_control_frame_stop, suitable for reuse, together with fstrm protocol defines. --- dnstap/dnstap.c | 1 - dnstap/dtstream.c | 77 +++++++++++++++++++++++++++++++++++++++++++++-- dnstap/dtstream.h | 34 +++++++++++++++++++-- 3 files changed, 105 insertions(+), 7 deletions(-) diff --git a/dnstap/dnstap.c b/dnstap/dnstap.c index e942c4194..d8bc155aa 100644 --- a/dnstap/dnstap.c +++ b/dnstap/dnstap.c @@ -56,7 +56,6 @@ #include "dnstap/dtstream.h" #include "dnstap/dnstap.pb-c.h" -#define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap" #define DNSTAP_INITIAL_BUF_SIZE 256 struct dt_msg { diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index db3cac475..ae77851bb 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -50,6 +50,52 @@ #include #endif +void* fstrm_create_control_frame_start(char* contenttype, size_t* len) +{ + uint32_t* control; + size_t n; + /* start framestream message: + * 4byte 0: control indicator. + * 4byte bigendian: length of control frame + * 4byte bigendian: type START + * 4byte bigendian: frame option: content-type + * 4byte bigendian: length of string + * string of content type (dnstap) + */ + n = 4+4+4+4+4+strlen(contenttype); + control = malloc(n); + if(!control) + return NULL; + control[0] = 0; + control[1] = htonl(4+4+4+strlen(contenttype)); + control[2] = htonl(FSTRM_CONTROL_FRAME_START); + control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE); + control[4] = htonl(strlen(contenttype)); + memmove(&control[5], contenttype, strlen(contenttype)); + *len = n; + return control; +} + +void* fstrm_create_control_frame_stop(size_t* len) +{ + uint32_t* control; + size_t n; + /* stop framestream message: + * 4byte 0: control indicator. + * 4byte bigendian: length of control frame + * 4byte bigendian: type STOP + */ + n = 4+4+4; + control = malloc(n); + if(!control) + return NULL; + control[0] = 0; + control[1] = htonl(4); + control[2] = htonl(FSTRM_CONTROL_FRAME_STOP); + *len = n; + return control; +} + struct dt_msg_queue* dt_msg_queue_create(void) { @@ -196,8 +242,9 @@ void dt_io_thread_unregister_queue(struct dt_io_thread* dtio, } } -/** pick a message from the queue, lock and unlock, true if a message */ -static int pick_msg_from_queue(struct dt_msg_queue* mq, void** buf, +/** pick a message from the queue, the routine locks and unlocks, + * returns true if there is a message */ +static int dt_msg_queue_pop(struct dt_msg_queue* mq, void** buf, size_t* len) { lock_basic_lock(&mq->lock); @@ -223,10 +270,11 @@ static int dtio_find_in_queue(struct dt_io_thread* dtio, { void* buf=NULL; size_t len=0; - if(pick_msg_from_queue(mq, &buf, &len)) { + if(dt_msg_queue_pop(mq, &buf, &len)) { dtio->cur_msg = buf; dtio->cur_msg_len = len; dtio->cur_msg_done = 0; + dtio->cur_msg_len_done = 0; return 1; } return 0; @@ -273,6 +321,7 @@ static void dtio_output_cb(int fd, short ATTR_UNUSED(bits), void* arg) dtio->cur_msg = NULL; dtio->cur_msg_len = 0; dtio->cur_msg_done = 0; + dtio->cur_msg_len_done = 0; } /** callback for the dnstap commandpipe, to stop the dnstap IO */ @@ -361,6 +410,24 @@ static void dtio_desetup(struct dt_io_thread* dtio) ub_event_base_free(dtio->event_base); } +/** setup a start control message */ +static int dtio_control_start_send(struct dt_io_thread* dtio) +{ + log_assert(dtio->cur_msg == NULL && dtio->cur_msg_len == 0); + dtio->cur_msg = fstrm_create_control_frame_start(DNSTAP_CONTENT_TYPE, + &dtio->cur_msg_len); + if(!dtio->cur_msg) { + return 0; + } + /* setup to send the control message */ + /* set that the buffer needs to be sent, but the length + * of that buffer is already written, that way the buffer can + * start with 0 length and then the length of the control frame in it*/ + dtio->cur_msg_done = 0; + dtio->cur_msg_len_done = 4; + return 1; +} + /** open the output file descriptor */ static void dtio_open_output(struct dt_io_thread* dtio) { @@ -396,6 +463,10 @@ static void dtio_open_output(struct dt_io_thread* dtio) } dtio->event = ev; + /* setup protocol control message to start */ + if(!dtio_control_start_send(dtio)) { + fatal_exit("dnstap io: out of memory"); + } } /** add the output file descriptor event for listening */ diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 5d4e57646..19d1667ff 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -108,6 +108,9 @@ struct dt_io_thread { size_t cur_msg_len; /** number of bytes written for the current message */ size_t cur_msg_done; + /** number of bytes of the length that have been written, + * for the current message length that precedes the frame */ + size_t cur_msg_len_done; /** command pipe that stops the pipe if closed. Used to quit * the program. [0] is read, [1] is written to. */ @@ -218,10 +221,35 @@ struct dt_io_list_item { /** the constant that denotes the control field type that is the * string for the content type of the stream. */ #define FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE 0x01 +/** the content type for DNSTAP frame streams */ +#define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap" -/* routine to send START message, with content type. */ -/* routine to send a frame. */ -/* routine to send STOP message. */ +/** + * routine for START message, with content type. + * This creates an FSTRM control frame of type START. + * @param contenttype: a zero delimited string with the content type. + * eg. DNSTAP_CONTENT_TYPE, "protobuf:dnstap.Dnstap" + * @param len: if a buffer is returned this is the length of that buffer. + * @return NULL on malloc failure. Returns a malloced buffer with the + * protocol message. The buffer starts with the 4byte 0 that indicates + * a control frame. The buffer should be sent without preceding it with + * the 'len' variable, but straight the 0 start zeroes, and then the + * length of the control frame itself is embedded next in the buffer, + * with the control frame after that in the buffer. + */ +void* fstrm_create_control_frame_start(char* contenttype, size_t* len); +/** + * routine for STOP message. + * This creates an FSTRM control frame of type STOP. + * @param len: if a buffer is returned this is the length of that buffer. + * @return NULL on malloc failure. Returns a malloced buffer with the + * protocol message. The buffer starts with the 4byte 0 that indicates + * a control frame. The buffer should be sent without preceding it with + * the 'len' variable, but straight the 0 start zeroes, and then the + * length of the control frame itself is embedded next in the buffer, + * with the control frame after that in the buffer. + */ +void* fstrm_create_control_frame_stop(size_t* len); /** * Create new (empty) worker message queue. Limit set to default on max. From 6fb602d57bba9fe1a0976f3d6553305be13ac55a Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 22 Jan 2020 11:57:15 +0100 Subject: [PATCH 14/96] improve fstrm routine documentation. --- dnstap/dtstream.h | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 19d1667ff..94c6b698d 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -225,29 +225,28 @@ struct dt_io_list_item { #define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap" /** - * routine for START message, with content type. * This creates an FSTRM control frame of type START. * @param contenttype: a zero delimited string with the content type. - * eg. DNSTAP_CONTENT_TYPE, "protobuf:dnstap.Dnstap" + * eg. use the constant DNSTAP_CONTENT_TYPE, which is defined as + * "protobuf:dnstap.Dnstap", for a dnstap frame stream. * @param len: if a buffer is returned this is the length of that buffer. * @return NULL on malloc failure. Returns a malloced buffer with the - * protocol message. The buffer starts with the 4byte 0 that indicates + * protocol message. The buffer starts with the 4 bytes of 0 that indicate * a control frame. The buffer should be sent without preceding it with - * the 'len' variable, but straight the 0 start zeroes, and then the - * length of the control frame itself is embedded next in the buffer, - * with the control frame after that in the buffer. + * the 'len' variable (like data frames are), but straight the content of the + * buffer, because the lengths are included in the buffer. This is so that + * the zero control indicator can be included before the control frame length. */ void* fstrm_create_control_frame_start(char* contenttype, size_t* len); /** - * routine for STOP message. * This creates an FSTRM control frame of type STOP. * @param len: if a buffer is returned this is the length of that buffer. * @return NULL on malloc failure. Returns a malloced buffer with the - * protocol message. The buffer starts with the 4byte 0 that indicates + * protocol message. The buffer starts with the 4 bytes of 0 that indicate * a control frame. The buffer should be sent without preceding it with - * the 'len' variable, but straight the 0 start zeroes, and then the - * length of the control frame itself is embedded next in the buffer, - * with the control frame after that in the buffer. + * the 'len' variable (like data frames are), but straight the content of the + * buffer, because the lengths are included in the buffer. This is so that + * the zero control indicator can be included before the control frame length. */ void* fstrm_create_control_frame_stop(size_t* len); From 3cc1f4a74e34a140067509a8ee886b6dcfbbedd3 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 22 Jan 2020 12:05:52 +0100 Subject: [PATCH 15/96] remove fatal_exit from runtime reopen routines. --- dnstap/dtstream.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index ae77851bb..1f833f1f9 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -422,7 +422,8 @@ static int dtio_control_start_send(struct dt_io_thread* dtio) /* setup to send the control message */ /* set that the buffer needs to be sent, but the length * of that buffer is already written, that way the buffer can - * start with 0 length and then the length of the control frame in it*/ + * start with 0 length and then the length of the control frame + * in it */ dtio->cur_msg_done = 0; dtio->cur_msg_len_done = 4; return 1; @@ -450,6 +451,8 @@ static void dtio_open_output(struct dt_io_thread* dtio) if(connect(dtio->fd, (struct sockaddr*)&s, (socklen_t)sizeof(s)) == -1) { log_err("dnstap io: failed to connect: %s", strerror(errno)); + close(dtio->fd); + dtio->fd = -1; return; } fd_set_nonblock(dtio->fd); @@ -459,21 +462,32 @@ static void dtio_open_output(struct dt_io_thread* dtio) UB_EV_READ | UB_EV_WRITE | UB_EV_PERSIST, &dtio_output_cb, dtio); if(!ev) { - fatal_exit("dnstap io: out of memory"); + close(dtio->fd); + dtio->fd = -1; + log_err("dnstap io: out of memory"); + return; } dtio->event = ev; /* setup protocol control message to start */ if(!dtio_control_start_send(dtio)) { - fatal_exit("dnstap io: out of memory"); + ub_event_free(dtio->event); + dtio->event = NULL; + close(dtio->fd); + dtio->fd = -1; + log_err("dnstap io: out of memory"); + return; } } /** add the output file descriptor event for listening */ static void dtio_add_output_event(struct dt_io_thread* dtio) { + if(!dtio->event) + return; if(ub_event_add(dtio->event, NULL) != 0) { - fatal_exit("dnstap io: out of memory (adding event)"); + log_err("dnstap io: out of memory (adding event)"); + return; } dtio->event_added = 1; } From a21ac9838deef24581d51c1a62b4194182712a38 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 22 Jan 2020 15:20:48 +0100 Subject: [PATCH 16/96] write data and stop flush for dnstap io. --- dnstap/dtstream.c | 413 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 400 insertions(+), 13 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 1f833f1f9..9d7a465cd 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -292,15 +292,170 @@ static int dtio_find_msg(struct dt_io_thread* dtio) return 0; } +/** close and stop the output file descriptor event */ +static void dtio_close_output(struct dt_io_thread* dtio) +{ + if(!dtio->event) + return; + ub_event_free(dtio->event); + dtio->event = NULL; +#ifndef USE_WINSOCK + close(dtio->fd); +#else + closesocket(dtio->fd); +#endif + dtio->fd = -1; +} + +/** write buffer to output. + * returns number of bytes written, 0 if nothing happened, + * try again later, or -1 if the channel is to be closed. */ +static int dtio_write_buf(struct dt_io_thread* dtio, uint8_t* buf, + size_t len) +{ + ssize_t ret; + if(dtio->fd == -1) + return -1; + ret = send(dtio->fd, buf, len, 0); + if(ret == -1) { +#ifndef USE_WINSOCK + if(errno == EINTR || errno == EAGAIN) + return 0; + log_err("dnstap io: failed send: %s", strerror(errno)); +#else + if(WSAGetLastError() == WSAEINPROGRESS) + return 0; + if(WSAGetLastError() == WSAEWOULDBLOCK) { + ub_winsock_tcp_wouldblock(dtio->event, UB_EV_WRITE); + return 0; + } + log_err("dnstap io: failed send: %s", + wsa_strerror(WSAGetLastError())); +#endif + return -1; + } + return ret; +} + +#ifdef HAVE_WRITEV +/** write with writev, len and message, in one write, if possible. + * return true if message is done, false if incomplete */ +static int dtio_write_with_writev(struct dt_io_thread* dtio) +{ + uint32_t sendlen = htonl(dtio->cur_msg_len); + struct iovec iov[2]; + ssize_t r; + iov[0].iov_base = ((uint8_t*)&sendlen)+dtio->cur_msg_len_done; + iov[0].iov_len = sizeof(sendlen)-dtio->cur_msg_len_done; + iov[1].iov_base = dtio->cur_msg; + iov[1].iov_len = dtio->cur_msg_len; + log_assert(iov[0].iov_len > 0); + r = writev(dtio->fd, iov, 2); + if(r == -1) { +#ifndef USE_WINSOCK + if(errno == EINTR || errno == EAGAIN) + return 0; + log_err("dnstap io: failed writev: %s", strerror(errno)); +#else + if(WSAGetLastError() == WSAEINPROGRESS) + return 0; + if(WSAGetLastError() == WSAEWOULDBLOCK) { + ub_winsock_tcp_wouldblock(dtio->event, UB_EV_WRITE); + return 0; + } + log_err("dnstap io: failed writev: %s", + wsa_strerror(WSAGetLastError())); +#endif + return -1; + } + /* written r bytes */ + dtio->cur_msg_len_done += r; + if(dtio->cur_msg_len_done < 4) + return 0; + if(dtio->cur_msg_len_done > 4) { + dtio->cur_msg_done = dtio->cur_msg_len_done-4; + dtio->cur_msg_len_done = 4; + } + if(dtio->cur_msg_done < dtio->cur_msg_len) + return 0; + return 1; +} +#endif /* HAVE_WRITEV */ + +/** write more of the length, preceding the data frame. + * return true if message is done, false if incomplete. */ +static int dtio_write_more_of_len(struct dt_io_thread* dtio) +{ +#ifndef HAVE_WRITEV + uint32_t sendlen = htonl(dtio->cur_msg_len); + int r; +#endif + if(dtio->cur_msg_len_done >= 4) + return 1; +#ifdef HAVE_WRITEV + /* we try writev for everything.*/ + return dtio_write_with_writev(dtio); +#else + r = dtio_write_buf(dtio, + ((uint8_t*)&sendlen)+dtio->cur_msg_len_done, + sizeof(sendlen)-dtio->cur_msg_len_done); + if(r == -1) { + /* close the channel */ + dtio_close_output(dtio); + return 0; + } else if(r == 0) { + /* try again later */ + return 0; + } + dtio->cur_msg_len_done += r; + if(dtio->cur_msg_len_done < 4) + return 0; + return 1; +#endif /* HAVE_WRITEV */ +} + +/** write more of the data frame. + * return true if message is done, false if incomplete. */ +static int dtio_write_more_of_data(struct dt_io_thread* dtio) +{ + int r; + if(dtio->cur_msg_done >= dtio->cur_msg_len) + return 1; + r = dtio_write_buf(dtio, + ((uint8_t*)dtio->cur_msg)+dtio->cur_msg_done, + dtio->cur_msg_len - dtio->cur_msg_done); + if(r == -1) { + /* close the channel */ + dtio_close_output(dtio); + return 0; + } else if(r == 0) { + /* try again later */ + return 0; + } + dtio->cur_msg_done += r; + if(dtio->cur_msg_done < dtio->cur_msg_len) + return 0; + return 1; +} + /** write more of the current messsage. false if incomplete, true if * the message is done */ -static int dtio_write_more(int fd, struct dt_io_thread* dtio) +static int dtio_write_more(struct dt_io_thread* dtio) { - return 0; + if(dtio->cur_msg_len_done < 4) { + if(!dtio_write_more_of_len(dtio)) + return 0; + } + if(dtio->cur_msg_done < dtio->cur_msg_len) { + if(!dtio_write_more_of_data(dtio)) + return 0; + } + return 1; } /** callback for the dnstap events, to write to the output */ -static void dtio_output_cb(int fd, short ATTR_UNUSED(bits), void* arg) +static void dtio_output_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), + void* arg) { struct dt_io_thread* dtio = (struct dt_io_thread*)arg; @@ -312,7 +467,7 @@ static void dtio_output_cb(int fd, short ATTR_UNUSED(bits), void* arg) /* write it */ if(dtio->cur_msg_done < dtio->cur_msg_len) { - if(!dtio_write_more(fd, dtio)) + if(!dtio_write_more(dtio)) return; } @@ -334,15 +489,25 @@ static void dtio_cmd_cb(int fd, short ATTR_UNUSED(bits), void* arg) return; r = read(fd, &cmd, sizeof(cmd)); if(r == -1) { +#ifndef USE_WINSOCK if(errno == EINTR || errno == EAGAIN) return; /* ignore this */ log_err("dnstap io: failed to read: %s", strerror(errno)); +#else + if(WSAGetLastError() == WSAEINPROGRESS) + return; + if(WSAGetLastError() == WSAEWOULDBLOCK) + return; + log_err("dnstap io: failed to read: %s", + wsa_strerror(WSAGetLastError())); +#endif /* and then fall through to quit the thread */ - } - if(r == 0) { + } else if(r == 0) { verbose(VERB_ALGO, "dnstap io: cmd channel closed"); } else if(r == 1 && cmd == 0) { verbose(VERB_ALGO, "dnstap io: cmd channel cmd quit"); + } else if(r == 1) { + verbose(VERB_ALGO, "dnstap io: cmd channel unknown command"); } dtio->want_to_exit = 1; if(ub_event_base_loopexit((struct ub_event_base*)dtio->event_base) @@ -387,26 +552,205 @@ static void dtio_del_output_event(struct dt_io_thread* dtio) dtio->event_added = 0; } -/** close and stop the output file descriptor event */ -static void dtio_close_output(struct dt_io_thread* dtio) +/** + * structure to keep track of information during stop flush + */ +struct stop_flush_info { + /** the event base during stop flush */ + struct ub_event_base* base; + /** did we already want to exit this stop-flush event base */ + int want_to_exit_flush; + /** has the timer fired */ + int timer_done; + /** the dtio */ + struct dt_io_thread* dtio; + /** the stop control frame */ + void* stop_frame; + /** length of the stop frame */ + size_t stop_frame_len; + /** how much we have done of the stop frame */ + size_t stop_frame_done; +}; + +/** exit the stop flush base */ +static void dtio_stop_flush_exit(struct stop_flush_info* info) { - if(!dtio->event) + if(info->want_to_exit_flush) return; - ub_event_free(dtio->event); - dtio->event = NULL; - close(dtio->fd); - dtio->fd = -1; + info->want_to_exit_flush = 1; + if(ub_event_base_loopexit(info->base) != 0) { + log_err("dnstap io: could not loopexit"); + } +} + +/** send the stop control, + * return true if completed the frame. */ +static int dtio_control_stop_send(struct stop_flush_info* info) +{ + struct dt_io_thread* dtio = info->dtio; + int r; + if(info->stop_frame_done >= info->stop_frame_len) + return 1; + r = dtio_write_buf(dtio, ((uint8_t*)info->stop_frame) + + info->stop_frame_done, info->stop_frame_len - + info->stop_frame_done); + if(r == -1) { + verbose(VERB_ALGO, "dnstap io: stop flush: output closed"); + dtio_stop_flush_exit(info); + return 0; + } + if(r == 0) { + /* try again later, or timeout */ + return 0; + } + info->stop_frame_done += r; + if(info->stop_frame_done < info->stop_frame_len) + return 0; /* not done yet */ + return 1; +} + +static void dtio_stop_timer_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), + void* arg) +{ + struct stop_flush_info* info = (struct stop_flush_info*)arg; + if(info->want_to_exit_flush) + return; + verbose(VERB_ALGO, "dnstap io: stop flush timer expired, stop flush"); + info->timer_done = 1; + dtio_stop_flush_exit(info); +} + +static void dtio_stop_ev_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), + void* arg) +{ + struct stop_flush_info* info = (struct stop_flush_info*)arg; + struct dt_io_thread* dtio = info->dtio; + if(info->want_to_exit_flush) + return; + /* write remainder of last frame */ + if(dtio->cur_msg) { + if(dtio->cur_msg_done < dtio->cur_msg_len) { + if(!dtio_write_more(dtio)) { + if(dtio->fd == -1) { + verbose(VERB_ALGO, "dnstap io: " + "stop flush: output closed"); + dtio_stop_flush_exit(info); + } + return; + } + } + verbose(VERB_ALGO, "dnstap io: stop flush completed " + "last frame"); + free(dtio->cur_msg); + dtio->cur_msg = NULL; + dtio->cur_msg_len = 0; + dtio->cur_msg_done = 0; + dtio->cur_msg_len_done = 0; + } + /* write stop frame */ + if(info->stop_frame_done < info->stop_frame_len) { + if(!dtio_control_stop_send(info)) + return; + verbose(VERB_ALGO, "dnstap io: stop flush completed " + "stop control frame"); + } + /* when last frame and stop frame are sent, exit */ + dtio_stop_flush_exit(info); +} + +/** flush at end, last packet and stop control */ +static void dtio_control_stop_flush(struct dt_io_thread* dtio) +{ + /* briefly attempt to flush the previous packet to the output, + * this could be a partial packet, or even the start control frame */ + time_t secs = 0; + struct timeval now; + struct stop_flush_info info; + struct timeval tv; + struct ub_event* timer, *stopev; + memset(&info, 0, sizeof(info)); + memset(&now, 0, sizeof(now)); + info.base = ub_default_event_base(0, &secs, &now); + if(!info.base) { + log_err("dnstap io: malloc failure"); + return; + } + timer = ub_event_new(info.base, -1, UB_EV_TIMEOUT, + &dtio_stop_timer_cb, &info); + if(!timer) { + log_err("dnstap io: malloc failure"); + ub_event_base_free(info.base); + return; + } + memset(&tv, 0, sizeof(tv)); + tv.tv_sec = 2; + if(ub_timer_add(timer, info.base, &dtio_stop_timer_cb, &info, + &tv) != 0) { + log_err("dnstap io: cannot event_timer_add"); + ub_event_free(timer); + ub_event_base_free(info.base); + return; + } + stopev = ub_event_new(info.base, dtio->fd, UB_EV_READ | + UB_EV_WRITE | UB_EV_PERSIST, &dtio_stop_ev_cb, &info); + if(!stopev) { + log_err("dnstap io: malloc failure"); + ub_event_del(timer); + ub_event_free(timer); + ub_event_base_free(info.base); + return; + } + if(ub_event_add(stopev, NULL) != 0) { + log_err("dnstap io: cannot event_add"); + ub_event_free(stopev); + ub_event_del(timer); + ub_event_free(timer); + ub_event_base_free(info.base); + return; + } + info.stop_frame = fstrm_create_control_frame_stop( + &info.stop_frame_len); + if(!info.stop_frame) { + log_err("dnstap io: malloc failure"); + ub_event_del(stopev); + ub_event_free(stopev); + ub_event_del(timer); + ub_event_free(timer); + ub_event_base_free(info.base); + return; + } + + /* wait briefly, or until finished */ + verbose(VERB_ALGO, "dnstap io: stop flush started"); + if(ub_event_base_dispatch(info.base) < 0) { + log_err("dnstap io: dispatch flush failed, errno is %s", + strerror(errno)); + } + verbose(VERB_ALGO, "dnstap io: stop flush ended"); + free(info.stop_frame); + ub_event_del(stopev); + ub_event_free(stopev); + ub_event_del(timer); + ub_event_free(timer); + ub_event_base_free(info.base); } /** perform desetup and free stuff when the dnstap io thread exits */ static void dtio_desetup(struct dt_io_thread* dtio) { + dtio_control_stop_flush(dtio); dtio_del_output_event(dtio); dtio_close_output(dtio); ub_event_del(dtio->command_event); ub_event_free(dtio->command_event); +#ifndef USE_WINSOCK close(dtio->commandpipe[0]); +#else + _close(dtio->commandpipe[0]); +#endif dtio->commandpipe[0] = -1; + free(dtio->cur_msg); + dtio->cur_msg = NULL; ub_event_base_free(dtio->event_base); } @@ -436,8 +780,13 @@ static void dtio_open_output(struct dt_io_thread* dtio) struct sockaddr_un s; dtio->fd = socket(AF_LOCAL, SOCK_STREAM, SOCK_CLOEXEC); if(dtio->fd == -1) { +#ifndef USE_WINSOCK log_err("dnstap io: failed to create socket: %s", strerror(errno)); +#else + log_err("dnstap io: failed to create socket: %s", + wsa_strerror(WSAGetLastError())); +#endif return; } memset(&s, 0, sizeof(s)); @@ -450,8 +799,17 @@ static void dtio_open_output(struct dt_io_thread* dtio) (void)strlcpy(s.sun_path, dtio->socket_path, sizeof(s.sun_path)); if(connect(dtio->fd, (struct sockaddr*)&s, (socklen_t)sizeof(s)) == -1) { +#ifndef USE_WINSOCK log_err("dnstap io: failed to connect: %s", strerror(errno)); +#else + log_err("dnstap io: failed to connect: %s", + wsa_strerror(WSAGetLastError())); +#endif +#ifndef USE_WINSOCK close(dtio->fd); +#else + closesocket(dtio->fd); +#endif dtio->fd = -1; return; } @@ -462,7 +820,11 @@ static void dtio_open_output(struct dt_io_thread* dtio) UB_EV_READ | UB_EV_WRITE | UB_EV_PERSIST, &dtio_output_cb, dtio); if(!ev) { +#ifndef USE_WINSOCK close(dtio->fd); +#else + closesocket(dtio->fd); +#endif dtio->fd = -1; log_err("dnstap io: out of memory"); return; @@ -473,7 +835,11 @@ static void dtio_open_output(struct dt_io_thread* dtio) if(!dtio_control_start_send(dtio)) { ub_event_free(dtio->event); dtio->event = NULL; +#ifndef USE_WINSOCK close(dtio->fd); +#else + closesocket(dtio->fd); +#endif dtio->fd = -1; log_err("dnstap io: out of memory"); return; @@ -521,10 +887,18 @@ static void* dnstap_io(void* arg) int dt_io_thread_start(struct dt_io_thread* dtio) { /* set up the thread, can fail */ +#ifndef USE_WINSOCK if(pipe(dtio->commandpipe) == -1) { log_err("failed to create pipe: %s", strerror(errno)); return 0; } +#else + if(_pipe(dtio->commandpipe, 4096, _O_BINARY) == -1) { + log_err("failed to create _pipe: %s", + wsa_strerror(WSAGetLastError())); + return 0; + } +#endif /* start the thread */ ub_thread_create(&dtio->tid, dnstap_io, dtio); @@ -540,15 +914,28 @@ void dt_io_thread_stop(struct dt_io_thread* dtio) while(1) { ssize_t r = write(dtio->commandpipe[1], &cmd, sizeof(cmd)); if(r == -1) { +#ifndef USE_WINSOCK if(errno == EINTR || errno == EAGAIN) continue; log_err("dnstap io stop: write: %s", strerror(errno)); +#else + if(WSAGetLastError() == WSAEINPROGRESS) + continue; + if(WSAGetLastError() == WSAEWOULDBLOCK) + continue; + log_err("dnstap io stop: write: %s", + wsa_strerror(WSAGetLastError())); +#endif break; } break; } +#ifndef USE_WINSOCK close(dtio->commandpipe[1]); +#else + _close(dtio->commandpipe[1]); +#endif dtio->commandpipe[1] = -1; ub_thread_join(dtio->tid); } From 814a8863544ffc47098efff83adb1ee4dbd40ae3 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 22 Jan 2020 15:26:04 +0100 Subject: [PATCH 17/96] output event del before free. --- dnstap/dtstream.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 9d7a465cd..2e2de641a 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -292,6 +292,15 @@ static int dtio_find_msg(struct dt_io_thread* dtio) return 0; } +/** del the output file descriptor event for listening */ +static void dtio_del_output_event(struct dt_io_thread* dtio) +{ + if(!dtio->event_added) + return; + ub_event_del(dtio->event); + dtio->event_added = 0; +} + /** close and stop the output file descriptor event */ static void dtio_close_output(struct dt_io_thread* dtio) { @@ -366,7 +375,10 @@ static int dtio_write_with_writev(struct dt_io_thread* dtio) log_err("dnstap io: failed writev: %s", wsa_strerror(WSAGetLastError())); #endif - return -1; + /* close the channel */ + dtio_del_output_event(dtio); + dtio_close_output(dtio); + return 0; } /* written r bytes */ dtio->cur_msg_len_done += r; @@ -401,6 +413,7 @@ static int dtio_write_more_of_len(struct dt_io_thread* dtio) sizeof(sendlen)-dtio->cur_msg_len_done); if(r == -1) { /* close the channel */ + dtio_del_output_event(dtio); dtio_close_output(dtio); return 0; } else if(r == 0) { @@ -426,6 +439,7 @@ static int dtio_write_more_of_data(struct dt_io_thread* dtio) dtio->cur_msg_len - dtio->cur_msg_done); if(r == -1) { /* close the channel */ + dtio_del_output_event(dtio); dtio_close_output(dtio); return 0; } else if(r == 0) { @@ -543,15 +557,6 @@ static void dtio_setup_cmd(struct dt_io_thread* dtio) } } -/** del the output file descriptor event for listening */ -static void dtio_del_output_event(struct dt_io_thread* dtio) -{ - if(!dtio->event_added) - return; - ub_event_del(dtio->event); - dtio->event_added = 0; -} - /** * structure to keep track of information during stop flush */ From 569cccea24798bbae5e3034c9c63d119b9cc4807 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 22 Jan 2020 17:41:34 +0100 Subject: [PATCH 18/96] dnstap io output performs nonblocking connect. --- dnstap/dtstream.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++- dnstap/dtstream.h | 2 ++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 2e2de641a..4ebf9f21e 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -316,6 +316,49 @@ static void dtio_close_output(struct dt_io_thread* dtio) dtio->fd = -1; } +/** check for pending nonblocking connect errors, + * returns 1 if it is okay. -1 on error (close it), 0 to try later */ +static int dtio_check_nb_connect(struct dt_io_thread* dtio) +{ + int error = 0; + socklen_t len = (socklen_t)sizeof(error); + if(!dtio->check_nb_connect) + return 1; /* everything okay */ + if(getsockopt(dtio->fd, SOL_SOCKET, SO_ERROR, (void*)&error, + &len) < 0) { +#ifndef USE_WINSOCK + error = errno; /* on solaris errno is error */ +#else + error = WSAGetLastError(); +#endif + } +#ifndef USE_WINSOCK +#if defined(EINPROGRESS) && defined(EWOULDBLOCK) + if(error == EINPROGRESS || error == EWOULDBLOCK) + return 0; /* try again later */ +#endif +#else + if(error == WSAEINPROGRESS) { + return 0; /* try again later */ + } else if(error == WSAEWOULDBLOCK) { + ub_winsock_tcp_wouldblock(dtio->event, UB_EV_WRITE); + return 0; /* try again later */ + } +#endif + if(error != 0) { +#ifndef USE_WINSOCK + log_err("dnstap io: failed to connect: %s", strerror(error)); +#else + log_err("dnstap io: failed to connect: %s", + wsa_strerror(error)); +#endif + return -1; /* error, close it */ + } + + dtio->check_nb_connect = 0; + return 1; /* everything okay */ +} + /** write buffer to output. * returns number of bytes written, 0 if nothing happened, * try again later, or -1 if the channel is to be closed. */ @@ -325,6 +368,14 @@ static int dtio_write_buf(struct dt_io_thread* dtio, uint8_t* buf, ssize_t ret; if(dtio->fd == -1) return -1; + if(dtio->check_nb_connect) { + int connect_err = dtio_check_nb_connect(dtio); + if(connect_err == -1) { + return -1; + } else if(connect_err == 0) { + return 0; + } + } ret = send(dtio->fd, buf, len, 0); if(ret == -1) { #ifndef USE_WINSOCK @@ -354,6 +405,17 @@ static int dtio_write_with_writev(struct dt_io_thread* dtio) uint32_t sendlen = htonl(dtio->cur_msg_len); struct iovec iov[2]; ssize_t r; + if(dtio->check_nb_connect) { + int connect_err = dtio_check_nb_connect(dtio); + if(connect_err == -1) { + /* close the channel */ + dtio_del_output_event(dtio); + dtio_close_output(dtio); + return 0; + } else if(connect_err == 0) { + return 0; + } + } iov[0].iov_base = ((uint8_t*)&sendlen)+dtio->cur_msg_len_done; iov[0].iov_len = sizeof(sendlen)-dtio->cur_msg_len_done; iov[1].iov_base = dtio->cur_msg; @@ -802,6 +864,7 @@ static void dtio_open_output(struct dt_io_thread* dtio) s.sun_family = AF_LOCAL; /* length is 92-108, 104 on FreeBSD */ (void)strlcpy(s.sun_path, dtio->socket_path, sizeof(s.sun_path)); + fd_set_nonblock(dtio->fd); if(connect(dtio->fd, (struct sockaddr*)&s, (socklen_t)sizeof(s)) == -1) { #ifndef USE_WINSOCK @@ -818,7 +881,7 @@ static void dtio_open_output(struct dt_io_thread* dtio) dtio->fd = -1; return; } - fd_set_nonblock(dtio->fd); + dtio->check_nb_connect = 1; /* the EV_READ is to catch channel close, write to write packets */ ev = ub_event_new(dtio->event_base, dtio->fd, diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 94c6b698d..7641ffbd6 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -101,6 +101,8 @@ struct dt_io_thread { void* event; /** the event is added */ int event_added; + /** check for nonblocking connect errors on fd */ + int check_nb_connect; /** the buffer that currently getting written, or NULL if no * (partial) message written now */ void* cur_msg; From e9772b609e83eba2d7c2efc695f250d99e08f3c4 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 23 Jan 2020 09:55:15 +0100 Subject: [PATCH 19/96] dnstap io fixup socket creation, stop flush dtio pointer, connect reports. --- dnstap/dtstream.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 4ebf9f21e..e414d5d02 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -346,15 +346,18 @@ static int dtio_check_nb_connect(struct dt_io_thread* dtio) } #endif if(error != 0) { + char* to = dtio->socket_path; #ifndef USE_WINSOCK - log_err("dnstap io: failed to connect: %s", strerror(error)); + log_err("dnstap io: failed to connect to \"%s\": %s", + to, strerror(error)); #else - log_err("dnstap io: failed to connect: %s", - wsa_strerror(error)); + log_err("dnstap io: failed to connect to \"%s\": %s", + to, wsa_strerror(error)); #endif return -1; /* error, close it */ } + verbose(VERB_ALGO, "dnstap io: connected to \"%s\"", dtio->socket_path); dtio->check_nb_connect = 0; return 1; /* everything okay */ } @@ -735,8 +738,16 @@ static void dtio_control_stop_flush(struct dt_io_thread* dtio) struct stop_flush_info info; struct timeval tv; struct ub_event* timer, *stopev; + + if(dtio->fd == -1 || dtio->check_nb_connect) { + /* no connection or we have just connected, so nothing is + * sent yet, so nothing to stop or flush */ + return; + } + memset(&info, 0, sizeof(info)); memset(&now, 0, sizeof(now)); + info.dtio = dtio; info.base = ub_default_event_base(0, &secs, &now); if(!info.base) { log_err("dnstap io: malloc failure"); @@ -845,7 +856,7 @@ static void dtio_open_output(struct dt_io_thread* dtio) { struct ub_event* ev; struct sockaddr_un s; - dtio->fd = socket(AF_LOCAL, SOCK_STREAM, SOCK_CLOEXEC); + dtio->fd = socket(AF_LOCAL, SOCK_STREAM, 0); if(dtio->fd == -1) { #ifndef USE_WINSOCK log_err("dnstap io: failed to create socket: %s", @@ -867,11 +878,13 @@ static void dtio_open_output(struct dt_io_thread* dtio) fd_set_nonblock(dtio->fd); if(connect(dtio->fd, (struct sockaddr*)&s, (socklen_t)sizeof(s)) == -1) { + char* to = dtio->socket_path; #ifndef USE_WINSOCK - log_err("dnstap io: failed to connect: %s", strerror(errno)); + log_err("dnstap io: failed to connect to \"%s\": %s", + to, strerror(errno)); #else - log_err("dnstap io: failed to connect: %s", - wsa_strerror(WSAGetLastError())); + log_err("dnstap io: failed to connect to \"%s\": %s", + to, wsa_strerror(WSAGetLastError())); #endif #ifndef USE_WINSOCK close(dtio->fd); From 14d76588973715f63753cd884b5f5791f52a42ca Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 23 Jan 2020 10:34:38 +0100 Subject: [PATCH 20/96] dtio_find_msg loop roundrobin instead of first queue only, with state in the dtio struct for loop iterator. --- dnstap/dtstream.c | 13 ++++++++++++- dnstap/dtstream.h | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index e414d5d02..c3270a008 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -221,6 +221,7 @@ int dt_io_thread_register_queue(struct dt_io_thread* dtio, item->queue = mq; item->next = dtio->io_list; dtio->io_list = item; + dtio->io_list_iter = NULL; return 1; } @@ -235,6 +236,7 @@ void dt_io_thread_unregister_queue(struct dt_io_thread* dtio, else dtio->io_list = item->next; /* the queue itself only registered, not deleted */ free(item); + dtio->io_list_iter = NULL; return; } prev = item; @@ -283,7 +285,16 @@ static int dtio_find_in_queue(struct dt_io_thread* dtio, /** find a new message to write, search message queues, false if none */ static int dtio_find_msg(struct dt_io_thread* dtio) { - struct dt_io_list_item* item = dtio->io_list; + struct dt_io_list_item* item; + + if(dtio->io_list_iter) + item = dtio->io_list_iter; + else item = dtio->io_list; + /* use the next queue for the next message lookup, + * if we hit the end(NULL) the NULL restarts the iter at start. */ + if(item) + dtio->io_list_iter = item->next; + while(item) { if(dtio_find_in_queue(dtio, item->queue)) return 1; diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 7641ffbd6..3c5bd9a4e 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -93,6 +93,10 @@ struct dt_io_thread { void* event_base; /** list of queues that is registered to get written */ struct dt_io_list_item* io_list; + /** iterator point in the io_list, to pick from them in a + * round-robin fashion, instead of only from the first when busy. + * if NULL it means start at the start of the list. */ + struct dt_io_list_item* io_list_iter; /** thread id, of the io thread */ ub_thread_type tid; /** file descriptor that the thread writes to */ From 24536473d8871bdcc22b54049ada8380c1f54850 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 23 Jan 2020 11:07:30 +0100 Subject: [PATCH 21/96] dnstap io: check for close of channel by the other side. --- dnstap/dtstream.c | 61 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index c3270a008..2642528ff 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -543,11 +543,56 @@ static int dtio_write_more(struct dt_io_thread* dtio) return 1; } +/** check if the output fd has been closed */ +static void dtio_check_close(struct dt_io_thread* dtio) +{ + /* we don't want to read any packets, but if there are we can + * discard the input (ignore it), which is okay for a framestream, + * and also, the read call can return that the stream has been + * closed by the other side. */ + ssize_t r; + uint8_t buf[1024]; + if(dtio->fd == -1) return; + while(1) { + r = recv(dtio->fd, buf, sizeof(buf), 0); + if(r == -1) { +#ifndef USE_WINSOCK + if(errno == EINTR || errno == EAGAIN) + return; /* try later */ +#else + if(WSAGetLastError() == WSAEINPROGRESS) { + return; /* try later */ + } else if(WSAGetLastError() == WSAEWOULDBLOCK) { + ub_winsock_tcp_wouldblock(dtio->event, UB_EV_READ); + return; /* try later */ + } +#endif + log_err("dnstap io: output recv: %s", strerror(errno)); + /* and close below */ + break; + } + if(r == 0) { + verbose(VERB_ALGO, "dnstap io: output closed by the other side"); + /* and close below */ + break; + } + /* something was received, ignore it */ + } + /* the other end has been closed */ + /* close the channel */ + dtio_del_output_event(dtio); + dtio_close_output(dtio); +} + /** callback for the dnstap events, to write to the output */ -static void dtio_output_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), - void* arg) +static void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg) { struct dt_io_thread* dtio = (struct dt_io_thread*)arg; + + if((bits&UB_EV_READ)) { + dtio_check_close(dtio); + return; + } /* see if there are messages that need writing */ if(!dtio->cur_msg) { @@ -701,13 +746,21 @@ static void dtio_stop_timer_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), dtio_stop_flush_exit(info); } -static void dtio_stop_ev_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), - void* arg) +static void dtio_stop_ev_cb(int ATTR_UNUSED(fd), short bits, void* arg) { struct stop_flush_info* info = (struct stop_flush_info*)arg; struct dt_io_thread* dtio = info->dtio; if(info->want_to_exit_flush) return; + if((bits&UB_EV_READ)) { + dtio_check_close(dtio); + if(dtio->fd == -1) { + verbose(VERB_ALGO, "dnstap io: " + "stop flush: output closed"); + dtio_stop_flush_exit(info); + } + return; + } /* write remainder of last frame */ if(dtio->cur_msg) { if(dtio->cur_msg_done < dtio->cur_msg_len) { From e7d5a89ae297494050f39725348d9b5fb36145ef Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 23 Jan 2020 11:16:41 +0100 Subject: [PATCH 22/96] check close neater also with a write at the same time. --- dnstap/dtstream.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 2642528ff..963d4769f 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -543,28 +543,30 @@ static int dtio_write_more(struct dt_io_thread* dtio) return 1; } -/** check if the output fd has been closed */ -static void dtio_check_close(struct dt_io_thread* dtio) +/** check if the output fd has been closed, + * it returns false if the stream is closed. */ +static int dtio_check_close(struct dt_io_thread* dtio) { /* we don't want to read any packets, but if there are we can - * discard the input (ignore it), which is okay for a framestream, - * and also, the read call can return that the stream has been - * closed by the other side. */ + * discard the input (ignore it). Ignore of unknown (control) + * packets is okay for the framestream protocol. And also, the + * read call can return that the stream has been closed by the + * other side. */ ssize_t r; uint8_t buf[1024]; - if(dtio->fd == -1) return; + if(dtio->fd == -1) return 0; while(1) { r = recv(dtio->fd, buf, sizeof(buf), 0); if(r == -1) { #ifndef USE_WINSOCK if(errno == EINTR || errno == EAGAIN) - return; /* try later */ + return 1; /* try later */ #else if(WSAGetLastError() == WSAEINPROGRESS) { - return; /* try later */ + return 1; /* try later */ } else if(WSAGetLastError() == WSAEWOULDBLOCK) { ub_winsock_tcp_wouldblock(dtio->event, UB_EV_READ); - return; /* try later */ + return 1; /* try later */ } #endif log_err("dnstap io: output recv: %s", strerror(errno)); @@ -582,6 +584,7 @@ static void dtio_check_close(struct dt_io_thread* dtio) /* close the channel */ dtio_del_output_event(dtio); dtio_close_output(dtio); + return 0; } /** callback for the dnstap events, to write to the output */ @@ -590,10 +593,10 @@ static void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg) struct dt_io_thread* dtio = (struct dt_io_thread*)arg; if((bits&UB_EV_READ)) { - dtio_check_close(dtio); - return; + if(!dtio_check_close(dtio)) + return; } - + /* see if there are messages that need writing */ if(!dtio->cur_msg) { if(!dtio_find_msg(dtio)) @@ -753,13 +756,14 @@ static void dtio_stop_ev_cb(int ATTR_UNUSED(fd), short bits, void* arg) if(info->want_to_exit_flush) return; if((bits&UB_EV_READ)) { - dtio_check_close(dtio); - if(dtio->fd == -1) { - verbose(VERB_ALGO, "dnstap io: " - "stop flush: output closed"); - dtio_stop_flush_exit(info); + if(!dtio_check_close(dtio)) { + if(dtio->fd == -1) { + verbose(VERB_ALGO, "dnstap io: " + "stop flush: output closed"); + dtio_stop_flush_exit(info); + } + return; } - return; } /* write remainder of last frame */ if(dtio->cur_msg) { From 29fdcf0c714b52f22ce3f84d5b3b7da90e06f36f Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 23 Jan 2020 11:44:32 +0100 Subject: [PATCH 23/96] loop in output callback for performance. --- dnstap/dtstream.c | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 963d4769f..164b56927 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -50,6 +50,9 @@ #include #endif +/** number of messages to process in one output callback */ +#define DTIO_MESSAGES_PER_CALLBACK 100 + void* fstrm_create_control_frame_start(char* contenttype, size_t* len) { uint32_t* control; @@ -591,30 +594,40 @@ static int dtio_check_close(struct dt_io_thread* dtio) static void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg) { struct dt_io_thread* dtio = (struct dt_io_thread*)arg; + int i; if((bits&UB_EV_READ)) { if(!dtio_check_close(dtio)) return; } - /* see if there are messages that need writing */ - if(!dtio->cur_msg) { - if(!dtio_find_msg(dtio)) - return; /* nothing to do */ - } + /* loop to process a number of messages. This improves throughput, + * because selecting on write-event if not needed for busy messages + * (dnstap log) generation and if they need to all be written back. + * The write event is usually not blocked up. But not forever, + * because the event loop needs to stay responsive for other events. + * If there are no (more) messages, or if the output buffers get + * full, it returns out of the loop. */ + for(i=0; icur_msg) { + if(!dtio_find_msg(dtio)) + return; /* nothing to do */ + } - /* write it */ - if(dtio->cur_msg_done < dtio->cur_msg_len) { - if(!dtio_write_more(dtio)) - return; - } + /* write it */ + if(dtio->cur_msg_done < dtio->cur_msg_len) { + if(!dtio_write_more(dtio)) + return; + } - /* done with the current message */ - free(dtio->cur_msg); - dtio->cur_msg = NULL; - dtio->cur_msg_len = 0; - dtio->cur_msg_done = 0; - dtio->cur_msg_len_done = 0; + /* done with the current message */ + free(dtio->cur_msg); + dtio->cur_msg = NULL; + dtio->cur_msg_len = 0; + dtio->cur_msg_done = 0; + dtio->cur_msg_len_done = 0; + } } /** callback for the dnstap commandpipe, to stop the dnstap IO */ From c0f410f72105ec4a70b2fa050cf6995b78a4430b Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 23 Jan 2020 11:51:10 +0100 Subject: [PATCH 24/96] dnstap io, make sure to free current message when stream closes. --- dnstap/dtstream.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 164b56927..c0fbb3999 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -306,6 +306,16 @@ static int dtio_find_msg(struct dt_io_thread* dtio) return 0; } +/** delete the current message in the dtio, and reset counters */ +static void dtio_cur_msg_free(struct dt_io_thread* dtio) +{ + free(dtio->cur_msg); + dtio->cur_msg = NULL; + dtio->cur_msg_len = 0; + dtio->cur_msg_done = 0; + dtio->cur_msg_len_done = 0; +} + /** del the output file descriptor event for listening */ static void dtio_del_output_event(struct dt_io_thread* dtio) { @@ -328,6 +338,13 @@ static void dtio_close_output(struct dt_io_thread* dtio) closesocket(dtio->fd); #endif dtio->fd = -1; + + /* if there is a (partial) message, discard it + * we cannot send (the remainder of) it, and a new + * connection needs to start with a control frame. */ + if(dtio->cur_msg) { + dtio_cur_msg_free(dtio); + } } /** check for pending nonblocking connect errors, @@ -622,11 +639,7 @@ static void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg) } /* done with the current message */ - free(dtio->cur_msg); - dtio->cur_msg = NULL; - dtio->cur_msg_len = 0; - dtio->cur_msg_done = 0; - dtio->cur_msg_len_done = 0; + dtio_cur_msg_free(dtio); } } @@ -792,11 +805,7 @@ static void dtio_stop_ev_cb(int ATTR_UNUSED(fd), short bits, void* arg) } verbose(VERB_ALGO, "dnstap io: stop flush completed " "last frame"); - free(dtio->cur_msg); - dtio->cur_msg = NULL; - dtio->cur_msg_len = 0; - dtio->cur_msg_done = 0; - dtio->cur_msg_len_done = 0; + dtio_cur_msg_free(dtio); } /* write stop frame */ if(info->stop_frame_done < info->stop_frame_len) { @@ -908,8 +917,7 @@ static void dtio_desetup(struct dt_io_thread* dtio) _close(dtio->commandpipe[0]); #endif dtio->commandpipe[0] = -1; - free(dtio->cur_msg); - dtio->cur_msg = NULL; + dtio_cur_msg_free(dtio); ub_event_base_free(dtio->event_base); } From 8c47d16e292177688cd92e294f233493f482b53a Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 23 Jan 2020 13:27:21 +0100 Subject: [PATCH 25/96] dnstap io, sleeps thread when there is no traffic. --- dnstap/dtstream.c | 143 +++++++++++++++++++++++++++++++++++++++------- dnstap/dtstream.h | 5 ++ 2 files changed, 126 insertions(+), 22 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index c0fbb3999..a81a7abd5 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -52,6 +52,13 @@ /** number of messages to process in one output callback */ #define DTIO_MESSAGES_PER_CALLBACK 100 +/** DTIO command channel commands */ +enum { + /** DTIO command channel stop */ + DTIO_COMMAND_STOP = 0, + /** DTIO command channel wakeup */ + DTIO_COMMAND_WAKEUP = 1 +} dtio_channel_command; void* fstrm_create_control_frame_start(char* contenttype, size_t* len) { @@ -137,9 +144,38 @@ dt_msg_queue_delete(struct dt_msg_queue* mq) free(mq); } +/** make the dtio wake up by sending a wakeup command */ +static void dtio_wakeup(struct dt_io_thread* dtio) +{ + uint8_t cmd = DTIO_COMMAND_WAKEUP; + if(!dtio) return; + if(!dtio->event_base) return; /* not started */ + + while(1) { + ssize_t r = write(dtio->commandpipe[1], &cmd, sizeof(cmd)); + if(r == -1) { +#ifndef USE_WINSOCK + if(errno == EINTR || errno == EAGAIN) + continue; + log_err("dnstap io wakeup: write: %s", strerror(errno)); +#else + if(WSAGetLastError() == WSAEINPROGRESS) + continue; + if(WSAGetLastError() == WSAEWOULDBLOCK) + continue; + log_err("dnstap io stop: write: %s", + wsa_strerror(WSAGetLastError())); +#endif + break; + } + break; + } +} + void dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len) { + int wakeup = 0; struct dt_msg_entry* entry; /* check conditions */ @@ -170,6 +206,9 @@ dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len) /* aqcuire lock */ lock_basic_lock(&mq->lock); + /* list was empty, wakeup dtio */ + if(mq->first == NULL) + wakeup = 1; /* see if it is going to fit */ if(mq->cursize + len > mq->maxsize) { /* buffer full, or congested. */ @@ -188,6 +227,9 @@ dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len) mq->last = entry; /* release lock */ lock_basic_unlock(&mq->lock); + + if(wakeup) + dtio_wakeup(mq->dtio); } struct dt_io_thread* dt_io_thread_create(void) @@ -221,6 +263,7 @@ int dt_io_thread_register_queue(struct dt_io_thread* dtio, { struct dt_io_list_item* item = malloc(sizeof(*item)); if(!item) return 0; + mq->dtio = dtio; item->queue = mq; item->next = dtio->io_list; dtio->io_list = item; @@ -238,6 +281,7 @@ void dt_io_thread_unregister_queue(struct dt_io_thread* dtio, if(prev) prev->next = item->next; else dtio->io_list = item->next; /* the queue itself only registered, not deleted */ + item->queue->dtio = NULL; free(item); dtio->io_list_iter = NULL; return; @@ -288,16 +332,25 @@ static int dtio_find_in_queue(struct dt_io_thread* dtio, /** find a new message to write, search message queues, false if none */ static int dtio_find_msg(struct dt_io_thread* dtio) { - struct dt_io_list_item* item; + struct dt_io_list_item *spot, *item; - if(dtio->io_list_iter) - item = dtio->io_list_iter; - else item = dtio->io_list; + spot = dtio->io_list_iter; /* use the next queue for the next message lookup, * if we hit the end(NULL) the NULL restarts the iter at start. */ - if(item) - dtio->io_list_iter = item->next; + if(spot) + dtio->io_list_iter = spot->next; + else if(dtio->io_list) + dtio->io_list_iter = dtio->io_list->next; + /* scan from spot to end-of-io_list */ + item = spot; + while(item) { + if(dtio_find_in_queue(dtio, item->queue)) + return 1; + item = item->next; + } + /* scan starting at the start-of-list (to wrap around the end) */ + item = dtio->io_list; while(item) { if(dtio_find_in_queue(dtio, item->queue)) return 1; @@ -323,6 +376,7 @@ static void dtio_del_output_event(struct dt_io_thread* dtio) return; ub_event_del(dtio->event); dtio->event_added = 0; + dtio->event_added_is_write = 0; } /** close and stop the output file descriptor event */ @@ -607,6 +661,52 @@ static int dtio_check_close(struct dt_io_thread* dtio) return 0; } +/** add the output file descriptor event for listening, read only */ +static void dtio_add_output_event_read(struct dt_io_thread* dtio) +{ + if(!dtio->event) + return; + if(dtio->event_added && !dtio->event_added_is_write) + return; + /* we have to (re-)register the event */ + if(dtio->event_added) + ub_event_del(dtio->event); + ub_event_del_bits(dtio->event, UB_EV_WRITE); + if(ub_event_add(dtio->event, NULL) != 0) { + log_err("dnstap io: out of memory (adding event)"); + return; + } + dtio->event_added = 1; + dtio->event_added_is_write = 0; +} + +/** add the output file descriptor event for listening, read and write */ +static void dtio_add_output_event_write(struct dt_io_thread* dtio) +{ + if(!dtio->event) + return; + if(dtio->event_added && dtio->event_added_is_write) + return; + /* we have to (re-)register the event */ + if(dtio->event_added) + ub_event_del(dtio->event); + ub_event_add_bits(dtio->event, UB_EV_WRITE); + if(ub_event_add(dtio->event, NULL) != 0) { + log_err("dnstap io: out of memory (adding event)"); + return; + } + dtio->event_added = 1; + dtio->event_added_is_write = 1; +} + +/** put the dtio thread to sleep */ +static void dtio_sleep(struct dt_io_thread* dtio) +{ + /* unregister the event polling for write, because there is + * nothing to be written */ + dtio_add_output_event_read(dtio); +} + /** callback for the dnstap events, to write to the output */ static void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg) { @@ -628,8 +728,14 @@ static void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg) for(i=0; icur_msg) { - if(!dtio_find_msg(dtio)) + if(!dtio_find_msg(dtio)) { + if(i == 0) { + /* no messages on the first iteration, + * the queues are all empty */ + dtio_sleep(dtio); + } return; /* nothing to do */ + } } /* write it */ @@ -668,8 +774,13 @@ static void dtio_cmd_cb(int fd, short ATTR_UNUSED(bits), void* arg) /* and then fall through to quit the thread */ } else if(r == 0) { verbose(VERB_ALGO, "dnstap io: cmd channel closed"); - } else if(r == 1 && cmd == 0) { + } else if(r == 1 && cmd == DTIO_COMMAND_STOP) { verbose(VERB_ALGO, "dnstap io: cmd channel cmd quit"); + } else if(r == 1 && cmd == DTIO_COMMAND_WAKEUP) { + verbose(VERB_ALGO, "dnstap io: cmd channel cmd wakeup"); + /* reregister event */ + dtio_add_output_event_write(dtio); + return; } else if(r == 1) { verbose(VERB_ALGO, "dnstap io: cmd channel unknown command"); } @@ -1016,18 +1127,6 @@ static void dtio_open_output(struct dt_io_thread* dtio) } } -/** add the output file descriptor event for listening */ -static void dtio_add_output_event(struct dt_io_thread* dtio) -{ - if(!dtio->event) - return; - if(ub_event_add(dtio->event, NULL) != 0) { - log_err("dnstap io: out of memory (adding event)"); - return; - } - dtio->event_added = 1; -} - /** the IO thread function for the DNSTAP IO */ static void* dnstap_io(void* arg) { @@ -1039,7 +1138,7 @@ static void* dnstap_io(void* arg) dtio_setup_base(dtio, &secs, &now); dtio_setup_cmd(dtio); dtio_open_output(dtio); - dtio_add_output_event(dtio); + dtio_add_output_event_write(dtio); verbose(VERB_ALGO, "start dnstap io thread"); /* run */ @@ -1077,7 +1176,7 @@ int dt_io_thread_start(struct dt_io_thread* dtio) void dt_io_thread_stop(struct dt_io_thread* dtio) { - uint8_t cmd = 0; + uint8_t cmd = DTIO_COMMAND_STOP; if(!dtio) return; if(!dtio->event_base) return; /* not started */ diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 3c5bd9a4e..77bda6ae0 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -47,6 +47,7 @@ #include "util/locks.h" struct dt_msg_entry; struct dt_io_list_item; +struct dt_io_thread; struct config_file; /** @@ -70,6 +71,8 @@ struct dt_msg_queue { /** list of messages. The messages are added to the back and taken * out from the front. */ struct dt_msg_entry* first, *last; + /** reference to the io thread to wakeup */ + struct dt_io_thread* dtio; }; /** @@ -105,6 +108,8 @@ struct dt_io_thread { void* event; /** the event is added */ int event_added; + /** event added is a write event */ + int event_added_is_write; /** check for nonblocking connect errors on fd */ int check_nb_connect; /** the buffer that currently getting written, or NULL if no From 86e1948afed289b555834c9094fafaaf15df3a40 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 23 Jan 2020 13:38:10 +0100 Subject: [PATCH 26/96] dnstap io, fixup error exit of event add routines. --- dnstap/dtstream.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index a81a7abd5..bbf202c57 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -674,6 +674,8 @@ static void dtio_add_output_event_read(struct dt_io_thread* dtio) ub_event_del_bits(dtio->event, UB_EV_WRITE); if(ub_event_add(dtio->event, NULL) != 0) { log_err("dnstap io: out of memory (adding event)"); + dtio->event_added = 0; + dtio->event_added_is_write = 0; return; } dtio->event_added = 1; @@ -693,6 +695,8 @@ static void dtio_add_output_event_write(struct dt_io_thread* dtio) ub_event_add_bits(dtio->event, UB_EV_WRITE); if(ub_event_add(dtio->event, NULL) != 0) { log_err("dnstap io: out of memory (adding event)"); + dtio->event_added = 0; + dtio->event_added_is_write = 0; return; } dtio->event_added = 1; From 299086d44737749f37bca5ee88c5aebc2c935eb1 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 23 Jan 2020 15:11:08 +0100 Subject: [PATCH 27/96] dnstap io, reconnect attempts with exponential backoff to once per second. --- dnstap/dtstream.c | 104 ++++++++++++++++++++++++++++++++++++++++++++-- dnstap/dtstream.h | 10 +++++ 2 files changed, 111 insertions(+), 3 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index bbf202c57..f3d50a027 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -52,6 +52,11 @@ /** number of messages to process in one output callback */ #define DTIO_MESSAGES_PER_CALLBACK 100 +/** the msec to wait for reconnect (if not immediate, the first attempt) */ +#define DTIO_RECONNECT_TIMEOUT_MIN 10 +/** the msec to wait for reconnect max after backoff */ +#define DTIO_RECONNECT_TIMEOUT_MAX 1000 + /** DTIO command channel commands */ enum { /** DTIO command channel stop */ @@ -60,6 +65,13 @@ enum { DTIO_COMMAND_WAKEUP = 1 } dtio_channel_command; +/** open the output channel */ +static void dtio_open_output(struct dt_io_thread* dtio); +/** add output event for read and write */ +static void dtio_add_output_event_write(struct dt_io_thread* dtio); +/** start reconnection attempts */ +static void dtio_reconnect_enable(struct dt_io_thread* dtio); + void* fstrm_create_control_frame_start(char* contenttype, size_t* len) { uint32_t* control; @@ -359,6 +371,73 @@ static int dtio_find_msg(struct dt_io_thread* dtio) return 0; } +/** callback for the dnstap reconnect, to start reconnecting to output */ +static void dtio_reconnect_timeout_cb(int ATTR_UNUSED(fd), + short ATTR_UNUSED(bits), void* arg) +{ + struct dt_io_thread* dtio = (struct dt_io_thread*)arg; + dtio->reconnect_is_added = 0; + verbose(VERB_ALGO, "dnstap io: reconnect timer"); + + dtio_open_output(dtio); + if(dtio->event) { + dtio_add_output_event_write(dtio); + /* nothing wrong so far, wait on the output event */ + return; + } + /* exponential backoff and retry on timer */ + dtio_reconnect_enable(dtio); +} + +/** attempt to reconnect to the output, after a timeout */ +static void dtio_reconnect_enable(struct dt_io_thread* dtio) +{ + struct timeval tv; + int msec; + if(dtio->reconnect_is_added) + return; /* already done */ + + /* exponential backoff, store the value for next timeout */ + msec = dtio->reconnect_timeout; + if(msec == 0) { + dtio->reconnect_timeout = DTIO_RECONNECT_TIMEOUT_MIN; + } else { + dtio->reconnect_timeout = msec*2; + if(dtio->reconnect_timeout > DTIO_RECONNECT_TIMEOUT_MAX) + dtio->reconnect_timeout = DTIO_RECONNECT_TIMEOUT_MAX; + } + verbose(VERB_ALGO, "dnstap io: set reconnect attempt after %d msec", + msec); + + /* setup wait timer */ + memset(&tv, 0, sizeof(tv)); + tv.tv_sec = msec/1000; + tv.tv_usec = (msec%1000)*1000; + if(ub_timer_add(dtio->reconnect_timer, dtio->event_base, + &dtio_reconnect_timeout_cb, dtio, &tv) != 0) { + log_err("dnstap io: could not reconnect ev timer add"); + return; + } + dtio->reconnect_is_added = 1; +} + +/** remove dtio reconnect timer */ +static void dtio_reconnect_del(struct dt_io_thread* dtio) +{ + if(!dtio->reconnect_is_added) + return; + ub_timer_del(dtio->reconnect_timer); + dtio->reconnect_is_added = 0; +} + +/** clear the reconnect exponential backoff timer. + * We have successfully connected so we can try again with short timeouts. */ +static void dtio_reconnect_clear(struct dt_io_thread* dtio) +{ + dtio->reconnect_timeout = 0; + dtio_reconnect_del(dtio); +} + /** delete the current message in the dtio, and reset counters */ static void dtio_cur_msg_free(struct dt_io_thread* dtio) { @@ -399,6 +478,7 @@ static void dtio_close_output(struct dt_io_thread* dtio) if(dtio->cur_msg) { dtio_cur_msg_free(dtio); } + dtio_reconnect_enable(dtio); } /** check for pending nonblocking connect errors, @@ -443,6 +523,7 @@ static int dtio_check_nb_connect(struct dt_io_thread* dtio) } verbose(VERB_ALGO, "dnstap io: connected to \"%s\"", dtio->socket_path); + dtio_reconnect_clear(dtio); dtio->check_nb_connect = 0; return 1; /* everything okay */ } @@ -822,6 +903,17 @@ static void dtio_setup_cmd(struct dt_io_thread* dtio) } } +/** setup the reconnect event for dnstap io */ +static void dtio_setup_reconnect(struct dt_io_thread* dtio) +{ + dtio_reconnect_clear(dtio); + dtio->reconnect_timer = ub_event_new(dtio->event_base, -1, + UB_EV_TIMEOUT, &dtio_reconnect_timeout_cb, dtio); + if(!dtio->reconnect_timer) { + fatal_exit("dnstap io: out of memory"); + } +} + /** * structure to keep track of information during stop flush */ @@ -1032,6 +1124,8 @@ static void dtio_desetup(struct dt_io_thread* dtio) _close(dtio->commandpipe[0]); #endif dtio->commandpipe[0] = -1; + dtio_reconnect_del(dtio); + ub_event_free(dtio->reconnect_timer); dtio_cur_msg_free(dtio); ub_event_base_free(dtio->event_base); } @@ -1096,6 +1190,7 @@ static void dtio_open_output(struct dt_io_thread* dtio) closesocket(dtio->fd); #endif dtio->fd = -1; + dtio_reconnect_enable(dtio); return; } dtio->check_nb_connect = 1; @@ -1105,19 +1200,21 @@ static void dtio_open_output(struct dt_io_thread* dtio) UB_EV_READ | UB_EV_WRITE | UB_EV_PERSIST, &dtio_output_cb, dtio); if(!ev) { + log_err("dnstap io: out of memory"); #ifndef USE_WINSOCK close(dtio->fd); #else closesocket(dtio->fd); #endif dtio->fd = -1; - log_err("dnstap io: out of memory"); + dtio_reconnect_enable(dtio); return; } dtio->event = ev; /* setup protocol control message to start */ if(!dtio_control_start_send(dtio)) { + log_err("dnstap io: out of memory"); ub_event_free(dtio->event); dtio->event = NULL; #ifndef USE_WINSOCK @@ -1126,7 +1223,7 @@ static void dtio_open_output(struct dt_io_thread* dtio) closesocket(dtio->fd); #endif dtio->fd = -1; - log_err("dnstap io: out of memory"); + dtio_reconnect_enable(dtio); return; } } @@ -1139,11 +1236,12 @@ static void* dnstap_io(void* arg) struct timeval now; /* setup */ + verbose(VERB_ALGO, "start dnstap io thread"); dtio_setup_base(dtio, &secs, &now); dtio_setup_cmd(dtio); + dtio_setup_reconnect(dtio); dtio_open_output(dtio); dtio_add_output_event_write(dtio); - verbose(VERB_ALGO, "start dnstap io thread"); /* run */ if(ub_event_base_dispatch(dtio->event_base) < 0) { diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 77bda6ae0..2f1546527 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -102,6 +102,7 @@ struct dt_io_thread { struct dt_io_list_item* io_list_iter; /** thread id, of the io thread */ ub_thread_type tid; + /** file descriptor that the thread writes to */ int fd; /** event structure that the thread uses */ @@ -112,6 +113,7 @@ struct dt_io_thread { int event_added_is_write; /** check for nonblocking connect errors on fd */ int check_nb_connect; + /** the buffer that currently getting written, or NULL if no * (partial) message written now */ void* cur_msg; @@ -131,6 +133,14 @@ struct dt_io_thread { /** the io thread wants to exit */ int want_to_exit; + /** the timer event for connection retries */ + void* reconnect_timer; + /** if the reconnect timer is added to the event base */ + int reconnect_is_added; + /** the current reconnection timeout, it is increased with + * exponential backoff, in msec */ + int reconnect_timeout; + /** If the log server is connected to over unix domain sockets, * eg. a file is named that is created to log onto. */ int upstream_is_unix; From b33df3cc637643f71cbc9b08ead08277069021ee Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 23 Jan 2020 15:17:43 +0100 Subject: [PATCH 28/96] in stop flush use timer_del to remove timer. --- dnstap/dtstream.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index f3d50a027..60cb04567 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -1070,7 +1070,7 @@ static void dtio_control_stop_flush(struct dt_io_thread* dtio) UB_EV_WRITE | UB_EV_PERSIST, &dtio_stop_ev_cb, &info); if(!stopev) { log_err("dnstap io: malloc failure"); - ub_event_del(timer); + ub_timer_del(timer); ub_event_free(timer); ub_event_base_free(info.base); return; @@ -1078,7 +1078,7 @@ static void dtio_control_stop_flush(struct dt_io_thread* dtio) if(ub_event_add(stopev, NULL) != 0) { log_err("dnstap io: cannot event_add"); ub_event_free(stopev); - ub_event_del(timer); + ub_timer_del(timer); ub_event_free(timer); ub_event_base_free(info.base); return; @@ -1089,7 +1089,7 @@ static void dtio_control_stop_flush(struct dt_io_thread* dtio) log_err("dnstap io: malloc failure"); ub_event_del(stopev); ub_event_free(stopev); - ub_event_del(timer); + ub_timer_del(timer); ub_event_free(timer); ub_event_base_free(info.base); return; @@ -1105,7 +1105,7 @@ static void dtio_control_stop_flush(struct dt_io_thread* dtio) free(info.stop_frame); ub_event_del(stopev); ub_event_free(stopev); - ub_event_del(timer); + ub_timer_del(timer); ub_event_free(timer); ub_event_base_free(info.base); } From 1042134eec0a1ddaca364c7794b467223934f197 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 23 Jan 2020 15:39:27 +0100 Subject: [PATCH 29/96] dnstap io, failure to add event closes and attempts to reopen the output. --- dnstap/dtstream.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 60cb04567..aa590ee8f 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -757,6 +757,8 @@ static void dtio_add_output_event_read(struct dt_io_thread* dtio) log_err("dnstap io: out of memory (adding event)"); dtio->event_added = 0; dtio->event_added_is_write = 0; + /* close output and start reattempts to open it */ + dtio_close_output(dtio); return; } dtio->event_added = 1; @@ -778,6 +780,8 @@ static void dtio_add_output_event_write(struct dt_io_thread* dtio) log_err("dnstap io: out of memory (adding event)"); dtio->event_added = 0; dtio->event_added_is_write = 0; + /* close output and start reattempts to open it */ + dtio_close_output(dtio); return; } dtio->event_added = 1; From 4c64c4b78e15d19ec5a2b169e12ab9ec0f8e8165 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 23 Jan 2020 15:49:36 +0100 Subject: [PATCH 30/96] dnstap io, remove libfstrm calls from dnstap.c. --- dnstap/dnstap.c | 45 ++------------------------------------------- dnstap/dnstap.h | 6 ------ 2 files changed, 2 insertions(+), 49 deletions(-) diff --git a/dnstap/dnstap.c b/dnstap/dnstap.c index d8bc155aa..0cf3ff7b5 100644 --- a/dnstap/dnstap.c +++ b/dnstap/dnstap.c @@ -129,16 +129,10 @@ check_socket_file(const char* socket_path) } struct dt_env * -dt_create(const char *socket_path, unsigned num_workers, struct config_file* cfg) +dt_create(const char *socket_path, unsigned num_workers, + struct config_file* cfg) { -#ifdef UNBOUND_DEBUG - fstrm_res res; -#endif struct dt_env *env; - struct fstrm_iothr_options *fopt; - struct fstrm_unix_writer_options *fuwopt; - struct fstrm_writer *fw; - struct fstrm_writer_options *fwopt; verbose(VERB_OPS, "attempting to connect to dnstap socket %s", socket_path); @@ -150,40 +144,9 @@ dt_create(const char *socket_path, unsigned num_workers, struct config_file* cfg if (!env) return NULL; - fwopt = fstrm_writer_options_init(); -#ifdef UNBOUND_DEBUG - res = -#else - (void) -#endif - fstrm_writer_options_add_content_type(fwopt, - DNSTAP_CONTENT_TYPE, sizeof(DNSTAP_CONTENT_TYPE) - 1); - log_assert(res == fstrm_res_success); - - fuwopt = fstrm_unix_writer_options_init(); - fstrm_unix_writer_options_set_socket_path(fuwopt, socket_path); - - fw = fstrm_unix_writer_init(fuwopt, fwopt); - log_assert(fw != NULL); - - fopt = fstrm_iothr_options_init(); - fstrm_iothr_options_set_num_input_queues(fopt, num_workers); - env->iothr = fstrm_iothr_init(fopt, &fw); - if (env->iothr == NULL) { - verbose(VERB_DETAIL, "dt_create: fstrm_iothr_init() failed"); - fstrm_writer_destroy(&fw); - free(env); - env = NULL; - } - fstrm_iothr_options_destroy(&fopt); - fstrm_unix_writer_options_destroy(&fuwopt); - fstrm_writer_options_destroy(&fwopt); - env->dtio = dt_io_thread_create(); if(!env->dtio) { log_err("malloc failure"); - fstrm_writer_destroy(&fw); - fstrm_iothr_destroy(&env->iothr); free(env); return NULL; } @@ -276,9 +239,6 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg) int dt_init(struct dt_env *env) { - env->ioq = fstrm_iothr_get_input_queue(env->iothr); - if (env->ioq == NULL) - return 0; env->msgqueue = dt_msg_queue_create(); if(!env->msgqueue) { log_err("malloc failure"); @@ -304,7 +264,6 @@ dt_delete(struct dt_env *env) if (!env) return; verbose(VERB_OPS, "closing dnstap socket"); - fstrm_iothr_destroy(&env->iothr); dt_io_thread_delete(env->dtio); free(env->identity); free(env->version); diff --git a/dnstap/dnstap.h b/dnstap/dnstap.h index 428691ed9..c87a549aa 100644 --- a/dnstap/dnstap.h +++ b/dnstap/dnstap.h @@ -40,19 +40,13 @@ #ifdef USE_DNSTAP struct config_file; -struct fstrm_io; -struct fstrm_queue; struct sldns_buffer; struct dt_msg_queue; struct dt_env { - /** dnstap I/O thread */ - struct fstrm_iothr *iothr; /** the io thread (made by the struct daemon) */ struct dt_io_thread* dtio; - /** dnstap I/O thread input queue */ - struct fstrm_iothr_queue *ioq; /** valid in worker struct, not in daemon struct, the per-worker * message list */ struct dt_msg_queue* msgqueue; From 874c349b44618f9e3839be935eec2e36d7bcb428 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 23 Jan 2020 15:56:12 +0100 Subject: [PATCH 31/96] dnstap io, remove --with-libfstrm, it is not required to build dnstap support. protobuf-c is still used for handling the dnstap encoding. --- Makefile.in | 2 +- configure | 71 +----------------------------------------------- dnstap/dnstap.c | 1 - dnstap/dnstap.m4 | 9 +----- 4 files changed, 3 insertions(+), 80 deletions(-) diff --git a/Makefile.in b/Makefile.in index 65dc20663..f2444dc65 100644 --- a/Makefile.in +++ b/Makefile.in @@ -77,7 +77,7 @@ LINT=splint LINTFLAGS=+quiet -weak -warnposix -unrecog -Din_addr_t=uint32_t -Du_int=unsigned -Du_char=uint8_t -preproc -Drlimit=rlimit64 -D__gnuc_va_list=va_list -formatcode #-Dglob64=glob -Dglobfree64=globfree # compat with openssl linux edition. -LINTFLAGS+="-DBN_ULONG=unsigned long" -Dkrb5_int32=int "-Dkrb5_ui_4=unsigned int" -DPQ_64BIT=uint64_t -DRC4_INT=unsigned -fixedformalarray -D"ENGINE=unsigned" -D"RSA=unsigned" -D"DSA=unsigned" -D"EVP_PKEY=unsigned" -D"EVP_MD=unsigned" -D"SSL=unsigned" -D"SSL_CTX=unsigned" -D"X509=unsigned" -D"RC4_KEY=unsigned" -D"EVP_MD_CTX=unsigned" -D"ECDSA_SIG=DSA_SIG" -Dfstrm_res=int +LINTFLAGS+="-DBN_ULONG=unsigned long" -Dkrb5_int32=int "-Dkrb5_ui_4=unsigned int" -DPQ_64BIT=uint64_t -DRC4_INT=unsigned -fixedformalarray -D"ENGINE=unsigned" -D"RSA=unsigned" -D"DSA=unsigned" -D"EVP_PKEY=unsigned" -D"EVP_MD=unsigned" -D"SSL=unsigned" -D"SSL_CTX=unsigned" -D"X509=unsigned" -D"RC4_KEY=unsigned" -D"EVP_MD_CTX=unsigned" -D"ECDSA_SIG=DSA_SIG" # compat with NetBSD LINTFLAGS+=@NETBSD_LINTFLAGS@ # compat with OpenBSD diff --git a/configure b/configure index 12d042492..0f49db296 100755 --- a/configure +++ b/configure @@ -880,7 +880,6 @@ enable_allsymbols enable_dnstap with_dnstap_socket_path with_protobuf_c -with_libfstrm enable_dnscrypt with_libsodium enable_cachedb @@ -1569,7 +1568,7 @@ Optional Features: --enable-allsymbols export all symbols from libunbound and link binaries to it, smaller install size but libunbound export table is polluted by internal symbols - --enable-dnstap Enable dnstap support (requires fstrm, protobuf-c) + --enable-dnstap Enable dnstap support (requires protobuf-c) --enable-dnscrypt Enable dnscrypt support (requires libsodium) --enable-cachedb enable cachedb module that can use external cache storage @@ -1630,7 +1629,6 @@ Optional Packages: --with-dnstap-socket-path=pathname set default dnstap socket path --with-protobuf-c=path Path where protobuf-c is installed, for dnstap - --with-libfstrm=path Path where libfstrm is installed, for dnstap --with-libsodium=path Path where libsodium is installed, for dnscrypt --with-libmnl=path specify explicit path for libmnl. --with-libunbound-only do not build daemon and tool programs @@ -20795,73 +20793,6 @@ else fi - -# Check whether --with-libfstrm was given. -if test "${with_libfstrm+set}" = set; then : - withval=$with_libfstrm; - CFLAGS="$CFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib" - -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fstrm_iothr_init" >&5 -$as_echo_n "checking for library containing fstrm_iothr_init... " >&6; } -if ${ac_cv_search_fstrm_iothr_init+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char fstrm_iothr_init (); -int -main () -{ -return fstrm_iothr_init (); - ; - return 0; -} -_ACEOF -for ac_lib in '' fstrm; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_fstrm_iothr_init=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_fstrm_iothr_init+:} false; then : - break -fi -done -if ${ac_cv_search_fstrm_iothr_init+:} false; then : - -else - ac_cv_search_fstrm_iothr_init=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fstrm_iothr_init" >&5 -$as_echo "$ac_cv_search_fstrm_iothr_init" >&6; } -ac_res=$ac_cv_search_fstrm_iothr_init -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -else - as_fn_error $? "The fstrm library was not found. Please install fstrm!" "$LINENO" 5 -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing protobuf_c_message_pack" >&5 $as_echo_n "checking for library containing protobuf_c_message_pack... " >&6; } if ${ac_cv_search_protobuf_c_message_pack+:} false; then : diff --git a/dnstap/dnstap.c b/dnstap/dnstap.c index 0cf3ff7b5..c06644eae 100644 --- a/dnstap/dnstap.c +++ b/dnstap/dnstap.c @@ -49,7 +49,6 @@ #include "util/netevent.h" #include "util/log.h" -#include #include #include "dnstap/dnstap.h" diff --git a/dnstap/dnstap.m4 b/dnstap/dnstap.m4 index 5b78b3e26..ba723e0be 100644 --- a/dnstap/dnstap.m4 +++ b/dnstap/dnstap.m4 @@ -7,7 +7,7 @@ AC_DEFUN([dt_DNSTAP], [ AC_ARG_ENABLE([dnstap], AS_HELP_STRING([--enable-dnstap], - [Enable dnstap support (requires fstrm, protobuf-c)]), + [Enable dnstap support (requires protobuf-c)]), [opt_dnstap=$enableval], [opt_dnstap=no]) AC_ARG_WITH([dnstap-socket-path], @@ -40,13 +40,6 @@ AC_DEFUN([dt_DNSTAP], fi fi ]) - AC_ARG_WITH([libfstrm], AC_HELP_STRING([--with-libfstrm=path], - [Path where libfstrm is installed, for dnstap]), [ - CFLAGS="$CFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib" - ]) - AC_SEARCH_LIBS([fstrm_iothr_init], [fstrm], [], - AC_MSG_ERROR([The fstrm library was not found. Please install fstrm!])) AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c], [], AC_MSG_ERROR([The protobuf-c library was not found. Please install protobuf-c!])) $2 From 8f2f004778301c75cc4231f104d3096dc35ac941 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 23 Jan 2020 16:49:44 +0100 Subject: [PATCH 32/96] dnstap io, fix event reference in winevent wouldblock call. --- dnstap/dtstream.c | 10 ++++++---- dnstap/dtstream.h | 3 +++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index aa590ee8f..8a4eefbf2 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -506,7 +506,7 @@ static int dtio_check_nb_connect(struct dt_io_thread* dtio) if(error == WSAEINPROGRESS) { return 0; /* try again later */ } else if(error == WSAEWOULDBLOCK) { - ub_winsock_tcp_wouldblock(dtio->event, UB_EV_WRITE); + ub_winsock_tcp_wouldblock((dtio->stop_flush_event?dtio->stop_flush_event:dtio->event), UB_EV_WRITE); return 0; /* try again later */ } #endif @@ -555,7 +555,7 @@ static int dtio_write_buf(struct dt_io_thread* dtio, uint8_t* buf, if(WSAGetLastError() == WSAEINPROGRESS) return 0; if(WSAGetLastError() == WSAEWOULDBLOCK) { - ub_winsock_tcp_wouldblock(dtio->event, UB_EV_WRITE); + ub_winsock_tcp_wouldblock((dtio->stop_flush_event?dtio->stop_flush_event:dtio->event), UB_EV_WRITE); return 0; } log_err("dnstap io: failed send: %s", @@ -600,7 +600,7 @@ static int dtio_write_with_writev(struct dt_io_thread* dtio) if(WSAGetLastError() == WSAEINPROGRESS) return 0; if(WSAGetLastError() == WSAEWOULDBLOCK) { - ub_winsock_tcp_wouldblock(dtio->event, UB_EV_WRITE); + ub_winsock_tcp_wouldblock((dtio->stop_flush_event?dtio->stop_flush_event:dtio->event), UB_EV_WRITE); return 0; } log_err("dnstap io: failed writev: %s", @@ -720,7 +720,7 @@ static int dtio_check_close(struct dt_io_thread* dtio) if(WSAGetLastError() == WSAEINPROGRESS) { return 1; /* try later */ } else if(WSAGetLastError() == WSAEWOULDBLOCK) { - ub_winsock_tcp_wouldblock(dtio->event, UB_EV_READ); + ub_winsock_tcp_wouldblock((dtio->stop_flush_event?dtio->stop_flush_event:dtio->event), UB_EV_READ); return 1; /* try later */ } #endif @@ -1098,6 +1098,7 @@ static void dtio_control_stop_flush(struct dt_io_thread* dtio) ub_event_base_free(info.base); return; } + dtio->stop_flush_event = stopev; /* wait briefly, or until finished */ verbose(VERB_ALGO, "dnstap io: stop flush started"); @@ -1107,6 +1108,7 @@ static void dtio_control_stop_flush(struct dt_io_thread* dtio) } verbose(VERB_ALGO, "dnstap io: stop flush ended"); free(info.stop_frame); + dtio->stop_flush_event = NULL; ub_event_del(stopev); ub_event_free(stopev); ub_timer_del(timer); diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 2f1546527..3386a1897 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -133,6 +133,9 @@ struct dt_io_thread { /** the io thread wants to exit */ int want_to_exit; + /** in stop flush, this is nonNULL and references the stop_ev */ + void* stop_flush_event; + /** the timer event for connection retries */ void* reconnect_timer; /** if the reconnect timer is added to the event base */ From cf5aa85f2932d2a4c6a197fa564b32fb1f079bbb Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 23 Jan 2020 16:51:57 +0100 Subject: [PATCH 33/96] dnstap io, nicer layout for wouldblock calls. --- dnstap/dtstream.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 8a4eefbf2..a62de0a63 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -506,7 +506,8 @@ static int dtio_check_nb_connect(struct dt_io_thread* dtio) if(error == WSAEINPROGRESS) { return 0; /* try again later */ } else if(error == WSAEWOULDBLOCK) { - ub_winsock_tcp_wouldblock((dtio->stop_flush_event?dtio->stop_flush_event:dtio->event), UB_EV_WRITE); + ub_winsock_tcp_wouldblock((dtio->stop_flush_event? + dtio->stop_flush_event:dtio->event), UB_EV_WRITE); return 0; /* try again later */ } #endif @@ -555,7 +556,9 @@ static int dtio_write_buf(struct dt_io_thread* dtio, uint8_t* buf, if(WSAGetLastError() == WSAEINPROGRESS) return 0; if(WSAGetLastError() == WSAEWOULDBLOCK) { - ub_winsock_tcp_wouldblock((dtio->stop_flush_event?dtio->stop_flush_event:dtio->event), UB_EV_WRITE); + ub_winsock_tcp_wouldblock((dtio->stop_flush_event? + dtio->stop_flush_event:dtio->event), + UB_EV_WRITE); return 0; } log_err("dnstap io: failed send: %s", @@ -600,7 +603,9 @@ static int dtio_write_with_writev(struct dt_io_thread* dtio) if(WSAGetLastError() == WSAEINPROGRESS) return 0; if(WSAGetLastError() == WSAEWOULDBLOCK) { - ub_winsock_tcp_wouldblock((dtio->stop_flush_event?dtio->stop_flush_event:dtio->event), UB_EV_WRITE); + ub_winsock_tcp_wouldblock((dtio->stop_flush_event? + dtio->stop_flush_event:dtio->event), + UB_EV_WRITE); return 0; } log_err("dnstap io: failed writev: %s", @@ -720,7 +725,10 @@ static int dtio_check_close(struct dt_io_thread* dtio) if(WSAGetLastError() == WSAEINPROGRESS) { return 1; /* try later */ } else if(WSAGetLastError() == WSAEWOULDBLOCK) { - ub_winsock_tcp_wouldblock((dtio->stop_flush_event?dtio->stop_flush_event:dtio->event), UB_EV_READ); + ub_winsock_tcp_wouldblock( + (dtio->stop_flush_event? + dtio->stop_flush_event:dtio->event), + UB_EV_READ); return 1; /* try later */ } #endif From c3712a288fe7c02f8897d66deb0302053e6f03be Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 28 Jan 2020 12:21:05 +0100 Subject: [PATCH 34/96] merge master into framestreams, autoconf again. --- configure | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/configure b/configure index 221924a6c..d9ca1bcc0 100755 --- a/configure +++ b/configure @@ -803,7 +803,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -950,7 +949,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1203,15 +1201,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1349,7 +1338,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1502,7 +1491,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -15658,7 +15646,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -15704,7 +15692,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -15728,7 +15716,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -15773,7 +15761,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -15797,7 +15785,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; From b3bf4168886c964cfd9526a93e2b6648720843ae Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 28 Jan 2020 12:46:08 +0100 Subject: [PATCH 35/96] dnstap io, fix for msg queue cleanup and make test. --- dnstap/dtstream.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index a62de0a63..d03828123 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -286,7 +286,9 @@ int dt_io_thread_register_queue(struct dt_io_thread* dtio, void dt_io_thread_unregister_queue(struct dt_io_thread* dtio, struct dt_msg_queue* mq) { - struct dt_io_list_item* item=dtio->io_list, *prev=NULL; + struct dt_io_list_item* item, *prev=NULL; + if(!dtio) return; + item = dtio->io_list; while(item) { if(item->queue == mq) { /* found it */ From bb81684206d730cfc46922e7257c120d81d6dbc5 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 28 Jan 2020 12:48:36 +0100 Subject: [PATCH 36/96] dnstap io, fix memory leak if dnstap queue full. --- dnstap/dtstream.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index d03828123..25148f227 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -227,6 +227,7 @@ dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len) /* drop */ lock_basic_unlock(&mq->lock); free(buf); + free(entry); return; } mq->cursize += len; From e13675d6cbb1c2b72f9a0b1b938f9df373636179 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 28 Jan 2020 14:24:14 +0100 Subject: [PATCH 37/96] dnstap io, windows portability improvements. --- dnstap/dtstream.c | 7 ++++-- dnstap/unbound-dnstap-socket.c | 45 ++++++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 25148f227..47f4473be 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -49,6 +49,7 @@ #ifdef HAVE_SYS_UN_H #include #endif +#include /** number of messages to process in one output callback */ #define DTIO_MESSAGES_PER_CALLBACK 100 @@ -549,7 +550,7 @@ static int dtio_write_buf(struct dt_io_thread* dtio, uint8_t* buf, return 0; } } - ret = send(dtio->fd, buf, len, 0); + ret = send(dtio->fd, (void*)buf, len, 0); if(ret == -1) { #ifndef USE_WINSOCK if(errno == EINTR || errno == EAGAIN) @@ -719,7 +720,7 @@ static int dtio_check_close(struct dt_io_thread* dtio) uint8_t buf[1024]; if(dtio->fd == -1) return 0; while(1) { - r = recv(dtio->fd, buf, sizeof(buf), 0); + r = recv(dtio->fd, (void*)buf, sizeof(buf), 0); if(r == -1) { #ifndef USE_WINSOCK if(errno == EINTR || errno == EAGAIN) @@ -1169,6 +1170,7 @@ static int dtio_control_start_send(struct dt_io_thread* dtio) /** open the output file descriptor */ static void dtio_open_output(struct dt_io_thread* dtio) { +#ifdef HAVE_SYS_UN_H struct ub_event* ev; struct sockaddr_un s; dtio->fd = socket(AF_LOCAL, SOCK_STREAM, 0); @@ -1243,6 +1245,7 @@ static void dtio_open_output(struct dt_io_thread* dtio) dtio_reconnect_enable(dtio); return; } +#endif /* HAVE_SYS_UN_H */ } /** the IO thread function for the DNSTAP IO */ diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index 96e798282..5a7a0cfa0 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -80,6 +80,14 @@ static void usage(char* argv[]) /** long format option, for multiline printout per message */ static int longformat = 0; +/** main tap callback data */ +struct main_tap_data { + /** the event base (to loopexit) */ + struct ub_event_base* base; + /** the event (that is accept()ed) */ + struct ub_event* ev; +}; + /** tap callback variables */ struct tap_data { /** the fd */ @@ -252,12 +260,14 @@ static char* tv_to_str(protobuf_c_boolean has_time_sec, uint64_t time_sec, { char buf[64], buf2[256]; struct timeval tv; + time_t time_t_sec; memset(&tv, 0, sizeof(tv)); if(has_time_sec) tv.tv_sec = time_sec; if(has_time_nsec) tv.tv_usec = time_nsec; buf[0]=0; - (void)ctime_r(&tv.tv_sec, buf); + time_t_sec = tv.tv_sec; + (void)ctime_r(&time_t_sec, buf); snprintf(buf2, sizeof(buf2), "%u.%9.9u %s", (unsigned)time_sec, (unsigned)time_nsec, buf); return strdup(buf2); @@ -364,7 +374,7 @@ static void log_data_frame(uint8_t* pkt, size_t len) /** receive bytes from fd, prints errors if bad, * returns 0: closed/error, -1: continue, >0 number of bytes */ -static ssize_t receive_bytes(int fd, void* buf, size_t len) +static ssize_t receive_bytes(int fd, void* buf, size_t len, struct ub_event* ev) { ssize_t ret = recv(fd, buf, len, 0); if(ret == 0) { @@ -374,6 +384,7 @@ static ssize_t receive_bytes(int fd, void* buf, size_t len) } else if(ret == -1) { /* error */ #ifndef USE_WINSOCK + (void)ev; if(errno == EINTR || errno == EAGAIN) return -1; log_err("could not recv: %s", strerror(errno)); @@ -381,8 +392,7 @@ static ssize_t receive_bytes(int fd, void* buf, size_t len) if(WSAGetLastError() == WSAEINPROGRESS) return -1; if(WSAGetLastError() == WSAEWOULDBLOCK) { - ub_winsock_tcp_wouldblock(data->ev, - UB_EV_READ); + ub_winsock_tcp_wouldblock(ev, UB_EV_READ); return -1; } log_err("could not recv: %s", @@ -433,7 +443,7 @@ static int reply_with_accept(int fd) strlen(DNSTAP_CONTENT_TYPE)); fd_set_block(fd); - if(send(fd, acceptframe, len, 0) == -1) { + if(send(fd, (void*)acceptframe, len, 0) == -1) { #ifndef USE_WINSOCK log_err("send failed: %s", strerror(errno)); #else @@ -468,7 +478,7 @@ static int reply_with_finish(int fd) finishframe[2] = htonl(FSTRM_CONTROL_FRAME_FINISH); fd_set_block(fd); - if(send(fd, finishframe, len, 0) == -1) { + if(send(fd, (void*)finishframe, len, 0) == -1) { #ifndef USE_WINSOCK log_err("send failed: %s", strerror(errno)); #else @@ -491,7 +501,8 @@ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) while(data->len_done < 4) { uint32_t l = (uint32_t)data->len; ssize_t ret = receive_bytes(fd, - ((uint8_t*)&l)+data->len_done, 4-data->len_done); + ((uint8_t*)&l)+data->len_done, 4-data->len_done, + data->ev); if(verbosity>=4) log_info("s recv %d", (int)ret); if(ret == 0) { /* closed or error */ @@ -526,7 +537,7 @@ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) /* we want to read the full length now */ if(data->data_done < data->len) { ssize_t r = receive_bytes(fd, data->frame + data->data_done, - data->len - data->data_done); + data->len - data->data_done, data->ev); if(verbosity>=4) log_info("f recv %d", (int)r); if(r == 0) { /* closed or error */ @@ -576,10 +587,10 @@ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) /** callback for main listening file descriptor */ void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) { + struct main_tap_data* maindata = (struct main_tap_data*)arg; struct tap_data* data; struct sockaddr_storage addr; socklen_t addrlen = (socklen_t)sizeof(addr); - struct ub_event_base* base = (struct ub_event_base*)arg; int s = accept(fd, (struct sockaddr*)&addr, &addrlen); if(s == -1) { #ifndef USE_WINSOCK @@ -602,17 +613,18 @@ void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) WSAGetLastError() == WSAECONNRESET) return; if(WSAGetLastError() == WSAEWOULDBLOCK) { - ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ); + ub_winsock_tcp_wouldblock(maindata->ev, UB_EV_READ); return; } log_err_addr("accept failed", wsa_strerror(WSAGetLastError()), - addr, *addrlen); + &addr, addrlen); #endif return; } fd_set_nonblock(s); if(verbosity) { if(addr.ss_family == AF_LOCAL) { +#ifdef HAVE_SYS_UN_H struct sockaddr_un* usock = calloc(1, sizeof(struct sockaddr_un) + 1); if(usock) { socklen_t ulen = sizeof(struct sockaddr_un); @@ -625,6 +637,7 @@ void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) } else { log_info("accepted new dnstap client"); } +#endif /* HAVE_SYS_UN_H */ } else { log_info("accepted new dnstap client"); } @@ -633,7 +646,7 @@ void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) data = calloc(1, sizeof(*data)); if(!data) fatal_exit("out of memory"); data->fd = s; - data->ev = ub_event_new(base, s, UB_EV_READ | UB_EV_PERSIST, + data->ev = ub_event_new(maindata->base, s, UB_EV_READ | UB_EV_PERSIST, &tap_callback, data); if(!data->ev) fatal_exit("could not ub_event_new"); if(ub_event_add(data->ev, NULL) != 0) fatal_exit("could not ub_event_add"); @@ -653,20 +666,25 @@ setup_and_run(char* socketpath) int fd; time_t secs = 0; struct timeval now; + struct main_tap_data* maindata; struct ub_event_base* base; const char *evnm="event", *evsys="", *evmethod=""; struct ub_event *ev; + maindata = calloc(1, sizeof(*maindata)); + if(!maindata) fatal_exit("out of memory"); memset(&now, 0, sizeof(now)); base = ub_default_event_base(1, &secs, &now); if(!base) fatal_exit("could not create ub_event base"); + maindata->base = base; fd = setup_fd(socketpath); ub_get_event_sys(base, &evnm, &evsys, &evmethod); if(verbosity) log_info("%s %s uses %s method", evnm, evsys, evmethod); ev = ub_event_new(base, fd, UB_EV_READ | UB_EV_PERSIST, - &mainfdcallback, base); + &mainfdcallback, maindata); if(!ev) fatal_exit("could not ub_event_new"); if(ub_event_add(ev, NULL) != 0) fatal_exit("could not ub_event_add"); + maindata->ev = ev; ub_event_base_dispatch(base); @@ -674,6 +692,7 @@ setup_and_run(char* socketpath) ub_event_free(ev); ub_event_base_free(base); close(fd); + free(maindata); } /** getopt global, in case header files fail to declare it. */ From 989922631ae7f6d31a93ba454b6f4364bac64694 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 28 Jan 2020 15:09:21 +0100 Subject: [PATCH 38/96] dnstap io, fix exit when compiled without threads. --- dnstap/dnstap.c | 1 - dnstap/dtstream.c | 7 +++++-- dnstap/dtstream.h | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/dnstap/dnstap.c b/dnstap/dnstap.c index c06644eae..810f3200a 100644 --- a/dnstap/dnstap.c +++ b/dnstap/dnstap.c @@ -262,7 +262,6 @@ dt_delete(struct dt_env *env) { if (!env) return; - verbose(VERB_OPS, "closing dnstap socket"); dt_io_thread_delete(env->dtio); free(env->identity); free(env->version); diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 47f4473be..f21641049 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -162,7 +162,7 @@ static void dtio_wakeup(struct dt_io_thread* dtio) { uint8_t cmd = DTIO_COMMAND_WAKEUP; if(!dtio) return; - if(!dtio->event_base) return; /* not started */ + if(!dtio->started) return; while(1) { ssize_t r = write(dtio->commandpipe[1], &cmd, sizeof(cmd)); @@ -1292,6 +1292,7 @@ int dt_io_thread_start(struct dt_io_thread* dtio) #endif /* start the thread */ + dtio->started = 1; ub_thread_create(&dtio->tid, dnstap_io, dtio); return 1; } @@ -1300,7 +1301,8 @@ void dt_io_thread_stop(struct dt_io_thread* dtio) { uint8_t cmd = DTIO_COMMAND_STOP; if(!dtio) return; - if(!dtio->event_base) return; /* not started */ + if(!dtio->started) return; + verbose(VERB_ALGO, "dnstap io: send stop cmd"); while(1) { ssize_t r = write(dtio->commandpipe[1], &cmd, sizeof(cmd)); @@ -1321,6 +1323,7 @@ void dt_io_thread_stop(struct dt_io_thread* dtio) } break; } + dtio->started = 0; #ifndef USE_WINSOCK close(dtio->commandpipe[1]); diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 3386a1897..473479d8f 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -102,6 +102,8 @@ struct dt_io_thread { struct dt_io_list_item* io_list_iter; /** thread id, of the io thread */ ub_thread_type tid; + /** if the io processing has started */ + int started; /** file descriptor that the thread writes to */ int fd; From 1e4165d25be668118aa8421719af06ce8877fcd4 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 28 Jan 2020 15:51:39 +0100 Subject: [PATCH 39/96] dnstap io, without threads, logs from the main event loop. --- daemon/worker.c | 5 +++-- dnstap/dtstream.c | 26 +++++++++++++++++++++++++- dnstap/dtstream.h | 5 ++++- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/daemon/worker.c b/daemon/worker.c index d14409570..759fd0457 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -1883,7 +1883,8 @@ worker_init(struct worker* worker, struct config_file *cfg, && worker->thread_num == 0 #endif ) { - if(!dt_io_thread_start(dtenv->dtio)) { + if(!dt_io_thread_start(dtenv->dtio, comm_base_internal( + worker->base))) { log_err("could not start dnstap io thread"); worker_delete(worker); return 0; @@ -1937,7 +1938,6 @@ worker_delete(struct worker* worker) wsvc_desetup_worker(worker); #endif /* UB_ON_WINDOWS */ } - comm_base_delete(worker->base); #ifdef USE_DNSTAP if(worker->daemon->cfg->dnstap #ifndef THREADS_DISABLED @@ -1948,6 +1948,7 @@ worker_delete(struct worker* worker) } dt_deinit(&worker->dtenv); #endif /* USE_DNSTAP */ + comm_base_delete(worker->base); ub_randfree(worker->rndstate); alloc_clear(&worker->alloc); regional_destroy(worker->env.scratch); diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index f21641049..9f7345b3a 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -398,6 +398,7 @@ static void dtio_reconnect_enable(struct dt_io_thread* dtio) { struct timeval tv; int msec; + if(dtio->want_to_exit) return; if(dtio->reconnect_is_added) return; /* already done */ @@ -892,6 +893,7 @@ static void dtio_cmd_cb(int fd, short ATTR_UNUSED(bits), void* arg) } } +#ifndef THREADS_DISABLED /** setup the event base for the dnstap io thread */ static void dtio_setup_base(struct dt_io_thread* dtio, time_t* secs, struct timeval* now) @@ -902,6 +904,7 @@ static void dtio_setup_base(struct dt_io_thread* dtio, time_t* secs, fatal_exit("dnstap io: could not create event_base"); } } +#endif /* THREADS_DISABLED */ /** setup the cmd event for dnstap io */ static void dtio_setup_cmd(struct dt_io_thread* dtio) @@ -1145,7 +1148,9 @@ static void dtio_desetup(struct dt_io_thread* dtio) dtio_reconnect_del(dtio); ub_event_free(dtio->reconnect_timer); dtio_cur_msg_free(dtio); +#ifndef THREADS_DISABLED ub_event_base_free(dtio->event_base); +#endif } /** setup a start control message */ @@ -1248,6 +1253,7 @@ static void dtio_open_output(struct dt_io_thread* dtio) #endif /* HAVE_SYS_UN_H */ } +#ifndef THREADS_DISABLED /** the IO thread function for the DNSTAP IO */ static void* dnstap_io(void* arg) { @@ -1274,8 +1280,9 @@ static void* dnstap_io(void* arg) dtio_desetup(dtio); return NULL; } +#endif /* THREADS_DISABLED */ -int dt_io_thread_start(struct dt_io_thread* dtio) +int dt_io_thread_start(struct dt_io_thread* dtio, void* event_base_nothr) { /* set up the thread, can fail */ #ifndef USE_WINSOCK @@ -1293,17 +1300,28 @@ int dt_io_thread_start(struct dt_io_thread* dtio) /* start the thread */ dtio->started = 1; +#ifndef THREADS_DISABLED ub_thread_create(&dtio->tid, dnstap_io, dtio); +#else + dtio->event_base = event_base_nothr; + dtio_setup_cmd(dtio); + dtio_setup_reconnect(dtio); + dtio_open_output(dtio); + dtio_add_output_event_write(dtio); +#endif return 1; } void dt_io_thread_stop(struct dt_io_thread* dtio) { +#ifndef THREADS_DISABLED uint8_t cmd = DTIO_COMMAND_STOP; +#endif if(!dtio) return; if(!dtio->started) return; verbose(VERB_ALGO, "dnstap io: send stop cmd"); +#ifndef THREADS_DISABLED while(1) { ssize_t r = write(dtio->commandpipe[1], &cmd, sizeof(cmd)); if(r == -1) { @@ -1324,6 +1342,7 @@ void dt_io_thread_stop(struct dt_io_thread* dtio) break; } dtio->started = 0; +#endif /* THREADS_DISABLED */ #ifndef USE_WINSOCK close(dtio->commandpipe[1]); @@ -1331,5 +1350,10 @@ void dt_io_thread_stop(struct dt_io_thread* dtio) _close(dtio->commandpipe[1]); #endif dtio->commandpipe[1] = -1; +#ifndef THREADS_DISABLED ub_thread_join(dtio->tid); +#else + dtio->want_to_exit = 1; + dtio_desetup(dtio); +#endif } diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 473479d8f..c2b898b86 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -345,9 +345,12 @@ void dt_io_thread_unregister_queue(struct dt_io_thread* dtio, /** * Start the io thread * @param dtio: the io thread. + * @param event_base_nothr: the event base to attach the events to, in case + * we are running without threads. With threads, this is ignored + * and a thread is started to process the dnstap log messages. * @return false on failure. */ -int dt_io_thread_start(struct dt_io_thread* dtio); +int dt_io_thread_start(struct dt_io_thread* dtio, void* event_base_nothr); /** * Stop the io thread From 565b3ef8cb91f665f6fb8f260b836f2069bb4bf4 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 29 Jan 2020 16:22:32 +0100 Subject: [PATCH 40/96] dnstap io, fix compile warning when compiled with threading enabled. --- dnstap/dtstream.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 9f7345b3a..2fd99a05c 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -1302,6 +1302,7 @@ int dt_io_thread_start(struct dt_io_thread* dtio, void* event_base_nothr) dtio->started = 1; #ifndef THREADS_DISABLED ub_thread_create(&dtio->tid, dnstap_io, dtio); + (void)event_base_nothr; #else dtio->event_base = event_base_nothr; dtio_setup_cmd(dtio); From 0248872938e47e58c9c02ea7151b19986e90ada7 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 29 Jan 2020 16:31:33 +0100 Subject: [PATCH 41/96] dnstap io, move setup with nothreads into its own routine. --- dnstap/dtstream.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 2fd99a05c..8d98c559d 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -1253,6 +1253,15 @@ static void dtio_open_output(struct dt_io_thread* dtio) #endif /* HAVE_SYS_UN_H */ } +/** perform the setup of the writer thread on the established event_base */ +static void dtio_setup_on_base(struct dt_io_thread* dtio) +{ + dtio_setup_cmd(dtio); + dtio_setup_reconnect(dtio); + dtio_open_output(dtio); + dtio_add_output_event_write(dtio); +} + #ifndef THREADS_DISABLED /** the IO thread function for the DNSTAP IO */ static void* dnstap_io(void* arg) @@ -1264,10 +1273,7 @@ static void* dnstap_io(void* arg) /* setup */ verbose(VERB_ALGO, "start dnstap io thread"); dtio_setup_base(dtio, &secs, &now); - dtio_setup_cmd(dtio); - dtio_setup_reconnect(dtio); - dtio_open_output(dtio); - dtio_add_output_event_write(dtio); + dtio_setup_on_base(dtio); /* run */ if(ub_event_base_dispatch(dtio->event_base) < 0) { @@ -1305,10 +1311,7 @@ int dt_io_thread_start(struct dt_io_thread* dtio, void* event_base_nothr) (void)event_base_nothr; #else dtio->event_base = event_base_nothr; - dtio_setup_cmd(dtio); - dtio_setup_reconnect(dtio); - dtio_open_output(dtio); - dtio_add_output_event_write(dtio); + dtio_setup_on_base(dtio); #endif return 1; } From ba4952470803e0da72f86bb745ca1b9c45f685e1 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 30 Jan 2020 13:10:29 +0100 Subject: [PATCH 42/96] dnstap socket tool better help text. --- dnstap/unbound-dnstap-socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index 5a7a0cfa0..a1705e1d7 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -70,7 +70,7 @@ static void usage(char* argv[]) printf("usage: %s [options]\n", argv[0]); printf(" Listen to dnstap messages\n"); printf("stdout has dnstap log, stderr has verbose server log\n"); - printf("-u use unix socket with this file name\n"); + printf("-u listen to unix socket with this file name\n"); printf("-l long format for DNS printout\n"); printf("-v more verbose log output\n"); printf("-h this help text\n"); From 9dbb5662b7be89debec51f0e977986802ef78cef Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 30 Jan 2020 13:39:13 +0100 Subject: [PATCH 43/96] fix ascync test compile with lock checks. --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index f2444dc65..f461f3a25 100644 --- a/Makefile.in +++ b/Makefile.in @@ -218,7 +218,7 @@ MEMSTATS_OBJ_LINK=$(MEMSTATS_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \ $(SLDNS_OBJ) ASYNCLOOK_SRC=testcode/asynclook.c ASYNCLOOK_OBJ=asynclook.lo -ASYNCLOOK_OBJ_LINK=$(ASYNCLOOK_OBJ) log.lo locks.lo $(COMPAT_OBJ) @ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ@ +ASYNCLOOK_OBJ_LINK=$(ASYNCLOOK_OBJ) log.lo locks.lo $(CHECKLOCK_OBJ) $(COMPAT_OBJ) @ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ@ STREAMTCP_SRC=testcode/streamtcp.c STREAMTCP_OBJ=streamtcp.lo STREAMTCP_OBJ_LINK=$(STREAMTCP_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \ From fa49fc77e30183bd3b9ddf1441fb72e640a091f3 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 30 Jan 2020 13:39:31 +0100 Subject: [PATCH 44/96] fix dnstap io for lock checks, log identity (numworkers+1), and add locks around protected area modification in the message queue. --- daemon/worker.c | 2 +- dnstap/dtstream.c | 9 ++++++++- dnstap/dtstream.h | 8 +++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/daemon/worker.c b/daemon/worker.c index 759fd0457..85d5b7de0 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -1884,7 +1884,7 @@ worker_init(struct worker* worker, struct config_file *cfg, #endif ) { if(!dt_io_thread_start(dtenv->dtio, comm_base_internal( - worker->base))) { + worker->base), worker->daemon->num)) { log_err("could not start dnstap io thread"); worker_delete(worker); return 0; diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 8d98c559d..bd4d39acb 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -277,7 +277,9 @@ int dt_io_thread_register_queue(struct dt_io_thread* dtio, { struct dt_io_list_item* item = malloc(sizeof(*item)); if(!item) return 0; + lock_basic_lock(&mq->lock); mq->dtio = dtio; + lock_basic_unlock(&mq->lock); item->queue = mq; item->next = dtio->io_list; dtio->io_list = item; @@ -297,7 +299,9 @@ void dt_io_thread_unregister_queue(struct dt_io_thread* dtio, if(prev) prev->next = item->next; else dtio->io_list = item->next; /* the queue itself only registered, not deleted */ + lock_basic_lock(&item->queue->lock); item->queue->dtio = NULL; + lock_basic_unlock(&item->queue->lock); free(item); dtio->io_list_iter = NULL; return; @@ -1269,6 +1273,7 @@ static void* dnstap_io(void* arg) struct dt_io_thread* dtio = (struct dt_io_thread*)arg; time_t secs = 0; struct timeval now; + log_thread_set(&dtio->threadnum); /* setup */ verbose(VERB_ALGO, "start dnstap io thread"); @@ -1288,7 +1293,8 @@ static void* dnstap_io(void* arg) } #endif /* THREADS_DISABLED */ -int dt_io_thread_start(struct dt_io_thread* dtio, void* event_base_nothr) +int dt_io_thread_start(struct dt_io_thread* dtio, void* event_base_nothr, + int numworkers) { /* set up the thread, can fail */ #ifndef USE_WINSOCK @@ -1305,6 +1311,7 @@ int dt_io_thread_start(struct dt_io_thread* dtio, void* event_base_nothr) #endif /* start the thread */ + dtio->threadnum = numworkers+1; dtio->started = 1; #ifndef THREADS_DISABLED ub_thread_create(&dtio->tid, dnstap_io, dtio); diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index c2b898b86..9309f5c0b 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -92,6 +92,9 @@ struct dt_msg_entry { * IO thread that reads from the queues and writes them. */ struct dt_io_thread { + /** the thread number for the dtio thread, + * must be first to cast thread arg to int* in checklock code. */ + int threadnum; /** event base, for event handling */ void* event_base; /** list of queues that is registered to get written */ @@ -348,9 +351,12 @@ void dt_io_thread_unregister_queue(struct dt_io_thread* dtio, * @param event_base_nothr: the event base to attach the events to, in case * we are running without threads. With threads, this is ignored * and a thread is started to process the dnstap log messages. + * @param numworkers: number of worker threads. The dnstap io thread is + * that number +1 as the threadnumber (in logs). * @return false on failure. */ -int dt_io_thread_start(struct dt_io_thread* dtio, void* event_base_nothr); +int dt_io_thread_start(struct dt_io_thread* dtio, void* event_base_nothr, + int numworkers); /** * Stop the io thread From 8aa338ba2d3dabc73dfa11d508dd05ae7a735ad6 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 30 Jan 2020 14:57:03 +0100 Subject: [PATCH 45/96] dnstap io, test threads in unit test. --- testdata/dnstap.tdir/dnstap.conf | 4 +++- testdata/dnstap.tdir/dnstap.post | 1 + testdata/dnstap.tdir/dnstap.test | 30 +++++++++++++++++++++++++++++- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/testdata/dnstap.tdir/dnstap.conf b/testdata/dnstap.tdir/dnstap.conf index 82250ec2d..5e8dfaefb 100644 --- a/testdata/dnstap.tdir/dnstap.conf +++ b/testdata/dnstap.tdir/dnstap.conf @@ -1,6 +1,6 @@ server: verbosity: 2 - num-threads: 1 + num-threads: 3 outgoing-range: 16 interface: 127.0.0.1 port: @PORT@ @@ -10,6 +10,8 @@ server: chroot: "" username: "" do-not-query-localhost: no + local-zone: "example.net." redirect + local-data: "example.net. IN A 10.20.30.41" remote-control: control-enable: yes control-interface: 127.0.0.1 diff --git a/testdata/dnstap.tdir/dnstap.post b/testdata/dnstap.tdir/dnstap.post index ec79e0427..6744b4b61 100644 --- a/testdata/dnstap.tdir/dnstap.post +++ b/testdata/dnstap.tdir/dnstap.post @@ -12,4 +12,5 @@ kill_pid $DNSTAP_SOCKET_PID kill_pid $FWD_PID kill $UNBOUND_PID kill $UNBOUND_PID >/dev/null 2>&1 +cat unbound.log exit 0 diff --git a/testdata/dnstap.tdir/dnstap.test b/testdata/dnstap.tdir/dnstap.test index 49f1d42a6..115b099d1 100644 --- a/testdata/dnstap.tdir/dnstap.test +++ b/testdata/dnstap.tdir/dnstap.test @@ -43,11 +43,39 @@ else exit 1 fi +echo "> make 10 queries to spread them over threads" +dig @127.0.0.1 -p $UNBOUND_PORT q1.example.net. +dig @127.0.0.1 -p $UNBOUND_PORT q2.example.net. +dig @127.0.0.1 -p $UNBOUND_PORT q3.example.net. +dig @127.0.0.1 -p $UNBOUND_PORT q4.example.net. +dig @127.0.0.1 -p $UNBOUND_PORT q5.example.net. +dig @127.0.0.1 -p $UNBOUND_PORT q6.example.net. +dig @127.0.0.1 -p $UNBOUND_PORT q7.example.net. +dig @127.0.0.1 -p $UNBOUND_PORT q8.example.net. +dig @127.0.0.1 -p $UNBOUND_PORT q9.example.net. +dig @127.0.0.1 -p $UNBOUND_PORT q10.example.net. +for x in q1 q2 q3 q4 5 q6 q7 q8 q9 q10; do + if grep "$x.example.net" tap.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap.log >/dev/null; then :; else sleep 10; fi + if grep "$x.example.net" tap.log; then echo "yes it is in tap.log"; + else + echo "$x.example.net. information not in tap.log" + echo "failed" + echo "> cat logfiles" + cat tap.log + cat tap.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 + fi +done echo "> cat logfiles" cat tap.log cat tap.errlog cat fwd.log -cat unbound.log echo "> OK" exit 0 From dd1b35412f0200343cabf57739922fcbf6b22f93 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 30 Jan 2020 15:13:25 +0100 Subject: [PATCH 46/96] dnstap io, add reconnect test. --- testdata/dnstap.tdir/dnstap.test | 1 + .../dnstap_reconnect.conf | 40 ++++++++ .../dnstap_reconnect.dsc | 16 +++ .../dnstap_reconnect.post | 16 +++ .../dnstap_reconnect.pre | 55 +++++++++++ .../dnstap_reconnect.test | 98 +++++++++++++++++++ .../dnstap_reconnect.testns | 22 +++++ .../dnstap_reconnect.tdir/unbound_control.key | 15 +++ .../dnstap_reconnect.tdir/unbound_control.pem | 11 +++ .../dnstap_reconnect.tdir/unbound_server.key | 15 +++ .../dnstap_reconnect.tdir/unbound_server.pem | 11 +++ 11 files changed, 300 insertions(+) create mode 100644 testdata/dnstap_reconnect.tdir/dnstap_reconnect.conf create mode 100644 testdata/dnstap_reconnect.tdir/dnstap_reconnect.dsc create mode 100644 testdata/dnstap_reconnect.tdir/dnstap_reconnect.post create mode 100644 testdata/dnstap_reconnect.tdir/dnstap_reconnect.pre create mode 100644 testdata/dnstap_reconnect.tdir/dnstap_reconnect.test create mode 100644 testdata/dnstap_reconnect.tdir/dnstap_reconnect.testns create mode 100644 testdata/dnstap_reconnect.tdir/unbound_control.key create mode 100644 testdata/dnstap_reconnect.tdir/unbound_control.pem create mode 100644 testdata/dnstap_reconnect.tdir/unbound_server.key create mode 100644 testdata/dnstap_reconnect.tdir/unbound_server.pem diff --git a/testdata/dnstap.tdir/dnstap.test b/testdata/dnstap.tdir/dnstap.test index 115b099d1..4ee4daf4c 100644 --- a/testdata/dnstap.tdir/dnstap.test +++ b/testdata/dnstap.tdir/dnstap.test @@ -4,6 +4,7 @@ # use .tpkg.var.test for in test variable passing [ -f .tpkg.var.test ] && source .tpkg.var.test +. ../common.sh PRE="../.." if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi diff --git a/testdata/dnstap_reconnect.tdir/dnstap_reconnect.conf b/testdata/dnstap_reconnect.tdir/dnstap_reconnect.conf new file mode 100644 index 000000000..07febae5a --- /dev/null +++ b/testdata/dnstap_reconnect.tdir/dnstap_reconnect.conf @@ -0,0 +1,40 @@ +server: + verbosity: 2 + num-threads: 1 + outgoing-range: 16 + interface: 127.0.0.1 + port: @PORT@ + use-syslog: no + directory: "" + pidfile: "unbound.pid" + chroot: "" + username: "" + do-not-query-localhost: no + local-zone: "example.net." redirect + local-data: "example.net. IN A 10.20.30.41" +remote-control: + control-enable: yes + control-interface: 127.0.0.1 + # control-interface: ::1 + control-port: @CONTROL_PORT@ + server-key-file: "unbound_server.key" + server-cert-file: "unbound_server.pem" + control-key-file: "unbound_control.key" + control-cert-file: "unbound_control.pem" +forward-zone: + name: "." + forward-addr: "127.0.0.1@@TOPORT@" +dnstap: + dnstap-enable: yes + dnstap-socket-path: "dnstap.socket" + dnstap-send-identity: yes + dnstap-send-version: yes + #dnstap-identity + #dnstap-version + dnstap-log-resolver-query-messages: yes + dnstap-log-resolver-response-messages: yes + dnstap-log-client-query-messages: yes + dnstap-log-client-response-messages: yes + dnstap-log-forwarder-query-messages: yes + dnstap-log-forwarder-response-messages: yes + diff --git a/testdata/dnstap_reconnect.tdir/dnstap_reconnect.dsc b/testdata/dnstap_reconnect.tdir/dnstap_reconnect.dsc new file mode 100644 index 000000000..c6b128006 --- /dev/null +++ b/testdata/dnstap_reconnect.tdir/dnstap_reconnect.dsc @@ -0,0 +1,16 @@ +BaseName: dnstap_reconnect +Version: 1.0 +Description: test dnstap reconnect +CreationDate: Tue Jan 21 13:00:38 CET 2020 +Maintainer: dr. W.C.A. Wijngaards +Category: +Component: +CmdDepends: +Depends: +Help: +Pre: dnstap_reconnect.pre +Post: dnstap_reconnect.post +Test: dnstap_reconnect.test +AuxFiles: +Passed: +Failure: diff --git a/testdata/dnstap_reconnect.tdir/dnstap_reconnect.post b/testdata/dnstap_reconnect.tdir/dnstap_reconnect.post new file mode 100644 index 000000000..8474b3a02 --- /dev/null +++ b/testdata/dnstap_reconnect.tdir/dnstap_reconnect.post @@ -0,0 +1,16 @@ +# #-- dnstap_reconnect.post --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# source the test var file when it's there +[ -f .tpkg.var.test ] && source .tpkg.var.test +# +# do your teardown here +. ../common.sh +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi +kill_pid $DNSTAP_SOCKET_PID +kill_pid $FWD_PID +kill $UNBOUND_PID +kill $UNBOUND_PID >/dev/null 2>&1 +cat unbound.log +exit 0 diff --git a/testdata/dnstap_reconnect.tdir/dnstap_reconnect.pre b/testdata/dnstap_reconnect.tdir/dnstap_reconnect.pre new file mode 100644 index 000000000..a1aba4f35 --- /dev/null +++ b/testdata/dnstap_reconnect.tdir/dnstap_reconnect.pre @@ -0,0 +1,55 @@ +# #-- dnstap_reconnect.pre--# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +. ../common.sh + +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi + +get_random_port 3 +UNBOUND_PORT=$RND_PORT +FWD_PORT=$(($RND_PORT + 1)) +CONTROL_PORT=$(($RND_PORT + 2)) +echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test +echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test +echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test + +# start forwarder +get_ldns_testns +$LDNS_TESTNS -p $FWD_PORT dnstap_reconnect.testns >fwd.log 2>&1 & +FWD_PID=$! +echo "FWD_PID=$FWD_PID" >> .tpkg.var.test + +# start the dnstap log server +# the -vvvv flag prints protocol and connection information from the +# unbound-dnstap-socket server. +# the -l flag prints the DNS info in the DNSTAP packet in multiline output. +# stderr is the '-vvvv' server logs and errors. +# stdout is the one-line packet logs (or with -l, multiline). +$PRE/unbound-dnstap-socket -u dnstap.socket -l -vvvv 2>tap.errlog >tap.log & +if test $? -ne 0; then + echo "could not start unbound-dnstap-socket server" + exit 1 +fi +DNSTAP_SOCKET_PID=$! +echo "DNSTAP_SOCKET_PID=$DNSTAP_SOCKET_PID" >> .tpkg.var.test +# wait for the server to go up and make the dnstap.socket file +wait_server_up "tap.errlog" "creating unix socket" +if test ! -S dnstap.socket; then + echo "the dnstap.socket file does not exist!" +fi + +# make config file +sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < dnstap_reconnect.conf > ub.conf +# start unbound in the background +$PRE/unbound -d -c ub.conf >unbound.log 2>&1 & +UNBOUND_PID=$! +echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test + +cat .tpkg.var.test +wait_ldns_testns_up fwd.log +wait_unbound_up unbound.log + diff --git a/testdata/dnstap_reconnect.tdir/dnstap_reconnect.test b/testdata/dnstap_reconnect.tdir/dnstap_reconnect.test new file mode 100644 index 000000000..94679bc66 --- /dev/null +++ b/testdata/dnstap_reconnect.tdir/dnstap_reconnect.test @@ -0,0 +1,98 @@ +# #-- dnstap_reconnect.test --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +. ../common.sh +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi + +# test if the server is up. +echo "> dig www.example.com." +dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile +echo "> check answer" +if grep "10.20.30.40" outfile; then + echo "OK" +else + echo "> cat logfiles" + cat tap.log + cat tap.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 +fi + +echo "> check tap.log for dnstap info" +# see if it logged the information in tap.log +# wait for a moment for filesystem to catch up. +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 10; fi +if grep "www.example.com" tap.log; then echo "yes it is in tap.log"; +else + echo "information not in tap.log" + echo "failed" + echo "> cat logfiles" + cat tap.log + cat tap.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 +fi + +echo "" +echo "> test disconnect from the upstream server" + +kill_pid $DNSTAP_SOCKET_PID +dig @127.0.0.1 -p $UNBOUND_PORT down.example.net. + +# bring log socket back up +$PRE/unbound-dnstap-socket -u dnstap.socket -l -vvvv 2>tap2.errlog >tap2.log & +if test $? -ne 0; then + echo "could not start (again) unbound-dnstap-socket server" + exit 1 +fi +DNSTAP_SOCKET_PID=$! +echo "DNSTAP_SOCKET_PID=$DNSTAP_SOCKET_PID" >> .tpkg.var.test +# wait for the server to go up and make the dnstap.socket file +wait_server_up "tap2.errlog" "creating unix socket" + +dig @127.0.0.1 -p $UNBOUND_PORT up.example.net. +sleep 2 +dig @127.0.0.1 -p $UNBOUND_PORT up2.example.net. + +for x in down up up2; do + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 10; fi + if grep "$x.example.net" tap2.log; then echo "yes it is in tap2.log"; + else + echo "$x.example.net. information not in tap2.log" + echo "failed" + echo "> cat logfiles" + cat tap.log + cat tap.errlog + echo "> tap2 logfiles" + cat tap2.log + cat tap2.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 + fi +done + +echo "> cat logfiles" +cat tap.log +cat tap.errlog +echo "> tap2 logfiles" +cat tap2.log +cat tap2.errlog +cat fwd.log +echo "> OK" +exit 0 diff --git a/testdata/dnstap_reconnect.tdir/dnstap_reconnect.testns b/testdata/dnstap_reconnect.tdir/dnstap_reconnect.testns new file mode 100644 index 000000000..0c911ca5b --- /dev/null +++ b/testdata/dnstap_reconnect.tdir/dnstap_reconnect.testns @@ -0,0 +1,22 @@ +; nameserver test file +$ORIGIN example.com. +$TTL 3600 + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA NOERROR +ADJUST copy_id +SECTION QUESTION +www IN A +SECTION ANSWER +www IN A 10.20.30.40 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA SERVFAIL +ADJUST copy_id +SECTION QUESTION +www.example.net. IN A +ENTRY_END + diff --git a/testdata/dnstap_reconnect.tdir/unbound_control.key b/testdata/dnstap_reconnect.tdir/unbound_control.key new file mode 100644 index 000000000..d7c43a06b --- /dev/null +++ b/testdata/dnstap_reconnect.tdir/unbound_control.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDD6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBa +rzPA0vlyuNtUsEN3qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvH +ST6JwUdIg0Lzg/USJ81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQAB +AoGAFT3e35MIgI4uDJJ8X0RfHp2NCO2LUg4TKbWical/C0W9vlR1/x80G1pE1d2Z +WotqJVWTrOq6eBox19RCgtLg2wPGk9uD62+9SDT37heWFlUCElWq50pQG6k9ThiG +DDypkZyZ/52+DdWybiaQJkuK6O5qQXuNAtVJMpghu4GnHAECQQDsupnZUQDpapzr +4FC4MSkL2+A1PRt6g4VhwoqOpJXaHfVnH6F7AwUuOLNwGdR5Cvv70pfJ7Jqg8L2m +Kxyl5bORAkEA09rn34YQ0pHJdHidbl2kInIuYTz09+TO3LWwan17nISH9aaYvVDr +p9x1B4Qzw9qyxT9oll7ze/5Rw/7C3AQj4QJAT2B2a+b8bkgAXBs4FbruL3rHoDJg +P2FQXSpVOWU4lg2LlsuFYvDtUMVUbZdLplanjZXcral3Y9W1Ub2M+ped8QJAYQN+ +aRpge7ys7vwIw7B36Bo3aOncF+ScYe+FkM5Tm7II/JHEofT7ZQwMP1vnxIlSkgbe +YvWqNB6a3NC99LikoQJBAM4UhDdRg63Tr6Idky6CQaH///zAN7nArJfffKGWFdw9 +DKrWpNqvYZtX/cfEJucKcRCm5YL8CKFYbQy4VoCxUcE= +-----END RSA PRIVATE KEY----- diff --git a/testdata/dnstap_reconnect.tdir/unbound_control.pem b/testdata/dnstap_reconnect.tdir/unbound_control.pem new file mode 100644 index 000000000..8f1ba87f1 --- /dev/null +++ b/testdata/dnstap_reconnect.tdir/unbound_control.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBozCCAQwCCQD6XaN6FzW/4DANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1 +bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowGjEYMBYGA1UE +AxMPdW5ib3VuZC1jb250cm9sMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDD +6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBarzPA0vlyuNtUsEN3 +qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvHST6JwUdIg0Lzg/US +J81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQABMA0GCSqGSIb3DQEB +BQUAA4GBAGFAXmaQHuFgAuc6HVhYZJdToxLBhfxGpot4oZNjcb1Cdoz3OL34MU1B +9E5psj2PpGPIi8/RwoqBtAJHJ+J5cWngo03o4ZmdwKNSzaxlp141z/3rUtFqEHEC +iO6gPCT3U7dt6MyC7r6vdMqyW6aldP3CtwD0gQziKAMoj+TAfAcq +-----END CERTIFICATE----- diff --git a/testdata/dnstap_reconnect.tdir/unbound_server.key b/testdata/dnstap_reconnect.tdir/unbound_server.key new file mode 100644 index 000000000..4256c421d --- /dev/null +++ b/testdata/dnstap_reconnect.tdir/unbound_server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQC3F7Jsv2u01pLL9rFnjsMU/IaCFUIz/624DcaE84Z4gjMl5kWA +3axQcqul1wlwSrbKwrony+d9hH/+MX0tZwvl8w3OmhmOAiaQ+SHCsIuOjVwQjX0s +RLB61Pz5+PAiVvnPa9JIYB5QrK6DVEsxIHj8MOc5JKORrnESsFDh6yeMeQIDAQAB +AoGAAuWoGBprTOA8UGfl5LqYkaNxSWumsYXxLMFjC8WCsjN1NbtQDDr1uAwodSZS +6ujzvX+ZTHnofs7y64XC8k34HTOCD2zlW7kijWbT8YjRYFU6o9F5zUGD9RCan0ds +sVscT2psLSzfdsmFAcbmnGdxYkXk2PC1FHtaqExxehralGUCQQDcqrg9uQKXlhQi +XAaPr8SiWvtRm2a9IMMZkRfUWZclPHq6fCWNuUaCD+cTat4wAuqeknAz33VEosw3 +fXGsok//AkEA1GjIHXrOcSlpfVJb6NeOBugjRtZ7ZDT5gbtnMS9ob0qntKV6saaL +CNmJwuD9Q3XkU5j1+uHvYGP2NzcJd2CjhwJACV0hNlVMe9w9fHvFN4Gw6WbM9ViP +0oS6YrJafYNTu5vGZXVxLoNnL4u3NYa6aPUmuZXjNwBLfJ8f5VboZPf6RwJAINd2 +oYA8bSi/A755MX4qmozH74r4Fx1Nuq5UHTm8RwDe/0Javx8F/j9MWpJY9lZDEF3l +In5OebPa/NyInSmW/wJAZuP9aRn0nDBkHYri++1A7NykMiJ/nH0mDECbnk+wxx0S +LwqIetBhxb8eQwMg45+iAH7CHAMQ8BQuF/nFE6eotg== +-----END RSA PRIVATE KEY----- diff --git a/testdata/dnstap_reconnect.tdir/unbound_server.pem b/testdata/dnstap_reconnect.tdir/unbound_server.pem new file mode 100644 index 000000000..aeda3ff11 --- /dev/null +++ b/testdata/dnstap_reconnect.tdir/unbound_server.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBmzCCAQQCCQDsNJ1UmphEFzANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1 +bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowEjEQMA4GA1UE +AxMHdW5ib3VuZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtxeybL9rtNaS +y/axZ47DFPyGghVCM/+tuA3GhPOGeIIzJeZFgN2sUHKrpdcJcEq2ysK6J8vnfYR/ +/jF9LWcL5fMNzpoZjgImkPkhwrCLjo1cEI19LESwetT8+fjwIlb5z2vSSGAeUKyu +g1RLMSB4/DDnOSSjka5xErBQ4esnjHkCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAZ +9N0lnLENs4JMvPS+mn8C5m9bkkFITd32IiLjf0zgYpIUbFXH6XaEr9GNZBUG8feG +l/6WRXnbnVSblI5odQ4XxGZ9inYY6qtW30uv76HvoKp+QZ1c3460ddR8NauhcCHH +Z7S+QbLXi+r2JAhpPozZCjBHlRD0ixzA1mKQTJhJZg== +-----END CERTIFICATE----- From a8264065f66efd9622b36d03ccaedd3ac2602adc Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 30 Jan 2020 17:11:07 +0100 Subject: [PATCH 47/96] - put fstrm protocol contents in separate files, dnstap_fstrm.c and dnstap_fstrm.h --- Makefile.in | 1 + configure | 4 +- configure.ac | 4 +- dnstap/dnstap_fstrm.c | 91 +++++++++++++++++++++ dnstap/dnstap_fstrm.h | 142 +++++++++++++++++++++++++++++++++ dnstap/dtstream.c | 47 +---------- dnstap/dtstream.h | 94 ---------------------- dnstap/unbound-dnstap-socket.c | 1 + 8 files changed, 240 insertions(+), 144 deletions(-) create mode 100644 dnstap/dnstap_fstrm.c create mode 100644 dnstap/dnstap_fstrm.h diff --git a/Makefile.in b/Makefile.in index 792ea6185..24f6f5059 100644 --- a/Makefile.in +++ b/Makefile.in @@ -410,6 +410,7 @@ unbound-dnstap-socket$(EXEEXT): $(DNSTAP_SOCKET_OBJ_LINK) dnstap.pb-c.lo dnstap.pb-c.o: dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h dtstream.lo dtstream.o: $(srcdir)/dnstap/dtstream.c config.h $(srcdir)/dnstap/dtstream.h +dnstap_fstrm.lo dnstap_fstrm.o: $(srcdir)/dnstap/dnstap_fstrm.c config.h $(srcdir)/dnstap/dnstap_fstrm.h unbound-dnstap-socket.lo unbound-dnstap-socket.o: $(srcdir)/dnstap/unbound-dnstap-socket.c config.h $(srcdir)/dnstap/dtstream.h # dnscrypt diff --git a/configure b/configure index 7832d0997..36f42644e 100755 --- a/configure +++ b/configure @@ -21039,9 +21039,9 @@ cat >>confdefs.h <<_ACEOF _ACEOF - DNSTAP_SRC="dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dtstream.c" + DNSTAP_SRC="dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dnstap_fstrm.c dnstap/dtstream.c" - DNSTAP_OBJ="dnstap.lo dnstap.pb-c.lo dtstream.lo" + DNSTAP_OBJ="dnstap.lo dnstap.pb-c.lo dnstap_fstrm.lo dtstream.lo" else diff --git a/configure.ac b/configure.ac index a9734f6f5..913703092 100644 --- a/configure.ac +++ b/configure.ac @@ -1688,8 +1688,8 @@ dt_DNSTAP([$UNBOUND_RUN_DIR/dnstap.sock], AC_DEFINE_UNQUOTED(DNSTAP_SOCKET_PATH, ["$hdr_dnstap_socket_path"], [default dnstap socket path]) - AC_SUBST([DNSTAP_SRC], ["dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dtstream.c"]) - AC_SUBST([DNSTAP_OBJ], ["dnstap.lo dnstap.pb-c.lo dtstream.lo"]) + AC_SUBST([DNSTAP_SRC], ["dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dnstap_fstrm.c dnstap/dtstream.c"]) + AC_SUBST([DNSTAP_OBJ], ["dnstap.lo dnstap.pb-c.lo dnstap_fstrm.lo dtstream.lo"]) ], [ AC_SUBST([ENABLE_DNSTAP], [0]) diff --git a/dnstap/dnstap_fstrm.c b/dnstap/dnstap_fstrm.c new file mode 100644 index 000000000..51ff71a6e --- /dev/null +++ b/dnstap/dnstap_fstrm.c @@ -0,0 +1,91 @@ +/* + * dnstap/dnstap_fstrm.c - Frame Streams protocol for dnstap + * + * Copyright (c) 2020, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** + * \file + * + * Definitions for the Frame Streams data transport protocol for + * dnstap message logs. + */ + +#include "config.h" +#include "dnstap/dnstap_fstrm.h" + +void* fstrm_create_control_frame_start(char* contenttype, size_t* len) +{ + uint32_t* control; + size_t n; + /* start framestream message: + * 4byte 0: control indicator. + * 4byte bigendian: length of control frame + * 4byte bigendian: type START + * 4byte bigendian: frame option: content-type + * 4byte bigendian: length of string + * string of content type (dnstap) + */ + n = 4+4+4+4+4+strlen(contenttype); + control = malloc(n); + if(!control) + return NULL; + control[0] = 0; + control[1] = htonl(4+4+4+strlen(contenttype)); + control[2] = htonl(FSTRM_CONTROL_FRAME_START); + control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE); + control[4] = htonl(strlen(contenttype)); + memmove(&control[5], contenttype, strlen(contenttype)); + *len = n; + return control; +} + +void* fstrm_create_control_frame_stop(size_t* len) +{ + uint32_t* control; + size_t n; + /* stop framestream message: + * 4byte 0: control indicator. + * 4byte bigendian: length of control frame + * 4byte bigendian: type STOP + */ + n = 4+4+4; + control = malloc(n); + if(!control) + return NULL; + control[0] = 0; + control[1] = htonl(4); + control[2] = htonl(FSTRM_CONTROL_FRAME_STOP); + *len = n; + return control; +} diff --git a/dnstap/dnstap_fstrm.h b/dnstap/dnstap_fstrm.h new file mode 100644 index 000000000..3b70547f1 --- /dev/null +++ b/dnstap/dnstap_fstrm.h @@ -0,0 +1,142 @@ +/* + * dnstap/dnstap_fstrm.h - Frame Streams protocol for dnstap + * + * Copyright (c) 2020, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** + * \file + * + * Definitions for the Frame Streams data transport protocol for + * dnstap message logs. + */ + +#ifndef DNSTAP_FSTRM_H +#define DNSTAP_FSTRM_H + +/* Frame Streams data transfer protocol encode for DNSTAP messages. + * The protocol looks to be specified in the libfstrm library. + * + * Quick writeup for DNSTAP usage, from reading fstrm/control.h eloquent + * comments and fstrm/control.c for some bytesize details (the content type + * length). + * + * The Frame Streams can be unidirectional or bi-directional. + * bi-directional streams use control frame types READY, ACCEPT and FINISH. + * uni-directional streams use control frame types START and STOP. + * unknown control frame types should be ignored by the receiver, they + * do not change the data frame encoding. + * + * bi-directional control frames implement a simple handshake protocol + * between sender and receiver. + * + * The uni-directional control frames have one start and one stop frame, + * before and after the data. The start frame can have a content type. + * The start and stop frames are not optional. + * + * data frames are preceded by 4byte length, bigendian. + * zero length data frames are not possible, they are an escape that + * signals the presence of a control frame. + * + * a control frame consists of 0 value in 4byte bigendian, this is really + * the data frame length, with 0 the escape sequence that indicates one + * control frame follows. + * Then, 4byte bigendian, length of the control frame message. + * Then, the control frame payload (of that length). with in it: + * 4byte bigendian, control type (eg. START, STOP, READY, ACCEPT, FINISH). + * perhaps nothing more (STOP, FINISH), but for other types maybe + * control fields + * 4byte bigendian, the control-field-type, currently only content-type. + * 4byte bigendian, length of the string for this option. + * .. bytes of that string. + * + * The START type can have only one field. Field max len 256. + * control frame max frame length 512 (excludes the 0-escape and control + * frame length bytes). + * + * the bidirectional type of transmission is like this: + * client sends READY (with content type included), + * client waits for ACCEPT (with content type included), + * client sends START (with matched content type from ACCEPT) + * .. data frames + * client sends STOP. + * client waits for FINISH frame. + * + */ + +/** max length of Frame Streams content type field string */ +#define FSTRM_CONTENT_TYPE_LENGTH_MAX 256 +/** control frame value to denote the control frame ACCEPT */ +#define FSTRM_CONTROL_FRAME_ACCEPT 0x01 +/** control frame value to denote the control frame START */ +#define FSTRM_CONTROL_FRAME_START 0x02 +/** control frame value to denote the control frame STOP */ +#define FSTRM_CONTROL_FRAME_STOP 0x03 +/** control frame value to denote the control frame READY */ +#define FSTRM_CONTROL_FRAME_READY 0x04 +/** control frame value to denote the control frame FINISH */ +#define FSTRM_CONTROL_FRAME_FINISH 0x05 +/** the constant that denotes the control field type that is the + * string for the content type of the stream. */ +#define FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE 0x01 +/** the content type for DNSTAP frame streams */ +#define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap" + +/** + * This creates an FSTRM control frame of type START. + * @param contenttype: a zero delimited string with the content type. + * eg. use the constant DNSTAP_CONTENT_TYPE, which is defined as + * "protobuf:dnstap.Dnstap", for a dnstap frame stream. + * @param len: if a buffer is returned this is the length of that buffer. + * @return NULL on malloc failure. Returns a malloced buffer with the + * protocol message. The buffer starts with the 4 bytes of 0 that indicate + * a control frame. The buffer should be sent without preceding it with + * the 'len' variable (like data frames are), but straight the content of the + * buffer, because the lengths are included in the buffer. This is so that + * the zero control indicator can be included before the control frame length. + */ +void* fstrm_create_control_frame_start(char* contenttype, size_t* len); + +/** + * This creates an FSTRM control frame of type STOP. + * @param len: if a buffer is returned this is the length of that buffer. + * @return NULL on malloc failure. Returns a malloced buffer with the + * protocol message. The buffer starts with the 4 bytes of 0 that indicate + * a control frame. The buffer should be sent without preceding it with + * the 'len' variable (like data frames are), but straight the content of the + * buffer, because the lengths are included in the buffer. This is so that + * the zero control indicator can be included before the control frame length. + */ +void* fstrm_create_control_frame_stop(size_t* len); + +#endif /* DNSTAP_FSTRM_H */ diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index bd4d39acb..b734fc9c1 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -43,6 +43,7 @@ #include "config.h" #include "dnstap/dtstream.h" +#include "dnstap/dnstap_fstrm.h" #include "util/config_file.h" #include "util/ub_event.h" #include "util/net_help.h" @@ -73,52 +74,6 @@ static void dtio_add_output_event_write(struct dt_io_thread* dtio); /** start reconnection attempts */ static void dtio_reconnect_enable(struct dt_io_thread* dtio); -void* fstrm_create_control_frame_start(char* contenttype, size_t* len) -{ - uint32_t* control; - size_t n; - /* start framestream message: - * 4byte 0: control indicator. - * 4byte bigendian: length of control frame - * 4byte bigendian: type START - * 4byte bigendian: frame option: content-type - * 4byte bigendian: length of string - * string of content type (dnstap) - */ - n = 4+4+4+4+4+strlen(contenttype); - control = malloc(n); - if(!control) - return NULL; - control[0] = 0; - control[1] = htonl(4+4+4+strlen(contenttype)); - control[2] = htonl(FSTRM_CONTROL_FRAME_START); - control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE); - control[4] = htonl(strlen(contenttype)); - memmove(&control[5], contenttype, strlen(contenttype)); - *len = n; - return control; -} - -void* fstrm_create_control_frame_stop(size_t* len) -{ - uint32_t* control; - size_t n; - /* stop framestream message: - * 4byte 0: control indicator. - * 4byte bigendian: length of control frame - * 4byte bigendian: type STOP - */ - n = 4+4+4; - control = malloc(n); - if(!control) - return NULL; - control[0] = 0; - control[1] = htonl(4); - control[2] = htonl(FSTRM_CONTROL_FRAME_STOP); - *len = n; - return control; -} - struct dt_msg_queue* dt_msg_queue_create(void) { diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 9309f5c0b..f2c13fde4 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -185,100 +185,6 @@ struct dt_io_list_item { struct dt_msg_queue* queue; }; -/* Frame Streams data transfer protocol encode for DNSTAP messages. - * The protocol looks to be specified in the libfstrm library. - * - * Quick writeup for DNSTAP usage, from reading fstrm/control.h eloquent - * comments and fstrm/control.c for some bytesize details (the content type - * length). - * - * The Frame Streams can be unidirectional or bi-directional. - * bi-directional streams use control frame types READY, ACCEPT and FINISH. - * uni-directional streams use control frame types START and STOP. - * unknown control frame types should be ignored by the receiver, they - * do not change the data frame encoding. - * - * bi-directional control frames implement a simple handshake protocol - * between sender and receiver. - * - * The uni-directional control frames have one start and one stop frame, - * before and after the data. The start frame can have a content type. - * The start and stop frames are not optional. - * - * data frames are preceded by 4byte length, bigendian. - * zero length data frames are not possible, they are an escape that - * signals the presence of a control frame. - * - * a control frame consists of 0 value in 4byte bigendian, this is really - * the data frame length, with 0 the escape sequence that indicates one - * control frame follows. - * Then, 4byte bigendian, length of the control frame message. - * Then, the control frame payload (of that length). with in it: - * 4byte bigendian, control type (eg. START, STOP, READY, ACCEPT, FINISH). - * perhaps nothing more (STOP, FINISH), but for other types maybe - * control fields - * 4byte bigendian, the control-field-type, currently only content-type. - * 4byte bigendian, length of the string for this option. - * .. bytes of that string. - * - * The START type can have only one field. Field max len 256. - * control frame max frame length 512 (excludes the 0-escape and control - * frame length bytes). - * - * the bidirectional type of transmission is like this: - * client sends READY (with content type included), - * client waits for ACCEPT (with content type included), - * client sends START (with matched content type from ACCEPT) - * .. data frames - * client sends STOP. - * client waits for FINISH frame. - * - */ - -/** max length of Frame Streams content type field string */ -#define FSTRM_CONTENT_TYPE_LENGTH_MAX 256 -/** control frame value to denote the control frame ACCEPT */ -#define FSTRM_CONTROL_FRAME_ACCEPT 0x01 -/** control frame value to denote the control frame START */ -#define FSTRM_CONTROL_FRAME_START 0x02 -/** control frame value to denote the control frame STOP */ -#define FSTRM_CONTROL_FRAME_STOP 0x03 -/** control frame value to denote the control frame READY */ -#define FSTRM_CONTROL_FRAME_READY 0x04 -/** control frame value to denote the control frame FINISH */ -#define FSTRM_CONTROL_FRAME_FINISH 0x05 -/** the constant that denotes the control field type that is the - * string for the content type of the stream. */ -#define FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE 0x01 -/** the content type for DNSTAP frame streams */ -#define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap" - -/** - * This creates an FSTRM control frame of type START. - * @param contenttype: a zero delimited string with the content type. - * eg. use the constant DNSTAP_CONTENT_TYPE, which is defined as - * "protobuf:dnstap.Dnstap", for a dnstap frame stream. - * @param len: if a buffer is returned this is the length of that buffer. - * @return NULL on malloc failure. Returns a malloced buffer with the - * protocol message. The buffer starts with the 4 bytes of 0 that indicate - * a control frame. The buffer should be sent without preceding it with - * the 'len' variable (like data frames are), but straight the content of the - * buffer, because the lengths are included in the buffer. This is so that - * the zero control indicator can be included before the control frame length. - */ -void* fstrm_create_control_frame_start(char* contenttype, size_t* len); -/** - * This creates an FSTRM control frame of type STOP. - * @param len: if a buffer is returned this is the length of that buffer. - * @return NULL on malloc failure. Returns a malloced buffer with the - * protocol message. The buffer starts with the 4 bytes of 0 that indicate - * a control frame. The buffer should be sent without preceding it with - * the 'len' variable (like data frames are), but straight the content of the - * buffer, because the lengths are included in the buffer. This is so that - * the zero control indicator can be included before the control frame length. - */ -void* fstrm_create_control_frame_stop(size_t* len); - /** * Create new (empty) worker message queue. Limit set to default on max. * @return NULL on malloc failure or a new queue (not locked). diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index a1705e1d7..8afb1c1fc 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -53,6 +53,7 @@ #include #include #include "dnstap/dtstream.h" +#include "dnstap/dnstap_fstrm.h" #include "util/log.h" #include "util/ub_event.h" #include "util/net_help.h" From 11e80ce3abdf4f1f55150173a1ce5c0c00d6b66b Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 31 Jan 2020 09:53:49 +0100 Subject: [PATCH 48/96] dnstap unbound-dnstap-sock, can listen to multiple sockets, can listen to TCP sockets, cleans up on exit after signal. --- dnstap/unbound-dnstap-socket.c | 376 +++++++++++++++++++++++++++++++-- 1 file changed, 353 insertions(+), 23 deletions(-) diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index 8afb1c1fc..218d46d3c 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #ifdef HAVE_SYS_UN_H #include @@ -62,8 +63,10 @@ #include "sldns/wire2str.h" #include #include "dnstap/dnstap.pb-c.h" +#include "util/config_file.h" #define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap" +#define LISTEN_BACKLOG 16 /** usage information for streamtcp */ static void usage(char* argv[]) @@ -72,6 +75,7 @@ static void usage(char* argv[]) printf(" Listen to dnstap messages\n"); printf("stdout has dnstap log, stderr has verbose server log\n"); printf("-u listen to unix socket with this file name\n"); + printf("-s listen on the IP and port\n"); printf("-l long format for DNS printout\n"); printf("-v more verbose log output\n"); printf("-h this help text\n"); @@ -81,12 +85,14 @@ static void usage(char* argv[]) /** long format option, for multiline printout per message */ static int longformat = 0; +struct tap_socket_list; +struct tap_socket; /** main tap callback data */ struct main_tap_data { /** the event base (to loopexit) */ struct ub_event_base* base; - /** the event (that is accept()ed) */ - struct ub_event* ev; + /** the list of accept sockets */ + struct tap_socket_list* acceptlist; }; /** tap callback variables */ @@ -109,6 +115,265 @@ struct tap_data { size_t len; }; +/** list of sockets */ +struct tap_socket_list { + /** next in list */ + struct tap_socket_list* next; + /** the socket */ + struct tap_socket* s; +}; + +/** tap socket */ +struct tap_socket { + /** fd of socket */ + int fd; + /** the event for it */ + struct ub_event *ev; + /** has the event been added */ + int ev_added; + /** the callback, for the event, ev_cb(fd, bits, arg) */ + void (*ev_cb)(int, short, void*); + /** data element, (arg for the tap_socket struct) */ + void* data; + /** socketpath, if this is an AF_LOCAL socket */ + char* socketpath; + /** IP, if this is a TCP socket */ + char* ip; +}; + +/** del the tap event */ +static void tap_socket_delev(struct tap_socket* s) +{ + if(!s) return; + if(!s->ev) return; + if(!s->ev_added) return; + ub_event_del(s->ev); + s->ev_added = 0; +} + +/** close the tap socket */ +static void tap_socket_close(struct tap_socket* s) +{ + if(!s) return; + if(s->fd == -1) return; + close(s->fd); + s->fd = -1; +} + +/** delete tap socket */ +static void tap_socket_delete(struct tap_socket* s) +{ + if(!s) return; + ub_event_free(s->ev); + free(s->socketpath); + free(s->ip); + free(s); +} + +/** create new socket (unconnected, not base-added), or NULL malloc fail */ +static struct tap_socket* tap_socket_new_local(char* socketpath, + void (*ev_cb)(int, short, void*), void* data) +{ + struct tap_socket* s = calloc(1, sizeof(*s)); + if(!s) { + log_err("malloc failure"); + return NULL; + } + s->socketpath = strdup(socketpath); + if(!s->socketpath) { + free(s); + log_err("malloc failure"); + return NULL; + } + s->fd = -1; + s->ev_cb = ev_cb; + s->data = data; + return s; +} + +/** create new socket (unconnected, not base-added), or NULL malloc fail */ +static struct tap_socket* tap_socket_new_tcpaccept(char* ip, + void (*ev_cb)(int, short, void*), void* data) +{ + struct tap_socket* s = calloc(1, sizeof(*s)); + if(!s) { + log_err("malloc failure"); + return NULL; + } + s->ip = strdup(ip); + if(!s->ip) { + free(s); + log_err("malloc failure"); + return NULL; + } + s->fd = -1; + s->ev_cb = ev_cb; + s->data = data; + return s; +} + +/** setup tcp accept socket on IP string */ +static int make_tcp_accept(char* ip) +{ +#ifdef SO_REUSEADDR + int on = 1; +#endif + struct sockaddr_storage addr; + socklen_t len; + int s; + + memset(&addr, 0, sizeof(addr)); + len = (socklen_t)sizeof(addr); + if(!extstrtoaddr(ip, &addr, &len)) { + log_err("could not parse IP '%s'", ip); + return -1; + } + + if((s = socket(addr.ss_family, SOCK_STREAM, 0)) == -1) { +#ifndef USE_WINSOCK + log_err("can't create socket: %s", strerror(errno)); +#else + log_err("can't create socket: %s", + wsa_strerror(WSAGetLastError())); +#endif + return -1; + } +#ifdef SO_REUSEADDR + if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on, + (socklen_t)sizeof(on)) < 0) { +#ifndef USE_WINSOCK + log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s", + strerror(errno)); + close(s); +#else + log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s", + wsa_strerror(WSAGetLastError())); + closesocket(s); +#endif + return -1; + } +#endif /* SO_REUSEADDR */ + if(bind(s, (struct sockaddr*)&addr, len) != 0) { +#ifndef USE_WINSOCK + log_err_addr("can't bind socket", strerror(errno), + &addr, len); + close(s); +#else + log_err_addr("can't bind socket", + wsa_strerror(WSAGetLastError()), &addr, len); + closesocket(s); +#endif + return -1; + } + if(!fd_set_nonblock(s)) { +#ifndef USE_WINSOCK + close(s); +#else + closesocket(s); +#endif + return -1; + } + if(listen(s, LISTEN_BACKLOG) == -1) { +#ifndef USE_WINSOCK + log_err("can't listen: %s", strerror(errno)); + close(s); +#else + log_err("can't listen: %s", wsa_strerror(WSAGetLastError())); + closesocket(s); +#endif + return -1; + } + return s; +} + +/** setup socket on event base */ +static int tap_socket_setup(struct tap_socket* s, struct ub_event_base* base) +{ + if(s->socketpath) { + /* AF_LOCAL accept socket */ + s->fd = create_local_accept_sock(s->socketpath, NULL, 0); + if(s->fd == -1) { + log_err("could not create local socket"); + return 0; + } + s->ev = ub_event_new(base, s->fd, UB_EV_READ | UB_EV_PERSIST, + s->ev_cb, s); + if(!s->ev) { + log_err("could not ub_event_new"); + return 0; + } + if(ub_event_add(s->ev, NULL) != 0) { + log_err("could not ub_event_add"); + return 0; + } + s->ev_added = 1; + return 1; + } + if(s->ip) { + /* TCP accept socket */ + s->fd = make_tcp_accept(s->ip); + if(s->fd == -1) { + log_err("could not create tcp socket"); + return 0; + } + s->ev = ub_event_new(base, s->fd, UB_EV_READ | UB_EV_PERSIST, + s->ev_cb, s); + if(!s->ev) { + log_err("could not ub_event_new"); + return 0; + } + if(ub_event_add(s->ev, NULL) != 0) { + log_err("could not ub_event_add"); + return 0; + } + s->ev_added = 1; + return 1; + } + return 0; +} + +/** add tap socket to list */ +static int tap_socket_list_insert(struct tap_socket_list** liststart, + struct tap_socket* s) +{ + struct tap_socket_list* entry = (struct tap_socket_list*) + malloc(sizeof(*entry)); + if(!entry) + return 0; + entry->next = *liststart; + entry->s = s; + *liststart = entry; + return 1; +} + +/** delete the list */ +static void tap_socket_list_delete(struct tap_socket_list* list) +{ + struct tap_socket_list* e = list, *next; + while(e) { + next = e->next; + tap_socket_delev(e->s); + tap_socket_close(e->s); + tap_socket_delete(e->s); + free(e); + e = next; + } +} + +/** setup accept events */ +static int tap_socket_list_addevs(struct tap_socket_list* list, + struct ub_event_base* base) +{ + struct tap_socket_list* entry; + for(entry = list; entry; entry = entry->next) { + if(!tap_socket_setup(entry->s, base)) { + log_err("could not setup socket"); + return 0; + } + } + return 1; +} + /** log control frame contents */ static void log_control_frame(uint8_t* pkt, size_t len) { @@ -588,7 +853,9 @@ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) /** callback for main listening file descriptor */ void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) { - struct main_tap_data* maindata = (struct main_tap_data*)arg; + struct tap_socket* tap_sock = (struct tap_socket*)arg; + struct main_tap_data* maindata = (struct main_tap_data*) + tap_sock->data; struct tap_data* data; struct sockaddr_storage addr; socklen_t addrlen = (socklen_t)sizeof(addr); @@ -653,24 +920,59 @@ void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) if(ub_event_add(data->ev, NULL) != 0) fatal_exit("could not ub_event_add"); } -/** create file descriptor to listen on */ -static int -setup_fd(char* socketpath) +/** setup local accept sockets */ +static void setup_local_list(struct main_tap_data* maindata, + struct config_strlist_head* local_list) { - return create_local_accept_sock(socketpath, NULL, 0); + struct config_strlist* item; + for(item = local_list->first; item; item = item->next) { + struct tap_socket* s; + s = tap_socket_new_local(item->str, &mainfdcallback, + maindata); + if(!s) fatal_exit("out of memory"); + if(!tap_socket_list_insert(&maindata->acceptlist, s)) + fatal_exit("out of memory"); + } +} + +/** setup tcp accept sockets */ +static void setup_tcp_list(struct main_tap_data* maindata, + struct config_strlist_head* tcp_list) +{ + struct config_strlist* item; + for(item = tcp_list->first; item; item = item->next) { + struct tap_socket* s; + s = tap_socket_new_tcpaccept(item->str, &mainfdcallback, + maindata); + if(!s) fatal_exit("out of memory"); + if(!tap_socket_list_insert(&maindata->acceptlist, s)) + fatal_exit("out of memory"); + } +} + +/** signal variable */ +static struct ub_event_base* sig_base = NULL; +/** do we have to quit */ +int sig_quit = 0; +/** signal handler for user quit */ +static RETSIGTYPE main_sigh(int sig) +{ + if(!sig_base) return; + verbose(VERB_ALGO, "exit on signal %d\n", sig); + ub_event_base_loopexit(sig_base); + sig_quit = 1; } /** setup and run the server to listen to DNSTAP messages */ static void -setup_and_run(char* socketpath) +setup_and_run(struct config_strlist_head* local_list, + struct config_strlist_head* tcp_list) { - int fd; time_t secs = 0; struct timeval now; struct main_tap_data* maindata; struct ub_event_base* base; const char *evnm="event", *evsys="", *evmethod=""; - struct ub_event *ev; maindata = calloc(1, sizeof(*maindata)); if(!maindata) fatal_exit("out of memory"); @@ -678,21 +980,24 @@ setup_and_run(char* socketpath) base = ub_default_event_base(1, &secs, &now); if(!base) fatal_exit("could not create ub_event base"); maindata->base = base; - fd = setup_fd(socketpath); + sig_base = base; + if(sig_quit) { + ub_event_base_free(base); + free(maindata); + return; + } ub_get_event_sys(base, &evnm, &evsys, &evmethod); if(verbosity) log_info("%s %s uses %s method", evnm, evsys, evmethod); - ev = ub_event_new(base, fd, UB_EV_READ | UB_EV_PERSIST, - &mainfdcallback, maindata); - if(!ev) fatal_exit("could not ub_event_new"); - if(ub_event_add(ev, NULL) != 0) fatal_exit("could not ub_event_add"); - maindata->ev = ev; + + setup_local_list(maindata, local_list); + setup_tcp_list(maindata, tcp_list); + if(!tap_socket_list_addevs(maindata->acceptlist, base)) + fatal_exit("could not setup accept events"); ub_event_base_dispatch(base); - ub_event_del(ev); - ub_event_free(ev); + tap_socket_list_delete(maindata->acceptlist); ub_event_base_free(base); - close(fd); free(maindata); } @@ -706,7 +1011,8 @@ int main(int argc, char** argv) { int c; int usessl = 0; - char* socketpath = NULL; + struct config_strlist_head local_list; + struct config_strlist_head tcp_list; #ifdef USE_WINSOCK WSADATA wsa_data; if(WSAStartup(MAKEWORD(2,2), &wsa_data) != 0) { @@ -714,6 +1020,20 @@ int main(int argc, char** argv) return 1; } #endif + if(signal(SIGINT, main_sigh) == SIG_ERR || +#ifdef SIGQUIT + signal(SIGQUIT, main_sigh) == SIG_ERR || +#endif +#ifdef SIGHUP + signal(SIGHUP, main_sigh) == SIG_ERR || +#endif +#ifdef SIGBREAK + signal(SIGBREAK, main_sigh) == SIG_ERR || +#endif + signal(SIGTERM, main_sigh) == SIG_ERR) + fatal_exit("could not bind to signal"); + memset(&local_list, 0, sizeof(local_list)); + memset(&tcp_list, 0, sizeof(tcp_list)); /* lock debug start (if any) */ log_ident_set("unbound-dnstap-socket"); @@ -728,10 +1048,17 @@ int main(int argc, char** argv) #endif /* command line options */ - while( (c=getopt(argc, argv, "hlu:v")) != -1) { + while( (c=getopt(argc, argv, "hls:u:v")) != -1) { switch(c) { case 'u': - socketpath = optarg; + if(!cfg_strlist_append(&local_list, + strdup(optarg))) + fatal_exit("out of memory"); + break; + case 's': + if(!cfg_strlist_append(&tcp_list, + strdup(optarg))) + fatal_exit("out of memory"); break; case 'l': longformat = 1; @@ -767,7 +1094,10 @@ int main(int argc, char** argv) (void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); #endif } - setup_and_run(socketpath); + setup_and_run(&local_list, &tcp_list); + config_delstrlist(local_list.first); + config_delstrlist(tcp_list.first); + checklock_stop(); #ifdef USE_WINSOCK WSACleanup(); From 70b2c24a4e884a2c72b0a13d5805c2e40a23bf2f Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 31 Jan 2020 10:02:51 +0100 Subject: [PATCH 49/96] dnstap unbound-dnstap-sock, fixup signal handler exit. --- dnstap/unbound-dnstap-socket.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index 218d46d3c..d854ef435 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -233,13 +233,13 @@ static int make_tcp_accept(char* ip) #ifndef USE_WINSOCK log_err("can't create socket: %s", strerror(errno)); #else - log_err("can't create socket: %s", + log_err("can't create socket: %s", wsa_strerror(WSAGetLastError())); #endif return -1; } #ifdef SO_REUSEADDR - if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on, + if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on, (socklen_t)sizeof(on)) < 0) { #ifndef USE_WINSOCK log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s", @@ -259,7 +259,7 @@ static int make_tcp_accept(char* ip) &addr, len); close(s); #else - log_err_addr("can't bind socket", + log_err_addr("can't bind socket", wsa_strerror(WSAGetLastError()), &addr, len); closesocket(s); #endif @@ -957,9 +957,9 @@ int sig_quit = 0; /** signal handler for user quit */ static RETSIGTYPE main_sigh(int sig) { - if(!sig_base) return; verbose(VERB_ALGO, "exit on signal %d\n", sig); - ub_event_base_loopexit(sig_base); + if(sig_base) + ub_event_base_loopexit(sig_base); sig_quit = 1; } @@ -996,6 +996,7 @@ setup_and_run(struct config_strlist_head* local_list, ub_event_base_dispatch(base); + sig_base = NULL; tap_socket_list_delete(maindata->acceptlist); ub_event_base_free(base); free(maindata); From 59136055b9c508043d7d4273c462f66add7af475 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 31 Jan 2020 10:05:00 +0100 Subject: [PATCH 50/96] dnstap unbound-dnstap-sock, fixup constant defines. --- dnstap/unbound-dnstap-socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index d854ef435..217df1c87 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -65,7 +65,7 @@ #include "dnstap/dnstap.pb-c.h" #include "util/config_file.h" -#define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap" +/** listen backlog on TCP connections for dnstap logs */ #define LISTEN_BACKLOG 16 /** usage information for streamtcp */ From 473783e4327b664ab9098ac82f97318bf593f3b8 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 31 Jan 2020 11:10:04 +0100 Subject: [PATCH 51/96] dnstap unbound-dnstap-sock, tls options and context created. --- dnstap/unbound-dnstap-socket.c | 137 +++++++++++++++++++++++++-------- 1 file changed, 106 insertions(+), 31 deletions(-) diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index 217df1c87..3c5bcbcda 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -75,7 +75,11 @@ static void usage(char* argv[]) printf(" Listen to dnstap messages\n"); printf("stdout has dnstap log, stderr has verbose server log\n"); printf("-u listen to unix socket with this file name\n"); - printf("-s listen on the IP and port\n"); + printf("-s listen for TCP on the IP and port\n"); + printf("-t listen for TLS on IP and port\n"); + printf("-x server key file for TLS service\n"); + printf("-y server cert file for TLS service\n"); + printf("-z cert file to verify client connections\n"); printf("-l long format for DNS printout\n"); printf("-v more verbose log output\n"); printf("-h this help text\n"); @@ -101,6 +105,8 @@ struct tap_data { int fd; /** the ub event */ struct ub_event* ev; + /** the SSL for TLS streams */ + SSL* ssl; /** have we read the length, and how many bytes of it */ int len_done; /** have we read the data, and how many bytes of it */ @@ -139,6 +145,8 @@ struct tap_socket { char* socketpath; /** IP, if this is a TCP socket */ char* ip; + /** for a TLS socket, the tls context */ + SSL_CTX* sslctx; }; /** del the tap event */ @@ -164,6 +172,7 @@ static void tap_socket_close(struct tap_socket* s) static void tap_socket_delete(struct tap_socket* s) { if(!s) return; + SSL_CTX_free(s->sslctx); ub_event_free(s->ev); free(s->socketpath); free(s->ip); @@ -212,6 +221,29 @@ static struct tap_socket* tap_socket_new_tcpaccept(char* ip, return s; } +/** create new socket (unconnected, not base-added), or NULL malloc fail */ +static struct tap_socket* tap_socket_new_tlsaccept(char* ip, + void (*ev_cb)(int, short, void*), void* data, char* server_key, + char* server_cert, char* verifypem) +{ + struct tap_socket* s = calloc(1, sizeof(*s)); + if(!s) { + log_err("malloc failure"); + return NULL; + } + s->ip = strdup(ip); + if(!s->ip) { + free(s); + log_err("malloc failure"); + return NULL; + } + s->fd = -1; + s->ev_cb = ev_cb; + s->data = data; + s->sslctx = listen_sslctx_create(server_key, server_cert, verifypem); + return s; +} + /** setup tcp accept socket on IP string */ static int make_tcp_accept(char* ip) { @@ -296,40 +328,26 @@ static int tap_socket_setup(struct tap_socket* s, struct ub_event_base* base) log_err("could not create local socket"); return 0; } - s->ev = ub_event_new(base, s->fd, UB_EV_READ | UB_EV_PERSIST, - s->ev_cb, s); - if(!s->ev) { - log_err("could not ub_event_new"); - return 0; - } - if(ub_event_add(s->ev, NULL) != 0) { - log_err("could not ub_event_add"); - return 0; - } - s->ev_added = 1; - return 1; - } - if(s->ip) { + } else if(s->ip || s->sslctx) { /* TCP accept socket */ s->fd = make_tcp_accept(s->ip); if(s->fd == -1) { log_err("could not create tcp socket"); return 0; } - s->ev = ub_event_new(base, s->fd, UB_EV_READ | UB_EV_PERSIST, - s->ev_cb, s); - if(!s->ev) { - log_err("could not ub_event_new"); - return 0; - } - if(ub_event_add(s->ev, NULL) != 0) { - log_err("could not ub_event_add"); - return 0; - } - s->ev_added = 1; - return 1; } - return 0; + s->ev = ub_event_new(base, s->fd, UB_EV_READ | UB_EV_PERSIST, + s->ev_cb, s); + if(!s->ev) { + log_err("could not ub_event_new"); + return 0; + } + if(ub_event_add(s->ev, NULL) != 0) { + log_err("could not ub_event_add"); + return 0; + } + s->ev_added = 1; + return 1; } /** add tap socket to list */ @@ -675,6 +693,7 @@ void tap_data_free(struct tap_data* data) { ub_event_del(data->ev); ub_event_free(data->ev); + SSL_free(data->ssl); close(data->fd); free(data->frame); free(data); @@ -850,6 +869,21 @@ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) } +/** setup SSL connection to the client */ +static SSL* +setup_ssl(int s, SSL_CTX* ctx) +{ + SSL* ssl = SSL_new(ctx); + if(!ssl) return NULL; + SSL_set_accept_state(ssl); + (void)SSL_set_mode(ssl, (long)SSL_MODE_AUTO_RETRY); + if(!SSL_set_fd(ssl, s)) { + SSL_free(ssl); + return NULL; + } + return ssl; +} + /** callback for main listening file descriptor */ void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) { @@ -914,6 +948,10 @@ void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) data = calloc(1, sizeof(*data)); if(!data) fatal_exit("out of memory"); data->fd = s; + if(tap_sock->sslctx) { + data->ssl = setup_ssl(data->fd, tap_sock->sslctx); + if(!data->ssl) fatal_exit("could not SSL_new"); + } data->ev = ub_event_new(maindata->base, s, UB_EV_READ | UB_EV_PERSIST, &tap_callback, data); if(!data->ev) fatal_exit("could not ub_event_new"); @@ -950,6 +988,22 @@ static void setup_tcp_list(struct main_tap_data* maindata, } } +/** setup tls accept sockets */ +static void setup_tls_list(struct main_tap_data* maindata, + struct config_strlist_head* tls_list, char* server_key, + char* server_cert, char* verifypem) +{ + struct config_strlist* item; + for(item = tls_list->first; item; item = item->next) { + struct tap_socket* s; + s = tap_socket_new_tlsaccept(item->str, &mainfdcallback, + maindata, server_key, server_cert, verifypem); + if(!s) fatal_exit("out of memory"); + if(!tap_socket_list_insert(&maindata->acceptlist, s)) + fatal_exit("out of memory"); + } +} + /** signal variable */ static struct ub_event_base* sig_base = NULL; /** do we have to quit */ @@ -966,7 +1020,9 @@ static RETSIGTYPE main_sigh(int sig) /** setup and run the server to listen to DNSTAP messages */ static void setup_and_run(struct config_strlist_head* local_list, - struct config_strlist_head* tcp_list) + struct config_strlist_head* tcp_list, + struct config_strlist_head* tls_list, char* server_key, + char* server_cert, char* verifypem) { time_t secs = 0; struct timeval now; @@ -991,6 +1047,8 @@ setup_and_run(struct config_strlist_head* local_list, setup_local_list(maindata, local_list); setup_tcp_list(maindata, tcp_list); + setup_tls_list(maindata, tls_list, server_key, server_cert, + verifypem); if(!tap_socket_list_addevs(maindata->acceptlist, base)) fatal_exit("could not setup accept events"); @@ -1014,6 +1072,8 @@ int main(int argc, char** argv) int usessl = 0; struct config_strlist_head local_list; struct config_strlist_head tcp_list; + struct config_strlist_head tls_list; + char* server_key = NULL, *server_cert = NULL, *verifypem = NULL; #ifdef USE_WINSOCK WSADATA wsa_data; if(WSAStartup(MAKEWORD(2,2), &wsa_data) != 0) { @@ -1035,6 +1095,7 @@ int main(int argc, char** argv) fatal_exit("could not bind to signal"); memset(&local_list, 0, sizeof(local_list)); memset(&tcp_list, 0, sizeof(tcp_list)); + memset(&tls_list, 0, sizeof(tls_list)); /* lock debug start (if any) */ log_ident_set("unbound-dnstap-socket"); @@ -1049,7 +1110,7 @@ int main(int argc, char** argv) #endif /* command line options */ - while( (c=getopt(argc, argv, "hls:u:v")) != -1) { + while( (c=getopt(argc, argv, "hls:u:vx:y:z:")) != -1) { switch(c) { case 'u': if(!cfg_strlist_append(&local_list, @@ -1061,6 +1122,18 @@ int main(int argc, char** argv) strdup(optarg))) fatal_exit("out of memory"); break; + case 'x': + server_key = optarg; + usessl = 1; + break; + case 'y': + server_cert = optarg; + usessl = 1; + break; + case 'z': + verifypem = optarg; + usessl = 1; + break; case 'l': longformat = 1; break; @@ -1095,9 +1168,11 @@ int main(int argc, char** argv) (void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); #endif } - setup_and_run(&local_list, &tcp_list); + setup_and_run(&local_list, &tcp_list, &tls_list, server_key, + server_cert, verifypem); config_delstrlist(local_list.first); config_delstrlist(tcp_list.first); + config_delstrlist(tls_list.first); checklock_stop(); #ifdef USE_WINSOCK From b912169f1524d04e2f6de3baf530f7d8e69d6716 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 31 Jan 2020 11:11:43 +0100 Subject: [PATCH 52/96] dnstap unbound-dnstap-sock, fixup check for ssl context create error. --- dnstap/unbound-dnstap-socket.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index 3c5bcbcda..cbb04a1c2 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -241,6 +241,12 @@ static struct tap_socket* tap_socket_new_tlsaccept(char* ip, s->ev_cb = ev_cb; s->data = data; s->sslctx = listen_sslctx_create(server_key, server_cert, verifypem); + if(!s->sslctx) { + log_err("could not create ssl context"); + free(s->ip); + free(s); + return NULL; + } return s; } From 8d2ff8a6bf6634deb323876fa5fe251507fb37a9 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 31 Jan 2020 11:18:14 +0100 Subject: [PATCH 53/96] dnstap unbound-dnstap-sock, add -t option. --- dnstap/unbound-dnstap-socket.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index cbb04a1c2..c5ac4be3f 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -1116,7 +1116,7 @@ int main(int argc, char** argv) #endif /* command line options */ - while( (c=getopt(argc, argv, "hls:u:vx:y:z:")) != -1) { + while( (c=getopt(argc, argv, "hls:t:u:vx:y:z:")) != -1) { switch(c) { case 'u': if(!cfg_strlist_append(&local_list, @@ -1128,6 +1128,12 @@ int main(int argc, char** argv) strdup(optarg))) fatal_exit("out of memory"); break; + case 't': + if(!cfg_strlist_append(&tls_list, + strdup(optarg))) + fatal_exit("out of memory"); + usessl = 1; + break; case 'x': server_key = optarg; usessl = 1; From 03db238a51bf8997cb69df5bf9643d42d47e12cb Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 31 Jan 2020 13:05:06 +0100 Subject: [PATCH 54/96] dnstap unbound-dnstap-sock, verbose accepted stream IP addresses --- dnstap/unbound-dnstap-socket.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index c5ac4be3f..e634773a8 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -107,6 +107,8 @@ struct tap_data { struct ub_event* ev; /** the SSL for TLS streams */ SSL* ssl; + /** string that identifies the socket (or NULL), like IP address */ + char* id; /** have we read the length, and how many bytes of it */ int len_done; /** have we read the data, and how many bytes of it */ @@ -664,12 +666,13 @@ static void log_data_frame(uint8_t* pkt, size_t len) /** receive bytes from fd, prints errors if bad, * returns 0: closed/error, -1: continue, >0 number of bytes */ -static ssize_t receive_bytes(int fd, void* buf, size_t len, struct ub_event* ev) +static ssize_t receive_bytes(struct tap_data* data, int fd, void* buf, size_t len, struct ub_event* ev) { ssize_t ret = recv(fd, buf, len, 0); if(ret == 0) { /* closed */ - if(verbosity) log_info("dnstap client stream closed"); + if(verbosity) log_info("dnstap client stream closed from %s", + (data->id?data->id:"")); return 0; } else if(ret == -1) { /* error */ @@ -688,7 +691,8 @@ static ssize_t receive_bytes(int fd, void* buf, size_t len, struct ub_event* ev) log_err("could not recv: %s", wsa_strerror(WSAGetLastError())); #endif - if(verbosity) log_info("dnstap client stream closed"); + if(verbosity) log_info("dnstap client stream closed from %s", + (data->id?data->id:"")); return 0; } return ret; @@ -701,6 +705,7 @@ void tap_data_free(struct tap_data* data) ub_event_free(data->ev); SSL_free(data->ssl); close(data->fd); + free(data->id); free(data->frame); free(data); } @@ -791,7 +796,7 @@ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) if(verbosity>=3) log_info("tap callback"); while(data->len_done < 4) { uint32_t l = (uint32_t)data->len; - ssize_t ret = receive_bytes(fd, + ssize_t ret = receive_bytes(data, fd, ((uint8_t*)&l)+data->len_done, 4-data->len_done, data->ev); if(verbosity>=4) log_info("s recv %d", (int)ret); @@ -827,7 +832,7 @@ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) /* we want to read the full length now */ if(data->data_done < data->len) { - ssize_t r = receive_bytes(fd, data->frame + data->data_done, + ssize_t r = receive_bytes(data, fd, data->frame + data->data_done, data->len - data->data_done, data->ev); if(verbosity>=4) log_info("f recv %d", (int)r); if(r == 0) { @@ -897,6 +902,7 @@ void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) struct main_tap_data* maindata = (struct main_tap_data*) tap_sock->data; struct tap_data* data; + char* id = NULL; struct sockaddr_storage addr; socklen_t addrlen = (socklen_t)sizeof(addr); int s = accept(fd, (struct sockaddr*)&addr, &addrlen); @@ -938,6 +944,7 @@ void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) socklen_t ulen = sizeof(struct sockaddr_un); if(getsockname(fd, (struct sockaddr*)usock, &ulen) != -1) { log_info("accepted new dnstap client from %s", usock->sun_path); + id = strdup(usock->sun_path); } else { log_info("accepted new dnstap client"); } @@ -946,6 +953,12 @@ void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) log_info("accepted new dnstap client"); } #endif /* HAVE_SYS_UN_H */ + } else if(addr.ss_family == AF_INET || + addr.ss_family == AF_INET6) { + char ip[256]; + addr_to_str(&addr, addrlen, ip, sizeof(ip)); + log_info("accepted new dnstap client from %s", ip); + id = strdup(ip); } else { log_info("accepted new dnstap client"); } @@ -954,6 +967,7 @@ void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) data = calloc(1, sizeof(*data)); if(!data) fatal_exit("out of memory"); data->fd = s; + data->id = id; if(tap_sock->sslctx) { data->ssl = setup_ssl(data->fd, tap_sock->sslctx); if(!data->ssl) fatal_exit("could not SSL_new"); From dc31cf36523be5d5758ea7b2dc8f5d3f34724356 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 31 Jan 2020 14:03:28 +0100 Subject: [PATCH 55/96] dnstap unbound-dnstap-sock, read from TLS. --- dnstap/unbound-dnstap-socket.c | 197 ++++++++++++++++++++++++++------- util/netevent.c | 2 +- util/netevent.h | 5 + 3 files changed, 162 insertions(+), 42 deletions(-) diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index e634773a8..9e28b85d7 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -107,6 +107,10 @@ struct tap_data { struct ub_event* ev; /** the SSL for TLS streams */ SSL* ssl; + /** is the ssl handshake done */ + int ssl_handshake_done; + /** we are briefly waiting to write (in the struct event) */ + int ssl_brief_write; /** string that identifies the socket (or NULL), like IP address */ char* id; /** have we read the length, and how many bytes of it */ @@ -666,7 +670,8 @@ static void log_data_frame(uint8_t* pkt, size_t len) /** receive bytes from fd, prints errors if bad, * returns 0: closed/error, -1: continue, >0 number of bytes */ -static ssize_t receive_bytes(struct tap_data* data, int fd, void* buf, size_t len, struct ub_event* ev) +static ssize_t receive_bytes(struct tap_data* data, int fd, void* buf, + size_t len) { ssize_t ret = recv(fd, buf, len, 0); if(ret == 0) { @@ -677,7 +682,6 @@ static ssize_t receive_bytes(struct tap_data* data, int fd, void* buf, size_t le } else if(ret == -1) { /* error */ #ifndef USE_WINSOCK - (void)ev; if(errno == EINTR || errno == EAGAIN) return -1; log_err("could not recv: %s", strerror(errno)); @@ -685,7 +689,7 @@ static ssize_t receive_bytes(struct tap_data* data, int fd, void* buf, size_t le if(WSAGetLastError() == WSAEINPROGRESS) return -1; if(WSAGetLastError() == WSAEWOULDBLOCK) { - ub_winsock_tcp_wouldblock(ev, UB_EV_READ); + ub_winsock_tcp_wouldblock(data->ev, UB_EV_READ); return -1; } log_err("could not recv: %s", @@ -698,6 +702,74 @@ static ssize_t receive_bytes(struct tap_data* data, int fd, void* buf, size_t le return ret; } +/** set to wait briefly for a write event, for one event call */ +static void tap_enable_brief_write(struct tap_data* data) +{ + ub_event_del(data->ev); + ub_event_del_bits(data->ev, UB_EV_READ); + ub_event_add_bits(data->ev, UB_EV_WRITE); + if(ub_event_add(data->ev, NULL) != 0) + log_err("could not ub_event_add in tap_enable_brief_write"); + data->ssl_brief_write = 1; +} + +/** stop the brief wait for a write event. back to reading. */ +static void tap_disable_brief_write(struct tap_data* data) +{ + ub_event_del(data->ev); + ub_event_del_bits(data->ev, UB_EV_WRITE); + ub_event_add_bits(data->ev, UB_EV_READ); + if(ub_event_add(data->ev, NULL) != 0) + log_err("could not ub_event_add in tap_disable_brief_write"); + data->ssl_brief_write = 0; +} + +/** receive bytes over ssl stream, prints errors if bad, + * returns 0: closed/error, -1: continue, >0 number of bytes */ +static ssize_t ssl_read_bytes(struct tap_data* data, void* buf, size_t len) +{ + int r; + ERR_clear_error(); + r = SSL_read(data->ssl, buf, len); + if(r <= 0) { + int want = SSL_get_error(data->ssl, r); + if(want == SSL_ERROR_ZERO_RETURN) { + /* closed */ + if(verbosity) log_info("dnstap client stream closed from %s", + (data->id?data->id:"")); + return 0; + } else if(want == SSL_ERROR_WANT_READ) { + /* continue later */ + return -1; + } else if(want == SSL_ERROR_WANT_WRITE) { + /* set to briefly write */ + tap_enable_brief_write(data); + return -1; + } else if(want == SSL_ERROR_SYSCALL) { +#ifdef ECONNRESET + if(errno == ECONNRESET && verbosity < 2) + return 0; /* silence reset by peer */ +#endif + if(errno != 0) + log_err("SSL_read syscall: %s", + strerror(errno)); + return 0; + } + log_crypto_err("could not SSL_read"); + return 0; + } + return r; +} + +/** receive bytes on the tap connection, prints errors if bad, + * returns 0: closed/error, -1: continue, >0 number of bytes */ +static ssize_t tap_receive(struct tap_data* data, void* buf, size_t len) +{ + if(data->ssl) + return ssl_read_bytes(data, buf, len); + return receive_bytes(data, data->fd, buf, len); +} + /** delete the tap structure */ void tap_data_free(struct tap_data* data) { @@ -789,16 +861,74 @@ static int reply_with_finish(int fd) return 1; } +/** perform SSL handshake, return 0 to wait for events, 1 to continue */ +static int tap_handshake(struct tap_data* data) +{ + int r; + if(data->ssl_brief_write) { + /* write condition has been satisfied, back to reading */ + tap_disable_brief_write(data); + } + if(data->ssl_handshake_done) + return 1; + + ERR_clear_error(); + r = SSL_do_handshake(data->ssl); + if(r != 1) { + int want = SSL_get_error(data->ssl, r); + if(want == SSL_ERROR_WANT_READ) { + return 0; + } else if(want == SSL_ERROR_WANT_WRITE) { + tap_enable_brief_write(data); + return 0; + } else if(r == 0) { + /* closed */ + tap_data_free(data); + return 0; + } else if(want == SSL_ERROR_SYSCALL) { + /* SYSCALL and errno==0 means closed uncleanly */ +#ifdef EPIPE + if(errno == EPIPE && verbosity < 2) + return 0; /* silence 'broken pipe' */ +#endif +#ifdef ECONNRESET + if(errno == ECONNRESET && verbosity < 2) + return 0; /* silence reset by peer */ +#endif + if(errno != 0) + log_err("SSL_handshake syscall: %s", + strerror(errno)); + tap_data_free(data); + return 0; + } else { + unsigned long err = ERR_get_error(); + if(!squelch_err_ssl_handshake(err)) { + log_crypto_err_code("ssl handshake failed", + err); + verbose(VERB_OPS, "ssl handshake failed " + "from %s", data->id); + } + } + } + /* check peer verification */ + data->ssl_handshake_done = 1; + return 1; +} + /** callback for dnstap listener */ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) { struct tap_data* data = (struct tap_data*)arg; if(verbosity>=3) log_info("tap callback"); + if(data->ssl && (!data->ssl_handshake_done || + data->ssl_brief_write)) { + if(!tap_handshake(data)) + return; + } while(data->len_done < 4) { uint32_t l = (uint32_t)data->len; - ssize_t ret = receive_bytes(data, fd, - ((uint8_t*)&l)+data->len_done, 4-data->len_done, - data->ev); + ssize_t ret = tap_receive(data, + ((uint8_t*)&l)+data->len_done, 4-data->len_done); if(verbosity>=4) log_info("s recv %d", (int)ret); if(ret == 0) { /* closed or error */ @@ -832,8 +962,8 @@ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) /* we want to read the full length now */ if(data->data_done < data->len) { - ssize_t r = receive_bytes(data, fd, data->frame + data->data_done, - data->len - data->data_done, data->ev); + ssize_t r = tap_receive(data, data->frame + data->data_done, + data->len - data->data_done); if(verbosity>=4) log_info("f recv %d", (int)r); if(r == 0) { /* closed or error */ @@ -880,21 +1010,6 @@ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) } -/** setup SSL connection to the client */ -static SSL* -setup_ssl(int s, SSL_CTX* ctx) -{ - SSL* ssl = SSL_new(ctx); - if(!ssl) return NULL; - SSL_set_accept_state(ssl); - (void)SSL_set_mode(ssl, (long)SSL_MODE_AUTO_RETRY); - if(!SSL_set_fd(ssl, s)) { - SSL_free(ssl); - return NULL; - } - return ssl; -} - /** callback for main listening file descriptor */ void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) { @@ -908,32 +1023,32 @@ void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) int s = accept(fd, (struct sockaddr*)&addr, &addrlen); if(s == -1) { #ifndef USE_WINSOCK - /* EINTR is signal interrupt. others are closed connection. */ - if( errno == EINTR || errno == EAGAIN + /* EINTR is signal interrupt. others are closed connection. */ + if( errno == EINTR || errno == EAGAIN #ifdef EWOULDBLOCK - || errno == EWOULDBLOCK + || errno == EWOULDBLOCK #endif #ifdef ECONNABORTED - || errno == ECONNABORTED + || errno == ECONNABORTED #endif #ifdef EPROTO - || errno == EPROTO + || errno == EPROTO #endif /* EPROTO */ - ) - return; + ) + return; log_err_addr("accept failed", strerror(errno), &addr, addrlen); #else /* USE_WINSOCK */ - if(WSAGetLastError() == WSAEINPROGRESS || - WSAGetLastError() == WSAECONNRESET) - return; - if(WSAGetLastError() == WSAEWOULDBLOCK) { - ub_winsock_tcp_wouldblock(maindata->ev, UB_EV_READ); - return; - } - log_err_addr("accept failed", wsa_strerror(WSAGetLastError()), - &addr, addrlen); + if(WSAGetLastError() == WSAEINPROGRESS || + WSAGetLastError() == WSAECONNRESET) + return; + if(WSAGetLastError() == WSAEWOULDBLOCK) { + ub_winsock_tcp_wouldblock(maindata->ev, UB_EV_READ); + return; + } + log_err_addr("accept failed", wsa_strerror(WSAGetLastError()), + &addr, addrlen); #endif - return; + return; } fd_set_nonblock(s); if(verbosity) { @@ -969,7 +1084,7 @@ void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) data->fd = s; data->id = id; if(tap_sock->sslctx) { - data->ssl = setup_ssl(data->fd, tap_sock->sslctx); + data->ssl = incoming_ssl_fd(tap_sock->sslctx, data->fd); if(!data->ssl) fatal_exit("could not SSL_new"); } data->ev = ub_event_new(maindata->base, s, UB_EV_READ | UB_EV_PERSIST, diff --git a/util/netevent.c b/util/netevent.c index 9fe5da2d4..e334e5008 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -1054,7 +1054,7 @@ log_cert(unsigned level, const char* str, X509* cert) #ifdef HAVE_SSL /** true if the ssl handshake error has to be squelched from the logs */ -static int +int squelch_err_ssl_handshake(unsigned long err) { if(verbosity >= VERB_QUERY) diff --git a/util/netevent.h b/util/netevent.h index d80c72b33..60824fc42 100644 --- a/util/netevent.h +++ b/util/netevent.h @@ -786,4 +786,9 @@ void comm_point_tcp_win_bio_cb(struct comm_point* c, void* ssl); /** see if errno for tcp connect has to be logged or not. This uses errno */ int tcp_connect_errno_needs_log(struct sockaddr* addr, socklen_t addrlen); +#ifdef HAVE_SSL +/** true if the ssl handshake error has to be squelched from the logs */ +int squelch_err_ssl_handshake(unsigned long err); +#endif + #endif /* NET_EVENT_H */ From 27a5239ccf58568455501d5e1e0a6f047ae644da Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 31 Jan 2020 14:13:41 +0100 Subject: [PATCH 56/96] dnstap unbound-dnstap-sock, comments and log output on tls error close. --- dnstap/unbound-dnstap-socket.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index 9e28b85d7..011d015dc 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -753,9 +753,13 @@ static ssize_t ssl_read_bytes(struct tap_data* data, void* buf, size_t len) if(errno != 0) log_err("SSL_read syscall: %s", strerror(errno)); + if(verbosity) log_info("dnstap client stream closed from %s", + (data->id?data->id:"")); return 0; } log_crypto_err("could not SSL_read"); + if(verbosity) log_info("dnstap client stream closed from %s", + (data->id?data->id:"")); return 0; } return r; @@ -861,7 +865,7 @@ static int reply_with_finish(int fd) return 1; } -/** perform SSL handshake, return 0 to wait for events, 1 to continue */ +/** perform SSL handshake, return 0 to wait for events, 1 if done */ static int tap_handshake(struct tap_data* data) { int r; @@ -927,7 +931,7 @@ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) } while(data->len_done < 4) { uint32_t l = (uint32_t)data->len; - ssize_t ret = tap_receive(data, + ssize_t ret = tap_receive(data, ((uint8_t*)&l)+data->len_done, 4-data->len_done); if(verbosity>=4) log_info("s recv %d", (int)ret); if(ret == 0) { From 1420d59949b3bfd63b3f860a48d73030f2ea41a9 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 31 Jan 2020 17:07:40 +0100 Subject: [PATCH 57/96] dnstap io, connect and write over TCP. --- dnstap/dnstap.c | 5 +- dnstap/dtstream.c | 127 ++++++++++++++++++++++++++++++++++++++----- dnstap/dtstream.h | 3 +- testcode/testbound.c | 5 ++ 4 files changed, 125 insertions(+), 15 deletions(-) diff --git a/dnstap/dnstap.c b/dnstap/dnstap.c index 810f3200a..2787c73ec 100644 --- a/dnstap/dnstap.c +++ b/dnstap/dnstap.c @@ -149,7 +149,10 @@ dt_create(const char *socket_path, unsigned num_workers, free(env); return NULL; } - dt_io_thread_apply_cfg(env->dtio, cfg); + if(!dt_io_thread_apply_cfg(env->dtio, cfg)) { + free(env); + return NULL; + } dt_apply_cfg(env, cfg); return env; } diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index b734fc9c1..445de18b8 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -47,6 +47,7 @@ #include "util/config_file.h" #include "util/ub_event.h" #include "util/net_help.h" +#include "services/outside_network.h" #ifdef HAVE_SYS_UN_H #include #endif @@ -218,13 +219,25 @@ void dt_io_thread_delete(struct dt_io_thread* dtio) item = nextitem; } free(dtio->socket_path); + free(dtio->ip_str); free(dtio); } -void dt_io_thread_apply_cfg(struct dt_io_thread* dtio, struct config_file *cfg) +int dt_io_thread_apply_cfg(struct dt_io_thread* dtio, struct config_file *cfg) { - dtio->upstream_is_unix = 1; - dtio->socket_path = strdup(cfg->dnstap_socket_path); + /* + dtio->upstream_is_tcp = 1; + dtio->ip_str = strdup("127.0.0.1@1234"); + */ + if(cfg->dnstap_socket_path && cfg->dnstap_socket_path[0]) { + dtio->socket_path = strdup(cfg->dnstap_socket_path); + if(!dtio->socket_path) { + log_err("malloc failure"); + return 0; + } + dtio->upstream_is_unix = 1; + } + return 1; } int dt_io_thread_register_queue(struct dt_io_thread* dtio, @@ -477,6 +490,8 @@ static int dtio_check_nb_connect(struct dt_io_thread* dtio) #endif if(error != 0) { char* to = dtio->socket_path; + if(!to) to = dtio->ip_str; + if(!to) to = ""; #ifndef USE_WINSOCK log_err("dnstap io: failed to connect to \"%s\": %s", to, strerror(error)); @@ -487,7 +502,12 @@ static int dtio_check_nb_connect(struct dt_io_thread* dtio) return -1; /* error, close it */ } - verbose(VERB_ALGO, "dnstap io: connected to \"%s\"", dtio->socket_path); + if(dtio->ip_str) + verbose(VERB_DETAIL, "dnstap io: connected to %s", + dtio->ip_str); + else if(dtio->socket_path) + verbose(VERB_DETAIL, "dnstap io: connected to \"%s\"", + dtio->socket_path); dtio_reconnect_clear(dtio); dtio->check_nb_connect = 0; return 1; /* everything okay */ @@ -682,6 +702,9 @@ static int dtio_check_close(struct dt_io_thread* dtio) while(1) { r = recv(dtio->fd, (void*)buf, sizeof(buf), 0); if(r == -1) { + char* to = dtio->socket_path; + if(!to) to = dtio->ip_str; + if(!to) to = ""; #ifndef USE_WINSOCK if(errno == EINTR || errno == EAGAIN) return 1; /* try later */ @@ -696,12 +719,17 @@ static int dtio_check_close(struct dt_io_thread* dtio) return 1; /* try later */ } #endif - log_err("dnstap io: output recv: %s", strerror(errno)); + if(dtio->reconnect_timeout > DTIO_RECONNECT_TIMEOUT_MIN && verbosity < 4) + break; /* no log retries on low verbosity */ + log_err("dnstap io: output closed, recv %s: %s", to, + strerror(errno)); /* and close below */ break; } if(r == 0) { - verbose(VERB_ALGO, "dnstap io: output closed by the other side"); + if(dtio->reconnect_timeout > DTIO_RECONNECT_TIMEOUT_MIN && verbosity < 4) + break; /* no log retries on low verbosity */ + verbose(VERB_DETAIL, "dnstap io: output closed by the other side"); /* and close below */ break; } @@ -1131,11 +1159,10 @@ static int dtio_control_start_send(struct dt_io_thread* dtio) return 1; } -/** open the output file descriptor */ -static void dtio_open_output(struct dt_io_thread* dtio) +/** open the output file descriptor for af_local */ +static int dtio_open_output_local(struct dt_io_thread* dtio) { #ifdef HAVE_SYS_UN_H - struct ub_event* ev; struct sockaddr_un s; dtio->fd = socket(AF_LOCAL, SOCK_STREAM, 0); if(dtio->fd == -1) { @@ -1146,7 +1173,7 @@ static void dtio_open_output(struct dt_io_thread* dtio) log_err("dnstap io: failed to create socket: %s", wsa_strerror(WSAGetLastError())); #endif - return; + return 0; } memset(&s, 0, sizeof(s)); #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN @@ -1173,8 +1200,83 @@ static void dtio_open_output(struct dt_io_thread* dtio) closesocket(dtio->fd); #endif dtio->fd = -1; - dtio_reconnect_enable(dtio); - return; + return 0; + } + return 1; +#else + log_err("cannot create af_local socket"); + return 0; +#endif /* HAVE_SYS_UN_H */ +} + +/** open the output file descriptor for af_inet and af_inet6 */ +static int dtio_open_output_tcp(struct dt_io_thread* dtio) +{ + struct sockaddr_storage addr; + socklen_t addrlen; + memset(&addr, 0, sizeof(addr)); + addrlen = (socklen_t)sizeof(addr); + + if(!extstrtoaddr(dtio->ip_str, &addr, &addrlen)) { + log_err("could not parse IP '%s'", dtio->ip_str); + return 0; + } + dtio->fd = socket(addr.ss_family, SOCK_STREAM, 0); + if(dtio->fd == -1) { +#ifndef USE_WINSOCK + log_err("can't create socket: %s", strerror(errno)); +#else + log_err("can't create socket: %s", + wsa_strerror(WSAGetLastError())); +#endif + return 0; + } + fd_set_nonblock(dtio->fd); + if(connect(dtio->fd, (struct sockaddr*)&addr, addrlen) == -1) { + if(errno == EINPROGRESS) + return 1; /* wait until connect done*/ +#ifndef USE_WINSOCK + if(tcp_connect_errno_needs_log( + (struct sockaddr *)&addr, addrlen)) { + log_err("dnstap io: failed to connect to %s: %s", + dtio->ip_str, strerror(errno)); + } +#else + if(WSAGetLastError() == WSAEINPROGRESS || + WSAGetLastError() == WSAEWOULDBLOCK) + return 1; /* wait until connect done*/ + if(tcp_connect_errno_needs_log( + (struct sockaddr *)&addr, addrlen)) { + log_err("dnstap io: failed to connect to %s: %s", + dtio->ip_str, wsa_strerror(WSAGetLastError())); + } +#endif + +#ifndef USE_WINSOCK + close(dtio->fd); +#else + closesocket(dtio->fd); +#endif + dtio->fd = -1; + return 0; + } + return 1; +} + +/** open the output file descriptor */ +static void dtio_open_output(struct dt_io_thread* dtio) +{ + struct ub_event* ev; + if(dtio->upstream_is_unix) { + if(!dtio_open_output_local(dtio)) { + dtio_reconnect_enable(dtio); + return; + } + } else if(dtio->upstream_is_tcp || dtio->upstream_is_tls) { + if(!dtio_open_output_tcp(dtio)) { + dtio_reconnect_enable(dtio); + return; + } } dtio->check_nb_connect = 1; @@ -1209,7 +1311,6 @@ static void dtio_open_output(struct dt_io_thread* dtio) dtio_reconnect_enable(dtio); return; } -#endif /* HAVE_SYS_UN_H */ } /** perform the setup of the writer thread on the established event_base */ diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index f2c13fde4..8fa2352f4 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -228,8 +228,9 @@ void dt_io_thread_delete(struct dt_io_thread* dtio); * Apply config to the dtio thread * @param dtio: io thread, not yet started. * @param cfg: config file struct. + * @return false on malloc failure. */ -void dt_io_thread_apply_cfg(struct dt_io_thread* dtio, +int dt_io_thread_apply_cfg(struct dt_io_thread* dtio, struct config_file *cfg); /** diff --git a/testcode/testbound.c b/testcode/testbound.c index 4405231c0..fdbc0b92d 100644 --- a/testcode/testbound.c +++ b/testcode/testbound.c @@ -577,3 +577,8 @@ void wsvc_cron_cb(void* ATTR_UNUSED(arg)) } #endif /* UB_ON_WINDOWS */ +int tcp_connect_errno_needs_log(struct sockaddr* ATTR_UNUSED(addr), + socklen_t ATTR_UNUSED(addrlen)) +{ + return 1; +} From f24d0e4054f6bae93f75a61641a61b6edb61e6c8 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 4 Feb 2020 09:45:44 +0100 Subject: [PATCH 58/96] dnstap create debug tool with other debug tools in list. --- Makefile.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index 24f6f5059..2636ed4d2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -310,7 +310,8 @@ rsrc_unbound_checkconf.o: $(srcdir)/winrc/rsrc_unbound_checkconf.rc config.h TEST_BIN=asynclook$(EXEEXT) delayer$(EXEEXT) \ lock-verify$(EXEEXT) memstats$(EXEEXT) perf$(EXEEXT) \ petal$(EXEEXT) pktview$(EXEEXT) streamtcp$(EXEEXT) \ - testbound$(EXEEXT) unittest$(EXEEXT) unbound-dnstap-socket$(EXEEXT) + unbound-dnstap-socket$(EXEEXT) \ + testbound$(EXEEXT) unittest$(EXEEXT) tests: all $(TEST_BIN) check: test From 9f7a16c7ab6ba1076ab231a7bb3d0433143d3839 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 4 Feb 2020 17:23:19 +0100 Subject: [PATCH 59/96] dnstap io, ssl and ssl ctx creation. --- dnstap/dtstream.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++ dnstap/dtstream.h | 4 +++ 2 files changed, 81 insertions(+) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 445de18b8..50dcbc083 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -52,6 +52,12 @@ #include #endif #include +#ifdef HAVE_OPENSSL_SSL_H +#include +#endif +#ifdef HAVE_OPENSSL_ERR_H +#include +#endif /** number of messages to process in one output callback */ #define DTIO_MESSAGES_PER_CALLBACK 100 @@ -220,6 +226,14 @@ void dt_io_thread_delete(struct dt_io_thread* dtio) } free(dtio->socket_path); free(dtio->ip_str); + free(dtio->tls_server_name); + free(dtio->client_key_file); + free(dtio->client_cert_file); + if(dtio->ssl_ctx) { +#ifdef HAVE_SSL + SSL_CTX_free(dtio->ssl_ctx); +#endif + } free(dtio); } @@ -229,6 +243,30 @@ int dt_io_thread_apply_cfg(struct dt_io_thread* dtio, struct config_file *cfg) dtio->upstream_is_tcp = 1; dtio->ip_str = strdup("127.0.0.1@1234"); */ +#ifdef HAVE_SSL + dtio->upstream_is_tls = 1; + dtio->ip_str = strdup("127.0.0.1@1234"); + //dtio->tls_server_name; + dtio->use_client_certs = 0; + if(dtio->use_client_certs) { + //dtio->client_key_file = NULL; + //dtio->client_cert_file = NULL; + } else { + free(dtio->client_key_file); + dtio->client_key_file = NULL; + free(dtio->client_cert_file); + dtio->client_cert_file = NULL; + } + dtio->ssl_ctx = connect_sslctx_create(dtio->client_key_file, + dtio->client_cert_file, cfg->tls_cert_bundle, + cfg->tls_win_cert); + if(!dtio->ssl_ctx) { + log_err("could not setup SSL CTX"); + return 0; + } + /* DEBUG */ + return 1; +#endif if(cfg->dnstap_socket_path && cfg->dnstap_socket_path[0]) { dtio->socket_path = strdup(cfg->dnstap_socket_path); if(!dtio->socket_path) { @@ -442,6 +480,13 @@ static void dtio_close_output(struct dt_io_thread* dtio) return; ub_event_free(dtio->event); dtio->event = NULL; + if(dtio->ssl) { +#ifdef HAVE_SSL + SSL_shutdown(dtio->ssl); + SSL_free(dtio->ssl); + dtio->ssl = NULL; +#endif + } #ifndef USE_WINSOCK close(dtio->fd); #else @@ -1263,6 +1308,14 @@ static int dtio_open_output_tcp(struct dt_io_thread* dtio) return 1; } +/** setup the SSL structure for new connection */ +static int dtio_setup_ssl(struct dt_io_thread* dtio) +{ + dtio->ssl = outgoing_ssl_fd(dtio->ssl_ctx, dtio->fd); + if(!dtio->ssl) return 0; + return 1; +} + /** open the output file descriptor */ static void dtio_open_output(struct dt_io_thread* dtio) { @@ -1278,6 +1331,18 @@ static void dtio_open_output(struct dt_io_thread* dtio) return; } } + if(dtio->upstream_is_tls) { + if(!dtio_setup_ssl(dtio)) { +#ifndef USE_WINSOCK + close(dtio->fd); +#else + closesocket(dtio->fd); +#endif + dtio->fd = -1; + dtio_reconnect_enable(dtio); + return; + } + } dtio->check_nb_connect = 1; /* the EV_READ is to catch channel close, write to write packets */ @@ -1286,6 +1351,12 @@ static void dtio_open_output(struct dt_io_thread* dtio) dtio); if(!ev) { log_err("dnstap io: out of memory"); + if(dtio->ssl) { +#ifdef HAVE_SSL + SSL_free(dtio->ssl); + dtio->ssl = NULL; +#endif + } #ifndef USE_WINSOCK close(dtio->fd); #else @@ -1302,6 +1373,12 @@ static void dtio_open_output(struct dt_io_thread* dtio) log_err("dnstap io: out of memory"); ub_event_free(dtio->event); dtio->event = NULL; + if(dtio->ssl) { +#ifdef HAVE_SSL + SSL_free(dtio->ssl); + dtio->ssl = NULL; +#endif + } #ifndef USE_WINSOCK close(dtio->fd); #else diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 8fa2352f4..b388752d5 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -107,6 +107,8 @@ struct dt_io_thread { ub_thread_type tid; /** if the io processing has started */ int started; + /** ssl context for the io thread, for tls connections. type SSL_CTX* */ + void* ssl_ctx; /** file descriptor that the thread writes to */ int fd; @@ -118,6 +120,8 @@ struct dt_io_thread { int event_added_is_write; /** check for nonblocking connect errors on fd */ int check_nb_connect; + /** ssl for current connection, type SSL* */ + void* ssl; /** the buffer that currently getting written, or NULL if no * (partial) message written now */ From e5d43a6f4e133ba5fd650c95537e37a8643b11f8 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 5 Feb 2020 13:03:58 +0100 Subject: [PATCH 60/96] dnstap io, close fd routine. --- dnstap/dtstream.c | 54 +++++++++++++++-------------------------------- 1 file changed, 17 insertions(+), 37 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 50dcbc083..6e3ade352 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -473,6 +473,17 @@ static void dtio_del_output_event(struct dt_io_thread* dtio) dtio->event_added_is_write = 0; } +/** close dtio socket and set it to -1 */ +static void dtio_close_fd(struct dt_io_thread* dtio) +{ +#ifndef USE_WINSOCK + close(dtio->fd); +#else + closesocket(dtio->fd); +#endif + dtio->fd = -1; +} + /** close and stop the output file descriptor event */ static void dtio_close_output(struct dt_io_thread* dtio) { @@ -487,12 +498,7 @@ static void dtio_close_output(struct dt_io_thread* dtio) dtio->ssl = NULL; #endif } -#ifndef USE_WINSOCK - close(dtio->fd); -#else - closesocket(dtio->fd); -#endif - dtio->fd = -1; + dtio_close_fd(dtio); /* if there is a (partial) message, discard it * we cannot send (the remainder of) it, and a new @@ -1239,12 +1245,7 @@ static int dtio_open_output_local(struct dt_io_thread* dtio) log_err("dnstap io: failed to connect to \"%s\": %s", to, wsa_strerror(WSAGetLastError())); #endif -#ifndef USE_WINSOCK - close(dtio->fd); -#else - closesocket(dtio->fd); -#endif - dtio->fd = -1; + dtio_close_fd(dtio); return 0; } return 1; @@ -1296,13 +1297,7 @@ static int dtio_open_output_tcp(struct dt_io_thread* dtio) dtio->ip_str, wsa_strerror(WSAGetLastError())); } #endif - -#ifndef USE_WINSOCK - close(dtio->fd); -#else - closesocket(dtio->fd); -#endif - dtio->fd = -1; + dtio_close_fd(dtio); return 0; } return 1; @@ -1333,12 +1328,7 @@ static void dtio_open_output(struct dt_io_thread* dtio) } if(dtio->upstream_is_tls) { if(!dtio_setup_ssl(dtio)) { -#ifndef USE_WINSOCK - close(dtio->fd); -#else - closesocket(dtio->fd); -#endif - dtio->fd = -1; + dtio_close_fd(dtio); dtio_reconnect_enable(dtio); return; } @@ -1357,12 +1347,7 @@ static void dtio_open_output(struct dt_io_thread* dtio) dtio->ssl = NULL; #endif } -#ifndef USE_WINSOCK - close(dtio->fd); -#else - closesocket(dtio->fd); -#endif - dtio->fd = -1; + dtio_close_fd(dtio); dtio_reconnect_enable(dtio); return; } @@ -1379,12 +1364,7 @@ static void dtio_open_output(struct dt_io_thread* dtio) dtio->ssl = NULL; #endif } -#ifndef USE_WINSOCK - close(dtio->fd); -#else - closesocket(dtio->fd); -#endif - dtio->fd = -1; + dtio_close_fd(dtio); dtio_reconnect_enable(dtio); return; } From 5b117c851ae4087156db3c001c02a0bc9546e284 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 5 Feb 2020 13:59:56 +0100 Subject: [PATCH 61/96] dnstap io, ssl handshake. --- dnstap/dtstream.c | 211 ++++++++++++++++++++++++++++----- dnstap/dtstream.h | 6 + dnstap/unbound-dnstap-socket.c | 11 +- testcode/testbound.c | 5 + 4 files changed, 198 insertions(+), 35 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 6e3ade352..5db9d602a 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -66,6 +66,7 @@ /** the msec to wait for reconnect max after backoff */ #define DTIO_RECONNECT_TIMEOUT_MAX 1000 +struct stop_flush_info; /** DTIO command channel commands */ enum { /** DTIO command channel stop */ @@ -77,9 +78,11 @@ enum { /** open the output channel */ static void dtio_open_output(struct dt_io_thread* dtio); /** add output event for read and write */ -static void dtio_add_output_event_write(struct dt_io_thread* dtio); +static int dtio_add_output_event_write(struct dt_io_thread* dtio); /** start reconnection attempts */ static void dtio_reconnect_enable(struct dt_io_thread* dtio); +/** stop from stop_flush event loop */ +static void dtio_stop_flush_exit(struct stop_flush_info* info); struct dt_msg_queue* dt_msg_queue_create(void) @@ -395,7 +398,8 @@ static void dtio_reconnect_timeout_cb(int ATTR_UNUSED(fd), dtio_open_output(dtio); if(dtio->event) { - dtio_add_output_event_write(dtio); + if(!dtio_add_output_event_write(dtio)) + return; /* nothing wrong so far, wait on the output event */ return; } @@ -573,14 +577,6 @@ static int dtio_write_buf(struct dt_io_thread* dtio, uint8_t* buf, ssize_t ret; if(dtio->fd == -1) return -1; - if(dtio->check_nb_connect) { - int connect_err = dtio_check_nb_connect(dtio); - if(connect_err == -1) { - return -1; - } else if(connect_err == 0) { - return 0; - } - } ret = send(dtio->fd, (void*)buf, len, 0); if(ret == -1) { #ifndef USE_WINSOCK @@ -612,17 +608,6 @@ static int dtio_write_with_writev(struct dt_io_thread* dtio) uint32_t sendlen = htonl(dtio->cur_msg_len); struct iovec iov[2]; ssize_t r; - if(dtio->check_nb_connect) { - int connect_err = dtio_check_nb_connect(dtio); - if(connect_err == -1) { - /* close the channel */ - dtio_del_output_event(dtio); - dtio_close_output(dtio); - return 0; - } else if(connect_err == 0) { - return 0; - } - } iov[0].iov_base = ((uint8_t*)&sendlen)+dtio->cur_msg_len_done; iov[0].iov_len = sizeof(sendlen)-dtio->cur_msg_len_done; iov[1].iov_base = dtio->cur_msg; @@ -794,12 +779,12 @@ static int dtio_check_close(struct dt_io_thread* dtio) } /** add the output file descriptor event for listening, read only */ -static void dtio_add_output_event_read(struct dt_io_thread* dtio) +static int dtio_add_output_event_read(struct dt_io_thread* dtio) { if(!dtio->event) - return; + return 0; if(dtio->event_added && !dtio->event_added_is_write) - return; + return 1; /* we have to (re-)register the event */ if(dtio->event_added) ub_event_del(dtio->event); @@ -810,19 +795,20 @@ static void dtio_add_output_event_read(struct dt_io_thread* dtio) dtio->event_added_is_write = 0; /* close output and start reattempts to open it */ dtio_close_output(dtio); - return; + return 0; } dtio->event_added = 1; dtio->event_added_is_write = 0; + return 1; } /** add the output file descriptor event for listening, read and write */ -static void dtio_add_output_event_write(struct dt_io_thread* dtio) +static int dtio_add_output_event_write(struct dt_io_thread* dtio) { if(!dtio->event) - return; + return 0; if(dtio->event_added && dtio->event_added_is_write) - return; + return 1; /* we have to (re-)register the event */ if(dtio->event_added) ub_event_del(dtio->event); @@ -833,10 +819,11 @@ static void dtio_add_output_event_write(struct dt_io_thread* dtio) dtio->event_added_is_write = 0; /* close output and start reattempts to open it */ dtio_close_output(dtio); - return; + return 0; } dtio->event_added = 1; dtio->event_added_is_write = 1; + return 1; } /** put the dtio thread to sleep */ @@ -844,7 +831,117 @@ static void dtio_sleep(struct dt_io_thread* dtio) { /* unregister the event polling for write, because there is * nothing to be written */ - dtio_add_output_event_read(dtio); + (void)dtio_add_output_event_read(dtio); +} + +/** enable the brief read condition */ +static int dtio_enable_brief_read(struct dt_io_thread* dtio) +{ + dtio->ssl_brief_read = 1; + if(dtio->stop_flush_event) { + ub_event_del(dtio->stop_flush_event); + ub_event_del_bits(dtio->stop_flush_event, UB_EV_WRITE); + if(ub_event_add(dtio->stop_flush_event, NULL) != 0) { + log_err("dnstap io, stop flush, could not ub_event_add"); + return 0; + } + return 1; + } + return dtio_add_output_event_read(dtio); +} + +/** disable the brief read condition */ +static int dtio_disable_brief_read(struct dt_io_thread* dtio) +{ + dtio->ssl_brief_read = 0; + if(dtio->stop_flush_event) { + ub_event_del(dtio->stop_flush_event); + ub_event_add_bits(dtio->stop_flush_event, UB_EV_WRITE); + if(ub_event_add(dtio->stop_flush_event, NULL) != 0) { + log_err("dnstap io, stop flush, could not ub_event_add"); + return 0; + } + return 1; + } + return dtio_add_output_event_write(dtio); +} + +/** perform ssl handshake, returns 1 if okay, 0 to stop */ +static int dtio_ssl_handshake(struct dt_io_thread* dtio, + struct stop_flush_info* info) +{ + int r; + if(dtio->ssl_brief_read) { + /* assume the brief read condition is satisfied, + * if we need more or again, we can set it again */ + if(!dtio_disable_brief_read(dtio)) { + if(info) dtio_stop_flush_exit(info); + return 0; + } + } + if(dtio->ssl_handshake_done) + return 1; + + ERR_clear_error(); + r = SSL_do_handshake(dtio->ssl); + if(r != 1) { + int want = SSL_get_error(dtio->ssl, r); + if(want == SSL_ERROR_WANT_READ) { + /* we want to read on the connection */ + if(!dtio_enable_brief_read(dtio)) { + if(info) dtio_stop_flush_exit(info); + return 0; + } + return 0; + } else if(want == SSL_ERROR_WANT_WRITE) { + /* we want to write on the connection */ + return 0; + } else if(r == 0) { + /* closed */ + if(info) dtio_stop_flush_exit(info); + dtio_del_output_event(dtio); + dtio_close_output(dtio); + return 0; + } else if(want == SSL_ERROR_SYSCALL) { + /* SYSCALL and errno==0 means closed uncleanly */ + int silent = 0; +#ifdef EPIPE + if(errno == EPIPE && verbosity < 2) + silent = 1; /* silence 'broken pipe' */ +#endif +#ifdef ECONNRESET + if(errno == ECONNRESET && verbosity < 2) + silent = 1; /* silence reset by peer */ +#endif + if(errno == 0) + silent = 1; + if(!silent) + log_err("dnstap io, SSL_handshake syscall: %s", + strerror(errno)); + /* closed */ + if(info) dtio_stop_flush_exit(info); + dtio_del_output_event(dtio); + dtio_close_output(dtio); + return 0; + } else { + unsigned long err = ERR_get_error(); + if(!squelch_err_ssl_handshake(err)) { + log_crypto_err_code("dnstap io, ssl handshake failed", + err); + verbose(VERB_OPS, "dnstap io, ssl handshake failed " + "from %s", dtio->ip_str); + } + /* closed */ + if(info) dtio_stop_flush_exit(info); + dtio_del_output_event(dtio); + dtio_close_output(dtio); + return 0; + } + + } + /* check peer verification */ + dtio->ssl_handshake_done = 1; + return 1; } /** callback for the dnstap events, to write to the output */ @@ -853,6 +950,26 @@ static void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg) struct dt_io_thread* dtio = (struct dt_io_thread*)arg; int i; + if(dtio->check_nb_connect) { + int connect_err = dtio_check_nb_connect(dtio); + if(connect_err == -1) { + /* close the channel */ + dtio_del_output_event(dtio); + dtio_close_output(dtio); + return; + } else if(connect_err == 0) { + /* try again later */ + return; + } + /* nonblocking connect check passed, continue */ + } + + if(dtio->ssl && + (!dtio->ssl_handshake_done || dtio->ssl_brief_read)) { + if(!dtio_ssl_handshake(dtio, NULL)) + return; + } + if((bits&UB_EV_READ)) { if(!dtio_check_close(dtio)) return; @@ -919,7 +1036,8 @@ static void dtio_cmd_cb(int fd, short ATTR_UNUSED(bits), void* arg) } else if(r == 1 && cmd == DTIO_COMMAND_WAKEUP) { verbose(VERB_ALGO, "dnstap io: cmd channel cmd wakeup"); /* reregister event */ - dtio_add_output_event_write(dtio); + if(!dtio_add_output_event_write(dtio)) + return; return; } else if(r == 1) { verbose(VERB_ALGO, "dnstap io: cmd channel unknown command"); @@ -1045,6 +1163,28 @@ static void dtio_stop_ev_cb(int ATTR_UNUSED(fd), short bits, void* arg) struct dt_io_thread* dtio = info->dtio; if(info->want_to_exit_flush) return; + if(dtio->check_nb_connect) { + /* we don't start the stop_flush if connect still + * in progress, but the check code is here, just in case */ + int connect_err = dtio_check_nb_connect(dtio); + if(connect_err == -1) { + /* close the channel, exit the stop flush */ + dtio_stop_flush_exit(info); + dtio_del_output_event(dtio); + dtio_close_output(dtio); + return; + } else if(connect_err == 0) { + /* try again later */ + return; + } + /* nonblocking connect check passed, continue */ + } + if(dtio->ssl && + (!dtio->ssl_handshake_done || dtio->ssl_brief_read)) { + if(!dtio_ssl_handshake(dtio, info)) + return; + } + if((bits&UB_EV_READ)) { if(!dtio_check_close(dtio)) { if(dtio->fd == -1) { @@ -1098,6 +1238,10 @@ static void dtio_control_stop_flush(struct dt_io_thread* dtio) * sent yet, so nothing to stop or flush */ return; } + if(dtio->ssl && !dtio->ssl_handshake_done) { + /* no SSL connection has been established yet */ + return; + } memset(&info, 0, sizeof(info)); memset(&now, 0, sizeof(now)); @@ -1308,6 +1452,8 @@ static int dtio_setup_ssl(struct dt_io_thread* dtio) { dtio->ssl = outgoing_ssl_fd(dtio->ssl_ctx, dtio->fd); if(!dtio->ssl) return 0; + dtio->ssl_handshake_done = 0; + dtio->ssl_brief_read = 0; return 1; } @@ -1376,7 +1522,8 @@ static void dtio_setup_on_base(struct dt_io_thread* dtio) dtio_setup_cmd(dtio); dtio_setup_reconnect(dtio); dtio_open_output(dtio); - dtio_add_output_event_write(dtio); + if(!dtio_add_output_event_write(dtio)) + return; } #ifndef THREADS_DISABLED diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index b388752d5..bb6cebbe6 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -122,6 +122,12 @@ struct dt_io_thread { int check_nb_connect; /** ssl for current connection, type SSL* */ void* ssl; + /** true if the handshake for SSL is done, 0 if not */ + int ssl_handshake_done; + /** true if briefly the SSL wants a read event, 0 if not. + * This happens during negotiation, we then do not want to write, + * but wait for a read event. */ + int ssl_brief_read; /** the buffer that currently getting written, or NULL if no * (partial) message written now */ diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index 011d015dc..e5a52967a 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -891,15 +891,18 @@ static int tap_handshake(struct tap_data* data) return 0; } else if(want == SSL_ERROR_SYSCALL) { /* SYSCALL and errno==0 means closed uncleanly */ + int silent = 0; #ifdef EPIPE if(errno == EPIPE && verbosity < 2) - return 0; /* silence 'broken pipe' */ + silent = 1; /* silence 'broken pipe' */ #endif #ifdef ECONNRESET if(errno == ECONNRESET && verbosity < 2) - return 0; /* silence reset by peer */ + silent = 1; /* silence reset by peer */ #endif - if(errno != 0) + if(errno == 0) + silent = 1; + if(!silent) log_err("SSL_handshake syscall: %s", strerror(errno)); tap_data_free(data); @@ -912,6 +915,8 @@ static int tap_handshake(struct tap_data* data) verbose(VERB_OPS, "ssl handshake failed " "from %s", data->id); } + tap_data_free(data); + return 0; } } /* check peer verification */ diff --git a/testcode/testbound.c b/testcode/testbound.c index fdbc0b92d..602dffaff 100644 --- a/testcode/testbound.c +++ b/testcode/testbound.c @@ -582,3 +582,8 @@ int tcp_connect_errno_needs_log(struct sockaddr* ATTR_UNUSED(addr), { return 1; } + +int squelch_err_ssl_handshake(unsigned long ATTR_UNUSED(err)) +{ + return 0; +} From 812d8f71e8f9f369d8895a459099cc14c815d9ce Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 5 Feb 2020 15:04:04 +0100 Subject: [PATCH 62/96] dnstap io, ssl write. --- dnstap/dtstream.c | 60 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 5db9d602a..a33103ec1 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -83,6 +83,8 @@ static int dtio_add_output_event_write(struct dt_io_thread* dtio); static void dtio_reconnect_enable(struct dt_io_thread* dtio); /** stop from stop_flush event loop */ static void dtio_stop_flush_exit(struct stop_flush_info* info); +/** enable briefly waiting for a read event, for SSL negotiation */ +static int dtio_enable_brief_read(struct dt_io_thread* dtio); struct dt_msg_queue* dt_msg_queue_create(void) @@ -568,6 +570,48 @@ static int dtio_check_nb_connect(struct dt_io_thread* dtio) return 1; /* everything okay */ } +/** write to ssl output + * returns number of bytes written, 0 if nothing happened, + * try again later, or -1 if the channel is to be closed. */ +static int dtio_write_ssl(struct dt_io_thread* dtio, uint8_t* buf, + size_t len) +{ + int r; + ERR_clear_error(); + r = SSL_write(dtio->ssl, buf, len); + if(r <= 0) { + int want = SSL_get_error(dtio->ssl, r); + if(want == SSL_ERROR_ZERO_RETURN) { + /* closed */ + return -1; + } else if(want == SSL_ERROR_WANT_READ) { + /* we want a brief read event */ + dtio_enable_brief_read(dtio); + return 0; + } else if(want == SSL_ERROR_WANT_WRITE) { + /* write again later */ + return 0; + } else if(want == SSL_ERROR_SYSCALL) { +#ifdef EPIPE + if(errno == EPIPE && verbosity < 2) + return -1; /* silence 'broken pipe' */ +#endif +#ifdef ECONNRESET + if(errno == ECONNRESET && verbosity < 2) + return -1; /* silence reset by peer */ +#endif + if(errno != 0) { + log_err("dnstap io, SSL_write syscall: %s", + strerror(errno)); + } + return -1; + } + log_crypto_err("dnstap io, could not SSL_write"); + return -1; + } + return r; +} + /** write buffer to output. * returns number of bytes written, 0 if nothing happened, * try again later, or -1 if the channel is to be closed. */ @@ -577,6 +621,8 @@ static int dtio_write_buf(struct dt_io_thread* dtio, uint8_t* buf, ssize_t ret; if(dtio->fd == -1) return -1; + if(dtio->ssl) + return dtio_write_ssl(dtio, buf, len); ret = send(dtio->fd, (void*)buf, len, 0); if(ret == -1) { #ifndef USE_WINSOCK @@ -654,16 +700,17 @@ static int dtio_write_with_writev(struct dt_io_thread* dtio) * return true if message is done, false if incomplete. */ static int dtio_write_more_of_len(struct dt_io_thread* dtio) { -#ifndef HAVE_WRITEV - uint32_t sendlen = htonl(dtio->cur_msg_len); + uint32_t sendlen; int r; -#endif if(dtio->cur_msg_len_done >= 4) return 1; #ifdef HAVE_WRITEV - /* we try writev for everything.*/ - return dtio_write_with_writev(dtio); -#else + if(!dtio->ssl) { + /* we try writev for everything.*/ + return dtio_write_with_writev(dtio); + } +#endif /* HAVE_WRITEV */ + sendlen = htonl(dtio->cur_msg_len); r = dtio_write_buf(dtio, ((uint8_t*)&sendlen)+dtio->cur_msg_len_done, sizeof(sendlen)-dtio->cur_msg_len_done); @@ -680,7 +727,6 @@ static int dtio_write_more_of_len(struct dt_io_thread* dtio) if(dtio->cur_msg_len_done < 4) return 0; return 1; -#endif /* HAVE_WRITEV */ } /** write more of the data frame. From ad180402ea781e1209015255b3245f217f293058 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 5 Feb 2020 16:17:21 +0100 Subject: [PATCH 63/96] dnstap io, set tls auth name in outgoing ssl --- dnstap/dtstream.c | 4 ++++ services/outside_network.c | 44 ++++++-------------------------------- util/net_help.c | 34 +++++++++++++++++++++++++++++ util/net_help.h | 8 +++++++ 4 files changed, 52 insertions(+), 38 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index a33103ec1..0ea933dc9 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -1500,6 +1500,10 @@ static int dtio_setup_ssl(struct dt_io_thread* dtio) if(!dtio->ssl) return 0; dtio->ssl_handshake_done = 0; dtio->ssl_brief_read = 0; + + if(!set_auth_name_on_ssl(dtio->ssl, dtio->tls_server_name)) { + return 0; + } return 1; } diff --git a/services/outside_network.c b/services/outside_network.c index 9876c2150..612767056 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -373,45 +373,13 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len) comm_point_tcp_win_bio_cb(pend->c, pend->c->ssl); #endif pend->c->ssl_shake_state = comm_ssl_shake_write; - if(w->tls_auth_name) { -#ifdef HAVE_SSL - (void)SSL_set_tlsext_host_name(pend->c->ssl, w->tls_auth_name); -#endif + if(!set_auth_name_on_ssl(pend->c->ssl, w->tls_auth_name)) { + pend->c->fd = s; + SSL_free(pend->c->ssl); + pend->c->ssl = NULL; + comm_point_close(pend->c); + return 0; } -#ifdef HAVE_SSL_SET1_HOST - if(w->tls_auth_name) { - SSL_set_verify(pend->c->ssl, SSL_VERIFY_PEER, NULL); - /* setting the hostname makes openssl verify the - * host name in the x509 certificate in the - * SSL connection*/ - if(!SSL_set1_host(pend->c->ssl, w->tls_auth_name)) { - log_err("SSL_set1_host failed"); - pend->c->fd = s; - SSL_free(pend->c->ssl); - pend->c->ssl = NULL; - comm_point_close(pend->c); - return 0; - } - } -#elif defined(HAVE_X509_VERIFY_PARAM_SET1_HOST) - /* openssl 1.0.2 has this function that can be used for - * set1_host like verification */ - if(w->tls_auth_name) { - X509_VERIFY_PARAM* param = SSL_get0_param(pend->c->ssl); - X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); - if(!X509_VERIFY_PARAM_set1_host(param, w->tls_auth_name, strlen(w->tls_auth_name))) { - log_err("X509_VERIFY_PARAM_set1_host failed"); - pend->c->fd = s; - SSL_free(pend->c->ssl); - pend->c->ssl = NULL; - comm_point_close(pend->c); - return 0; - } - SSL_set_verify(pend->c->ssl, SSL_VERIFY_PEER, NULL); - } -#else - verbose(VERB_ALGO, "the query has an auth_name, but libssl has no call to perform TLS authentication"); -#endif /* HAVE_SSL_SET1_HOST */ } w->pkt = NULL; w->next_waiting = (void*)pend; diff --git a/util/net_help.c b/util/net_help.c index 0869f91f9..7e0a7ac08 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -1191,6 +1191,40 @@ void* outgoing_ssl_fd(void* sslctx, int fd) #endif } +/** set the authname on an SSL structure, SSL* ssl */ +int set_auth_name_on_ssl(void* ssl, char* auth_name) +{ + if(!auth_name) return 1; +#ifdef HAVE_SSL + (void)SSL_set_tlsext_host_name(ssl, auth_name); +#endif +#ifdef HAVE_SSL_SET1_HOST + SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL); + /* setting the hostname makes openssl verify the + * host name in the x509 certificate in the + * SSL connection*/ + if(!SSL_set1_host(ssl, auth_name)) { + log_err("SSL_set1_host failed"); + return 0; + } +#elif defined(HAVE_X509_VERIFY_PARAM_SET1_HOST) + /* openssl 1.0.2 has this function that can be used for + * set1_host like verification */ + if(auth_name) { + X509_VERIFY_PARAM* param = SSL_get0_param(ssl); + X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); + if(!X509_VERIFY_PARAM_set1_host(param, auth_name, strlen(auth_name))) { + log_err("X509_VERIFY_PARAM_set1_host failed"); + return 0; + } + SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL); + } +#else + verbose(VERB_ALGO, "the query has an auth_name, but libssl has no call to perform TLS authentication"); +#endif /* HAVE_SSL_SET1_HOST */ + return 1; +} + #if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L /** global lock list for openssl locks */ static lock_basic_type *ub_openssl_locks = NULL; diff --git a/util/net_help.h b/util/net_help.h index 7a33a7203..b621639c0 100644 --- a/util/net_help.h +++ b/util/net_help.h @@ -434,6 +434,14 @@ void* incoming_ssl_fd(void* sslctx, int fd); */ void* outgoing_ssl_fd(void* sslctx, int fd); +/** + * set auth name on SSL for verification + * @param ssl: SSL* to set + * @param auth_name: if NULL nothing happens, otherwise the name to check. + * @return 1 on success or NULL auth_name, 0 on failure. + */ +int set_auth_name_on_ssl(void* ssl, char* auth_name); + /** * Initialize openssl locking for thread safety * @return false on failure (alloc failure). From 25a88d6d54ba94f9024a0b6efa053d9ec1f6df58 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 12 Feb 2020 15:23:58 +0100 Subject: [PATCH 64/96] dnstap io, check peer verification in dtstream dtio_ssl_handshake. --- dnstap/dtstream.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++ util/net_help.c | 26 +++++++++++++++++++++++ util/net_help.h | 8 +++++++ util/netevent.c | 26 ----------------------- 4 files changed, 88 insertions(+), 26 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 0ea933dc9..067f4a2db 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -987,6 +987,60 @@ static int dtio_ssl_handshake(struct dt_io_thread* dtio, } /* check peer verification */ dtio->ssl_handshake_done = 1; + + if((SSL_get_verify_mode(dtio->ssl)&SSL_VERIFY_PEER)) { + /* verification */ + if(SSL_get_verify_result(dtio->ssl) == X509_V_OK) { + X509* x = SSL_get_peer_certificate(dtio->ssl); + if(!x) { + verbose(VERB_ALGO, "dnstap io, %s, SSL " + "connection failed no certificate", + dtio->ip_str); + /* closed */ + if(info) dtio_stop_flush_exit(info); + dtio_del_output_event(dtio); + dtio_close_output(dtio); + return 0; + } + log_cert(VERB_ALGO, "dnstap io, peer certificate", + x); +#ifdef HAVE_SSL_GET0_PEERNAME + if(SSL_get0_peername(dtio->ssl)) { + verbose(VERB_ALGO, "dnstap io, %s, SSL " + "connection to %s authenticated", + dtio->ip_str, + SSL_get0_peername(dtio->ssl)); + } else { +#endif + verbose(VERB_ALGO, "dnstap io, %s, SSL " + "connection authenticated", + dtio->ip_str); +#ifdef HAVE_SSL_GET0_PEERNAME + } +#endif + X509_free(x); + } else { + X509* x = SSL_get_peer_certificate(dtio->ssl); + if(x) { + log_cert(VERB_ALGO, "dnstap io, peer " + "certificate", x); + X509_free(x); + } + verbose(VERB_ALGO, "dnstap io, %s, SSL connection " + "failed: failed to authenticate", + dtio->ip_str); + /* closed */ + if(info) dtio_stop_flush_exit(info); + dtio_del_output_event(dtio); + dtio_close_output(dtio); + return 0; + } + } else { + /* unauthenticated, the verify peer flag was not set + * in ssl when the ssl object was created from ssl_ctx */ + verbose(VERB_ALGO, "dnstap io, %s, SSL connection", + dtio->ip_str); + } return 1; } diff --git a/util/net_help.c b/util/net_help.c index 7e0a7ac08..007eaff0b 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -829,6 +829,32 @@ void log_crypto_err_code(const char* str, unsigned long err) #endif /* HAVE_SSL */ } +#ifdef HAVE_SSL +/** log certificate details */ +void +log_cert(unsigned level, const char* str, void* cert) +{ + BIO* bio; + char nul = 0; + char* pp = NULL; + long len; + if(verbosity < level) return; + bio = BIO_new(BIO_s_mem()); + if(!bio) return; + X509_print_ex(bio, (X509*)cert, 0, (unsigned long)-1 + ^(X509_FLAG_NO_SUBJECT + |X509_FLAG_NO_ISSUER|X509_FLAG_NO_VALIDITY + |X509_FLAG_NO_EXTENSIONS|X509_FLAG_NO_AUX + |X509_FLAG_NO_ATTRIBUTES)); + BIO_write(bio, &nul, (int)sizeof(nul)); + len = BIO_get_mem_data(bio, &pp); + if(len != 0 && pp) { + verbose(level, "%s: \n%s", str, pp); + } + BIO_free(bio); +} +#endif /* HAVE_SSL */ + int listen_sslctx_setup(void* ctxt) { diff --git a/util/net_help.h b/util/net_help.h index b621639c0..6df9f9b39 100644 --- a/util/net_help.h +++ b/util/net_help.h @@ -385,6 +385,14 @@ void log_crypto_err(const char* str); */ void log_crypto_err_code(const char* str, unsigned long err); +/** + * Log certificate details verbosity, string, of X509 cert + * @param level: verbosity level + * @param str: string to prefix on output + * @param cert: X509* structure. + */ +void log_cert(unsigned level, const char* str, void* cert); + /** * Set SSL_OP_NOxxx options on SSL context to disable bad crypto * @param ctxt: SSL_CTX* diff --git a/util/netevent.c b/util/netevent.c index e334e5008..090238384 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -1026,32 +1026,6 @@ tcp_callback_reader(struct comm_point* c) } } -#ifdef HAVE_SSL -/** log certificate details */ -static void -log_cert(unsigned level, const char* str, X509* cert) -{ - BIO* bio; - char nul = 0; - char* pp = NULL; - long len; - if(verbosity < level) return; - bio = BIO_new(BIO_s_mem()); - if(!bio) return; - X509_print_ex(bio, cert, 0, (unsigned long)-1 - ^(X509_FLAG_NO_SUBJECT - |X509_FLAG_NO_ISSUER|X509_FLAG_NO_VALIDITY - |X509_FLAG_NO_EXTENSIONS|X509_FLAG_NO_AUX - |X509_FLAG_NO_ATTRIBUTES)); - BIO_write(bio, &nul, (int)sizeof(nul)); - len = BIO_get_mem_data(bio, &pp); - if(len != 0 && pp) { - verbose(level, "%s: \n%s", str, pp); - } - BIO_free(bio); -} -#endif /* HAVE_SSL */ - #ifdef HAVE_SSL /** true if the ssl handshake error has to be squelched from the logs */ int From 571426095375080d08716ba7ffbc727cc9358bf4 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 12 Feb 2020 15:34:56 +0100 Subject: [PATCH 65/96] dnstap io, move peer check into routine. --- dnstap/dtstream.c | 109 ++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 52 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 067f4a2db..3492c4380 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -912,6 +912,57 @@ static int dtio_disable_brief_read(struct dt_io_thread* dtio) return dtio_add_output_event_write(dtio); } +/** check peer verification after ssl handshake connection, false if closed*/ +static int dtio_ssl_check_peer(struct dt_io_thread* dtio) +{ + if((SSL_get_verify_mode(dtio->ssl)&SSL_VERIFY_PEER)) { + /* verification */ + if(SSL_get_verify_result(dtio->ssl) == X509_V_OK) { + X509* x = SSL_get_peer_certificate(dtio->ssl); + if(!x) { + verbose(VERB_ALGO, "dnstap io, %s, SSL " + "connection failed no certificate", + dtio->ip_str); + return 0; + } + log_cert(VERB_ALGO, "dnstap io, peer certificate", + x); +#ifdef HAVE_SSL_GET0_PEERNAME + if(SSL_get0_peername(dtio->ssl)) { + verbose(VERB_ALGO, "dnstap io, %s, SSL " + "connection to %s authenticated", + dtio->ip_str, + SSL_get0_peername(dtio->ssl)); + } else { +#endif + verbose(VERB_ALGO, "dnstap io, %s, SSL " + "connection authenticated", + dtio->ip_str); +#ifdef HAVE_SSL_GET0_PEERNAME + } +#endif + X509_free(x); + } else { + X509* x = SSL_get_peer_certificate(dtio->ssl); + if(x) { + log_cert(VERB_ALGO, "dnstap io, peer " + "certificate", x); + X509_free(x); + } + verbose(VERB_ALGO, "dnstap io, %s, SSL connection " + "failed: failed to authenticate", + dtio->ip_str); + return 0; + } + } else { + /* unauthenticated, the verify peer flag was not set + * in ssl when the ssl object was created from ssl_ctx */ + verbose(VERB_ALGO, "dnstap io, %s, SSL connection", + dtio->ip_str); + } + return 1; +} + /** perform ssl handshake, returns 1 if okay, 0 to stop */ static int dtio_ssl_handshake(struct dt_io_thread* dtio, struct stop_flush_info* info) @@ -988,58 +1039,12 @@ static int dtio_ssl_handshake(struct dt_io_thread* dtio, /* check peer verification */ dtio->ssl_handshake_done = 1; - if((SSL_get_verify_mode(dtio->ssl)&SSL_VERIFY_PEER)) { - /* verification */ - if(SSL_get_verify_result(dtio->ssl) == X509_V_OK) { - X509* x = SSL_get_peer_certificate(dtio->ssl); - if(!x) { - verbose(VERB_ALGO, "dnstap io, %s, SSL " - "connection failed no certificate", - dtio->ip_str); - /* closed */ - if(info) dtio_stop_flush_exit(info); - dtio_del_output_event(dtio); - dtio_close_output(dtio); - return 0; - } - log_cert(VERB_ALGO, "dnstap io, peer certificate", - x); -#ifdef HAVE_SSL_GET0_PEERNAME - if(SSL_get0_peername(dtio->ssl)) { - verbose(VERB_ALGO, "dnstap io, %s, SSL " - "connection to %s authenticated", - dtio->ip_str, - SSL_get0_peername(dtio->ssl)); - } else { -#endif - verbose(VERB_ALGO, "dnstap io, %s, SSL " - "connection authenticated", - dtio->ip_str); -#ifdef HAVE_SSL_GET0_PEERNAME - } -#endif - X509_free(x); - } else { - X509* x = SSL_get_peer_certificate(dtio->ssl); - if(x) { - log_cert(VERB_ALGO, "dnstap io, peer " - "certificate", x); - X509_free(x); - } - verbose(VERB_ALGO, "dnstap io, %s, SSL connection " - "failed: failed to authenticate", - dtio->ip_str); - /* closed */ - if(info) dtio_stop_flush_exit(info); - dtio_del_output_event(dtio); - dtio_close_output(dtio); - return 0; - } - } else { - /* unauthenticated, the verify peer flag was not set - * in ssl when the ssl object was created from ssl_ctx */ - verbose(VERB_ALGO, "dnstap io, %s, SSL connection", - dtio->ip_str); + if(!dtio_ssl_check_peer(dtio)) { + /* closed */ + if(info) dtio_stop_flush_exit(info); + dtio_del_output_event(dtio); + dtio_close_output(dtio); + return 0; } return 1; } From 76772fe786c8ef954b2f9510b079dca04895cf03 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 12 Feb 2020 16:49:18 +0100 Subject: [PATCH 66/96] dnstap io, check peer verification in unbound-dnstap-socket tap_handshake. --- dnstap/unbound-dnstap-socket.c | 51 ++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index e5a52967a..eda75e0c0 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -865,6 +865,52 @@ static int reply_with_finish(int fd) return 1; } +/** check SSL peer certificate, return 0 on fail */ +static int tap_check_peer(struct tap_data* data) +{ + if((SSL_get_verify_mode(data->ssl)&SSL_VERIFY_PEER)) { + /* verification */ + if(SSL_get_verify_result(data->ssl) == X509_V_OK) { + X509* x = SSL_get_peer_certificate(data->ssl); + if(!x) { + if(verbosity) log_info("SSL connection %s" + " failed no certificate", data->id); + return 0; + } + if(verbosity) + log_cert(VERB_ALGO, "peer certificate", x); +#ifdef HAVE_SSL_GET0_PEERNAME + if(SSL_get0_peername(data->ssl)) { + if(verbosity) log_info("SSL connection %s " + "to %s authenticated", data->id, + SSL_get0_peername(data->ssl)); + } else { +#endif + if(verbosity) log_info("SSL connection %s " + "authenticated", data->id); +#ifdef HAVE_SSL_GET0_PEERNAME + } +#endif + X509_free(x); + } else { + X509* x = SSL_get_peer_certificate(data->ssl); + if(x) { + if(verbosity) + log_cert(VERB_ALGO, "peer certificate", x); + X509_free(x); + } + if(verbosity) log_info("SSL connection %s failed: " + "failed to authenticate", data->id); + return 0; + } + } else { + /* unauthenticated, the verify peer flag was not set + * in ssl when the ssl object was created from ssl_ctx */ + if(verbosity) log_info("SSL connection %s", data->id); + } + return 1; +} + /** perform SSL handshake, return 0 to wait for events, 1 if done */ static int tap_handshake(struct tap_data* data) { @@ -921,6 +967,11 @@ static int tap_handshake(struct tap_data* data) } /* check peer verification */ data->ssl_handshake_done = 1; + if(!tap_check_peer(data)) { + /* closed */ + tap_data_free(data); + return 0; + } return 1; } From 78e6060858fb189cf77e3a618d8cd0de880c2c6e Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 14 Feb 2020 09:03:09 +0100 Subject: [PATCH 67/96] dnstap io, example.conf example, config_file entries for tcp and tls. --- configure | 3 ++ configure.ac | 1 + dnstap/dtstream.c | 126 +++++++++++++++++++++++++++++++++----------- doc/example.conf.in | 32 +++++++++++ util/config_file.c | 20 +++++++ util/config_file.h | 12 +++++ 6 files changed, 163 insertions(+), 31 deletions(-) diff --git a/configure b/configure index e013dc5de..d66138c22 100755 --- a/configure +++ b/configure @@ -649,6 +649,7 @@ ENABLE_DNSCRYPT ENABLE_DNSCRYPT_XCHACHA20 DNSTAP_OBJ DNSTAP_SRC +DNSTAP_SOCKET_PATH opt_dnstap_socket_path ENABLE_DNSTAP PROTOC_C @@ -21038,6 +21039,8 @@ cat >>confdefs.h <<_ACEOF #define DNSTAP_SOCKET_PATH "$hdr_dnstap_socket_path" _ACEOF + DNSTAP_SOCKET_PATH="$hdr_dnstap_socket_path" + DNSTAP_SRC="dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dnstap_fstrm.c dnstap/dtstream.c" diff --git a/configure.ac b/configure.ac index 91f4cfbae..50daab3c2 100644 --- a/configure.ac +++ b/configure.ac @@ -1687,6 +1687,7 @@ dt_DNSTAP([$UNBOUND_RUN_DIR/dnstap.sock], ACX_ESCAPE_BACKSLASH($opt_dnstap_socket_path, hdr_dnstap_socket_path) AC_DEFINE_UNQUOTED(DNSTAP_SOCKET_PATH, ["$hdr_dnstap_socket_path"], [default dnstap socket path]) + AC_SUBST(DNSTAP_SOCKET_PATH,["$hdr_dnstap_socket_path"]) AC_SUBST([DNSTAP_SRC], ["dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dnstap_fstrm.c dnstap/dtstream.c"]) AC_SUBST([DNSTAP_OBJ], ["dnstap.lo dnstap.pb-c.lo dnstap_fstrm.lo dtstream.lo"]) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 3492c4380..4af83cd41 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -244,41 +244,105 @@ void dt_io_thread_delete(struct dt_io_thread* dtio) int dt_io_thread_apply_cfg(struct dt_io_thread* dtio, struct config_file *cfg) { - /* - dtio->upstream_is_tcp = 1; - dtio->ip_str = strdup("127.0.0.1@1234"); - */ -#ifdef HAVE_SSL - dtio->upstream_is_tls = 1; - dtio->ip_str = strdup("127.0.0.1@1234"); - //dtio->tls_server_name; - dtio->use_client_certs = 0; - if(dtio->use_client_certs) { - //dtio->client_key_file = NULL; - //dtio->client_cert_file = NULL; - } else { - free(dtio->client_key_file); - dtio->client_key_file = NULL; - free(dtio->client_cert_file); - dtio->client_cert_file = NULL; - } - dtio->ssl_ctx = connect_sslctx_create(dtio->client_key_file, - dtio->client_cert_file, cfg->tls_cert_bundle, - cfg->tls_win_cert); - if(!dtio->ssl_ctx) { - log_err("could not setup SSL CTX"); + if(!cfg->dnstap) { + log_warn("cannot setup dnstap because dnstap-enable is no"); return 0; } - /* DEBUG */ - return 1; -#endif - if(cfg->dnstap_socket_path && cfg->dnstap_socket_path[0]) { - dtio->socket_path = strdup(cfg->dnstap_socket_path); - if(!dtio->socket_path) { - log_err("malloc failure"); + + /* what type of connectivity do we have */ + if(cfg->dnstap_ip && cfg->dnstap_ip[0]) { + if(cfg->dnstap_tls) + dtio->upstream_is_tls = 1; + else dtio->upstream_is_tcp = 1; + } else { + dtio->upstream_is_unix = 1; + } + + if(dtio->upstream_is_unix) { + if(!cfg->dnstap_socket_path || + cfg->dnstap_socket_path[0]==0) { + log_err("dnstap setup failed, because dnstap is " + "enabled, but no dnstap-ip and no " + "dnstap-socket-path are given"); return 0; } - dtio->upstream_is_unix = 1; + free(dtio->socket_path); + dtio->socket_path = strdup(cfg->dnstap_socket_path); + if(!dtio->socket_path) { + log_err("dnstap setup: malloc failure"); + return 0; + } + } + + if(dtio->upstream_is_tcp || dtio->upstream_is_tls) { + free(dtio->ip_str); + dtio->ip_str = strdup(cfg->dnstap_ip); + if(!dtio->ip_str) { + log_err("dnstap setup: malloc failure"); + return 0; + } + } + + if(dtio->upstream_is_tls) { +#ifdef HAVE_SSL + if(cfg->dnstap_tls_server_name && + cfg->dnstap_tls_server_name[0]) { + free(dtio->tls_server_name); + dtio->tls_server_name = strdup( + cfg->dnstap_tls_server_name); + if(!dtio->tls_server_name) { + log_err("dnstap setup: malloc failure"); + return 0; + } + } + if(cfg->dnstap_tls_client_key_file && + cfg->dnstap_tls_client_key_file[0]) { + dtio->use_client_certs = 1; + free(dtio->client_key_file); + dtio->client_key_file = strdup( + cfg->dnstap_tls_client_key_file); + if(!dtio->client_key_file) { + log_err("dnstap setup: malloc failure"); + return 0; + } + if(!cfg->dnstap_tls_client_cert_file || + cfg->dnstap_tls_client_cert_file[0]==0) { + log_err("dnstap setup: client key " + "authentication enabled with " + "dnstap-tls-client-key-file, but " + "no dnstap-tls-client-cert-file " + "is given"); + return 0; + } + free(dtio->client_cert_file); + dtio->client_cert_file = strdup( + cfg->dnstap_tls_client_cert_file); + if(!dtio->client_cert_file) { + log_err("dnstap setup: malloc failure"); + return 0; + } + } else { + dtio->use_client_certs = 0; + dtio->client_key_file = NULL; + dtio->client_cert_file = NULL; + } + + if(cfg->dnstap_tls_cert_bundle) { + dtio->ssl_ctx = connect_sslctx_create( + dtio->client_key_file, + dtio->client_cert_file, + cfg->dnstap_tls_cert_bundle, 0); + } else { + dtio->ssl_ctx = connect_sslctx_create( + dtio->client_key_file, + dtio->client_cert_file, + cfg->tls_cert_bundle, cfg->tls_win_cert); + } + if(!dtio->ssl_ctx) { + log_err("could not setup SSL CTX"); + return 0; + } +#endif /* HAVE_SSL */ } return 1; } diff --git a/doc/example.conf.in b/doc/example.conf.in index 4ce9348c2..ec1b1ac70 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -1016,6 +1016,38 @@ remote-control: # name-v6: "list-v6" # +# Dnstap logging support, if compiled in. To enable, set the dnstap-enable +# to yes and also some of dnstap-log-..-messages to yes. And select an +# upstream log destination, by socket path, TCP or TLS destination. +# dnstap: +# dnstap-enable: no +# dnstap-socket-path: "@DNSTAP_SOCKET_PATH@" +# # if "" use the unix socket in dnstap-socket-path, otherwise, +# # set it to "IPaddress[@port]" of the destination. +# dnstap-ip: "" +# # if set to yes if you want to use TLS to dnstap-ip, no for TCP. +# dnstap-tls: no +# # name for authenticating the upstream server. or "" disabled. +# dnstap-tls-server-name: "" +# # if "", it uses the cert bundle from the main unbound config. +# dnstap-tls-cert-bundle: "" +# # key file for client authentication, or "" disabled. +# dnstap-tls-client-key-file: "" +# # cert file for client authentication, or "" disabled. +# dnstap-tls-client-cert-file: "" +# dnstap-send-identity: no +# dnstap-send-version: no +# # if "" it uses the hostname. +# dnstap-identity: "" +# # if "" it uses the package version. +# dnstap-version: "" +# dnstap-log-resolver-query-messages: no +# dnstap-log-resolver-response-messages: no +# dnstap-log-client-query-messages: no +# dnstap-log-client-response-messages: no +# dnstap-log-forwarder-query-messages: no +# dnstap-log-forwarder-response-messages: no + # Response Policy Zones # RPZ policies. Applied in order of configuration. QNAME and Response IP # Address trigger are the only supported triggers. Supported actions are: diff --git a/util/config_file.c b/util/config_file.c index 52ca5a184..19a5a0bcd 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -632,6 +632,13 @@ int config_set_option(struct config_file* cfg, const char* opt, #ifdef USE_DNSTAP else S_YNO("dnstap-enable:", dnstap) else S_STR("dnstap-socket-path:", dnstap_socket_path) + else S_STR("dnstap-ip:", dnstap_ip) + else S_YNO("dnstap-tls:", dnstap_tls) + else S_STR("dnstap-tls-server-name:", dnstap_tls_server_name) + else S_STR("dnstap-tls-cert-bundle:", dnstap_tls_cert_bundle) + else S_STR("dnstap-tls-client-key-file:", dnstap_tls_client_key_file) + else S_STR("dnstap-tls-client-cert-file:", + dnstap_tls_client_cert_file) else S_YNO("dnstap-send-identity:", dnstap_send_identity) else S_YNO("dnstap-send-version:", dnstap_send_version) else S_STR("dnstap-identity:", dnstap_identity) @@ -1039,6 +1046,14 @@ config_get_option(struct config_file* cfg, const char* opt, #ifdef USE_DNSTAP else O_YNO(opt, "dnstap-enable", dnstap) else O_STR(opt, "dnstap-socket-path", dnstap_socket_path) + else O_STR(opt, "dnstap-ip", dnstap_ip) + else O_YNO(opt, "dnstap-tls", dnstap_tls) + else O_STR(opt, "dnstap-tls-server-name", dnstap_tls_server_name) + else O_STR(opt, "dnstap-tls-cert-bundle", dnstap_tls_cert_bundle) + else O_STR(opt, "dnstap-tls-client-key-file", + dnstap_tls_client_key_file) + else O_STR(opt, "dnstap-tls-client-cert-file", + dnstap_tls_client_cert_file) else O_YNO(opt, "dnstap-send-identity", dnstap_send_identity) else O_YNO(opt, "dnstap-send-version", dnstap_send_version) else O_STR(opt, "dnstap-identity", dnstap_identity) @@ -1458,6 +1473,11 @@ config_delete(struct config_file* cfg) free(cfg->dns64_prefix); config_delstrlist(cfg->dns64_ignore_aaaa); free(cfg->dnstap_socket_path); + free(cfg->dnstap_ip); + free(cfg->dnstap_tls_server_name); + free(cfg->dnstap_tls_cert_bundle); + free(cfg->dnstap_tls_client_key_file); + free(cfg->dnstap_tls_client_cert_file); free(cfg->dnstap_identity); free(cfg->dnstap_version); config_deldblstrlist(cfg->ratelimit_for_domain); diff --git a/util/config_file.h b/util/config_file.h index 8739ca2ae..548fd9335 100644 --- a/util/config_file.h +++ b/util/config_file.h @@ -474,6 +474,18 @@ struct config_file { int dnstap; /** dnstap socket path */ char* dnstap_socket_path; + /** dnstap IP */ + char* dnstap_ip; + /** dnstap TLS enable */ + int dnstap_tls; + /** dnstap tls server authentication name */ + char* dnstap_tls_server_name; + /** dnstap server cert bundle */ + char* dnstap_tls_cert_bundle; + /** dnstap client key for client authentication */ + char* dnstap_tls_client_key_file; + /** dnstap client cert for client authentication */ + char* dnstap_tls_client_cert_file; /** true to send "identity" via dnstap */ int dnstap_send_identity; /** true to send "version" via dnstap */ From 00700bbe13fdb0100f1ce2c54fed22e9570f6e62 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 14 Feb 2020 09:40:37 +0100 Subject: [PATCH 68/96] dnstap io, config entries parse and lex. --- util/configlexer.c | 3853 +++++++++++++++++++++--------------------- util/configlexer.lex | 8 + util/configparser.c | 2706 +++++++++++++++-------------- util/configparser.h | 510 +++--- util/configparser.y | 51 +- 5 files changed, 3681 insertions(+), 3447 deletions(-) diff --git a/util/configlexer.c b/util/configlexer.c index 3b31bb02b..7e7de17c6 100644 --- a/util/configlexer.c +++ b/util/configlexer.c @@ -354,8 +354,8 @@ static void yynoreturn yy_fatal_error ( const char* msg ); (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 302 -#define YY_END_OF_BUFFER 303 +#define YY_NUM_RULES 308 +#define YY_END_OF_BUFFER 309 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -363,336 +363,343 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static const flex_int16_t yy_accept[2986] = +static const flex_int16_t yy_accept[3042] = { 0, - 1, 1, 284, 284, 288, 288, 292, 292, 296, 296, - 1, 1, 303, 300, 1, 282, 282, 301, 2, 301, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 284, 285, 285, 286, 301, 288, 289, 289, - 290, 301, 295, 292, 293, 293, 294, 301, 296, 297, - 297, 298, 301, 299, 283, 2, 287, 301, 299, 300, - 0, 1, 2, 2, 2, 2, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 1, 1, 290, 290, 294, 294, 298, 298, 302, 302, + 1, 1, 309, 306, 1, 288, 288, 307, 2, 307, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 290, 291, 291, 292, 307, 294, 295, 295, + 296, 307, 301, 298, 299, 299, 300, 307, 302, 303, + 303, 304, 307, 305, 289, 2, 293, 307, 305, 306, + 0, 1, 2, 2, 2, 2, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 284, 0, 288, 0, 295, 0, 292, 296, 0, 299, - 0, 2, 2, 299, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 290, 0, 294, 0, 301, 0, 298, 302, 0, 305, + 0, 2, 2, 305, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 299, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 305, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 112, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 120, 300, 300, 300, 300, - 300, 300, 300, 299, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 112, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 120, 306, 306, 306, 306, + 306, 306, 306, 305, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 96, 300, - 300, 300, 300, 300, 300, 8, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 113, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 125, 300, 299, 300, 300, 300, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 96, 306, + 306, 306, 306, 306, 306, 8, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 113, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 125, 306, 305, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 277, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 283, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 299, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 54, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 222, 300, 14, 15, 300, 18, 17, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 305, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 54, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 222, 306, 14, 15, 306, 18, 17, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 119, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 206, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 3, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 119, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 206, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 3, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 299, 300, 300, 300, 300, 300, 300, - 300, 272, 300, 300, 271, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 291, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 305, 306, 306, 306, 306, 306, 306, + 306, 278, 306, 306, 277, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 297, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 57, 300, 246, 300, 300, 300, 300, - 300, 300, 300, 300, 278, 279, 300, 300, 300, 300, - 300, 58, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 116, 300, 300, - 300, 300, 300, 300, 300, 300, 195, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 20, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 144, 300, 300, 291, 300, + 306, 306, 306, 306, 57, 306, 252, 306, 306, 306, + 306, 306, 306, 306, 306, 284, 285, 306, 306, 306, + 306, 306, 58, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 116, 306, + 306, 306, 306, 306, 306, 306, 306, 195, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 20, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 144, 306, 306, 297, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 94, - 300, 300, 300, 300, 300, 300, 300, 254, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 167, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 143, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 94, 306, 306, 306, 306, 306, 306, 306, 260, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 167, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 143, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 93, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 31, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 32, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 55, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 118, 300, 300, 300, 300, - 300, 111, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 56, 300, 300, 300, + 306, 306, 306, 306, 306, 306, 306, 93, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 31, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 32, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 55, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 118, 306, + 306, 306, 306, 306, 111, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 56, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 168, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 45, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 237, 300, 300, 300, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 225, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 168, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 45, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 49, 300, 50, 300, 300, 300, - 300, 300, 97, 300, 98, 300, 300, 300, 300, 95, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 7, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 215, 300, 300, 300, - 300, 146, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 306, 243, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 49, + 306, 50, 306, 306, 306, 306, 306, 97, 306, 98, + 306, 306, 306, 306, 95, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 7, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 215, 306, 306, 306, 306, 146, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 46, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 187, 300, 186, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 16, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 59, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 194, + 306, 306, 226, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 46, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 187, 306, 186, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 16, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 59, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 100, 300, 99, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 178, - 300, 300, 300, 300, 300, 300, 300, 300, 126, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 78, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 82, 300, + 306, 306, 306, 306, 306, 306, 194, 306, 306, 306, + 306, 306, 306, 100, 306, 99, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 178, 306, 306, 306, + 306, 306, 306, 306, 306, 126, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 78, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 53, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 181, 182, 300, 300, 300, 248, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 6, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 252, - 300, 300, 300, 300, 300, 300, 273, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 41, 300, 300, + 306, 306, 306, 306, 306, 306, 306, 82, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 53, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 181, + 182, 306, 306, 306, 254, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 6, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 258, 306, + 306, 306, 306, 306, 306, 279, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 43, 300, 300, 300, 300, 300, 300, 300, 300, 174, - 300, 300, 300, 121, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 199, 300, 175, 300, 300, 300, - 212, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 44, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 123, 105, 300, - 106, 300, 300, 300, 104, 300, 300, 300, 300, 300, - 300, 300, 300, 141, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 236, 300, 300, 300, 300, + 306, 306, 306, 306, 306, 306, 41, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 43, + 306, 306, 306, 306, 306, 306, 306, 306, 174, 306, + 306, 306, 121, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 199, 306, 175, 306, 306, 306, 212, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 44, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 123, + 105, 306, 106, 306, 306, 306, 104, 306, 306, 306, + 306, 306, 306, 306, 306, 141, 306, 306, 306, 306, - 300, 300, 300, 300, 176, 300, 300, 300, 300, 300, - 179, 300, 185, 300, 300, 300, 300, 300, 211, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 92, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 117, 300, 300, 300, 300, 300, 300, 51, 300, - 300, 300, 25, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 19, 300, 300, 300, 300, 300, 300, 26, - 35, 300, 151, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 306, 306, 306, 306, 306, 306, 306, 242, 306, 306, + 306, 306, 306, 306, 306, 306, 176, 306, 306, 306, + 306, 306, 179, 306, 185, 306, 306, 306, 306, 306, + 211, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 92, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 117, 306, 306, 306, 306, 306, 306, + 51, 306, 306, 306, 25, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 19, 306, 306, 306, 306, 306, + 306, 26, 35, 306, 151, 306, 306, 306, 306, 306, - 300, 300, 67, 69, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 256, 300, 300, - 300, 223, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 107, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 140, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 267, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 145, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 205, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 67, 69, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 262, + 306, 306, 306, 223, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 107, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 140, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 273, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 300, 300, 276, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 162, 300, 300, 300, 300, 300, 300, 300, 300, 101, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 157, - 300, 169, 300, 300, 300, 300, 300, 129, 300, 300, - 300, 300, 300, 88, 300, 300, 300, 300, 197, 300, - 300, 300, 300, 300, 300, 213, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 228, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 122, 300, + 145, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 205, 306, 306, 306, 306, 306, + 306, 306, 306, 282, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 162, 306, 306, 306, 306, + 306, 306, 306, 306, 101, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 157, 306, 169, 306, 306, 306, + 306, 306, 129, 306, 306, 306, 306, 306, 88, 306, + 306, 306, 306, 197, 306, 306, 306, 306, 306, 306, + 213, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 161, - 300, 300, 300, 300, 300, 70, 71, 300, 300, 300, - 300, 300, 52, 300, 300, 300, 300, 300, 77, 170, - 300, 188, 300, 216, 300, 300, 180, 249, 300, 300, - 300, 300, 300, 63, 300, 172, 300, 300, 300, 300, - 300, 9, 300, 300, 300, 91, 300, 300, 300, 300, - 241, 300, 300, 300, 196, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 306, 306, 306, 306, 306, 306, 234, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 122, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 161, 306, 306, + 306, 306, 306, 70, 71, 306, 306, 306, 306, 306, + 52, 306, 306, 306, 306, 306, 77, 170, 306, 188, + 306, 216, 306, 306, 180, 255, 306, 306, 306, 306, + 306, 63, 306, 172, 306, 306, 306, 306, 306, 9, + 306, 306, 306, 91, 306, 306, 306, 306, 247, 306, + 306, 306, 196, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 160, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 147, 300, 255, 300, 300, - 300, 300, 227, 300, 300, 300, 300, 300, 300, 300, - 300, 207, 300, 300, 300, 300, 247, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 270, 300, 171, 300, 300, 300, 300, 300, 300, - 300, 62, 64, 300, 300, 300, 300, 300, 300, 300, - 90, 300, 300, 300, 300, 239, 300, 300, 300, 251, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 160, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 147, 306, 261, 306, 306, 306, 306, + 233, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 207, 306, 306, 306, 306, 253, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 276, 306, 171, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 201, 33, 27, 29, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 34, 300, 28, 30, 300, 300, - 300, 300, 300, 300, 300, 300, 87, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 203, 200, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 61, 300, 300, 124, 300, 108, 300, 300, 300, 300, - 300, 300, 300, 300, 142, 13, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 265, 300, 268, 300, 300, + 306, 306, 62, 64, 306, 306, 306, 306, 306, 306, + 306, 90, 306, 306, 306, 306, 245, 306, 306, 306, + 257, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 201, 33, 27, 29, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 34, 306, 28, 30, 306, + 306, 306, 306, 306, 306, 306, 306, 87, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 203, 200, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 61, 306, 306, 124, 306, 108, - 300, 300, 300, 300, 300, 300, 300, 300, 12, 300, - 300, 21, 300, 300, 300, 245, 300, 300, 300, 253, - 300, 300, 300, 65, 300, 209, 300, 300, 300, 300, - 202, 300, 300, 60, 300, 300, 300, 300, 22, 300, - 42, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 156, 155, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 204, 198, 300, 214, 300, 300, - 257, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 72, 300, 300, 300, 240, + 306, 306, 306, 306, 306, 306, 306, 306, 142, 13, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 271, + 306, 274, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 12, 306, 306, 21, 306, 306, 306, 251, + 306, 306, 306, 259, 306, 306, 306, 65, 306, 209, + 306, 306, 306, 306, 202, 306, 306, 60, 306, 306, + 306, 306, 22, 306, 42, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 156, 155, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 204, 198, + 306, 214, 306, 306, 263, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 184, 300, 300, 300, 300, 208, - 300, 300, 300, 300, 300, 300, 300, 300, 274, 275, - 153, 300, 300, 66, 300, 300, 300, 300, 163, 300, - 300, 102, 103, 300, 300, 300, 300, 148, 300, 150, - 300, 189, 300, 300, 300, 300, 154, 300, 300, 217, - 300, 300, 300, 300, 300, 300, 300, 131, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 224, - 300, 300, 300, 23, 300, 250, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 190, 300, 300, - 238, 300, 269, 300, 183, 300, 300, 300, 300, 47, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 72, 306, 306, 306, 246, 306, 306, 306, + 306, 184, 306, 306, 306, 306, 208, 306, 306, 306, + 306, 306, 306, 306, 306, 280, 281, 153, 306, 306, + 66, 306, 306, 306, 306, 163, 306, 306, 102, 103, + 306, 306, 306, 306, 148, 306, 150, 306, 189, 306, + 306, 306, 306, 154, 306, 306, 217, 306, 306, 306, + 306, 306, 306, 306, 131, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 224, 306, 306, 306, - 300, 300, 300, 300, 4, 300, 300, 300, 115, 130, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 220, 36, - 37, 300, 300, 300, 300, 300, 300, 300, 258, 300, - 300, 300, 300, 300, 300, 226, 300, 300, 300, 193, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 75, - 300, 48, 244, 300, 221, 300, 300, 300, 300, 11, - 300, 300, 300, 300, 300, 114, 300, 300, 300, 300, - 191, 79, 300, 39, 300, 300, 300, 300, 300, 300, - 300, 300, 159, 300, 300, 300, 300, 300, 133, 300, + 306, 306, 306, 306, 23, 306, 256, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 190, 306, + 306, 244, 306, 275, 306, 183, 306, 306, 306, 306, + 47, 306, 306, 306, 306, 4, 306, 306, 306, 115, + 130, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 220, + 36, 37, 306, 306, 306, 306, 306, 306, 306, 264, + 306, 306, 306, 306, 306, 306, 232, 306, 306, 306, + 306, 306, 306, 306, 193, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 75, 306, 48, 250, 306, 221, - 300, 300, 300, 300, 300, 300, 300, 300, 225, 127, - 300, 300, 109, 110, 300, 300, 300, 81, 85, 80, - 300, 73, 300, 300, 300, 300, 300, 10, 300, 300, - 300, 242, 300, 300, 300, 300, 281, 38, 300, 300, - 300, 300, 300, 158, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 86, 84, 300, 74, 266, 300, 300, 300, - 300, 300, 300, 300, 177, 300, 300, 300, 300, 300, - 192, 300, 300, 300, 300, 300, 300, 300, 300, 149, - 68, 300, 300, 300, 300, 300, 259, 300, 300, 300, + 306, 306, 306, 306, 11, 306, 306, 306, 306, 306, + 114, 306, 306, 306, 306, 191, 79, 306, 39, 306, + 306, 306, 306, 306, 306, 306, 306, 159, 306, 306, + 306, 306, 306, 133, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 231, 306, 306, 306, 306, 127, 306, + 306, 109, 110, 306, 306, 306, 81, 85, 80, 306, + 73, 306, 306, 306, 306, 306, 10, 306, 306, 306, + 248, 306, 306, 306, 306, 287, 38, 306, 306, 306, + 306, 306, 158, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 128, 300, 83, 134, 135, 138, - 139, 136, 137, 76, 300, 243, 300, 300, 300, 300, - 152, 300, 300, 300, 300, 300, 219, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 165, 164, 40, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 89, 300, 218, - 300, 235, 263, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 5, 300, 300, 210, 300, 300, 264, - 300, 300, 300, 300, 300, 300, 300, 300, 24, 300, + 306, 306, 306, 306, 306, 86, 84, 306, 74, 272, + 306, 306, 306, 306, 306, 306, 306, 177, 306, 306, + 306, 306, 306, 192, 306, 306, 306, 306, 306, 306, + 306, 306, 149, 68, 306, 306, 306, 306, 306, 265, + 306, 306, 306, 306, 306, 306, 306, 228, 306, 306, + 227, 128, 306, 83, 134, 135, 138, 139, 136, 137, + 76, 306, 249, 306, 306, 306, 306, 152, 306, 306, + 306, 306, 306, 219, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 165, 164, 40, 306, 306, 306, 306, 306, 306, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 132, 300, 300, 300, 300, 300, - 300, 300, 300, 166, 300, 173, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 260, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 280, 300, 300, 231, 300, 300, 300, - 300, 300, 261, 300, 300, 300, 300, 300, 300, 262, - 300, 300, 300, 229, 300, 232, 233, 300, 300, 300, - 300, 300, 230, 234, 0 + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 89, 306, + 218, 306, 241, 269, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 5, 306, 306, 210, + 306, 306, 270, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 229, 24, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 230, 306, 306, 306, + 132, 306, 306, 306, 306, 306, 306, 306, 306, 166, + 306, 173, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 266, 306, 306, 306, 306, 306, 306, 306, 306, + + 306, 306, 306, 306, 306, 306, 306, 306, 306, 286, + 306, 306, 237, 306, 306, 306, 306, 306, 267, 306, + 306, 306, 306, 306, 306, 268, 306, 306, 306, 235, + 306, 238, 239, 306, 306, 306, 306, 306, 236, 240, + 0 } ; static const YY_CHAR yy_ec[256] = @@ -735,15 +742,15 @@ static const YY_CHAR yy_meta[41] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; -static const flex_int16_t yy_base[3000] = +static const flex_int16_t yy_base[3056] = { 0, 0, 0, 38, 41, 44, 46, 59, 65, 71, 77, - 90, 112, 4280, 4028, 81, 5813, 5813, 5813, 96, 52, + 90, 112, 3491, 3333, 81, 5920, 5920, 5920, 96, 52, 106, 63, 107, 111, 70, 128, 130, 133, 57, 88, 76, 135, 141, 117, 148, 145, 160, 164, 185, 177, - 189, 152, 3954, 5813, 5813, 5813, 107, 3854, 5813, 5813, - 5813, 165, 3105, 2544, 5813, 5813, 5813, 211, 2291, 5813, - 5813, 5813, 180, 2178, 5813, 217, 5813, 221, 168, 1832, + 189, 152, 3242, 5920, 5920, 5920, 107, 2717, 5920, 5920, + 5920, 165, 2157, 2047, 5920, 5920, 5920, 211, 1913, 5920, + 5920, 5920, 180, 1568, 5920, 217, 5920, 221, 168, 1529, 225, 231, 0, 237, 0, 0, 226, 231, 85, 180, 114, 238, 239, 156, 234, 206, 240, 232, 200, 132, 253, 244, 245, 248, 256, 257, 264, 271, 249, 277, @@ -772,9 +779,9 @@ static const flex_int16_t yy_base[3000] = 700, 701, 702, 711, 704, 712, 713, 726, 731, 721, 732, 733, 735, 737, 740, 748, 739, 746, 743, 750, - 752, 753, 762, 758, 5813, 757, 760, 773, 766, 774, + 752, 753, 762, 758, 5920, 757, 760, 773, 766, 774, 775, 776, 781, 782, 763, 789, 787, 788, 792, 814, - 796, 798, 794, 803, 806, 5813, 804, 808, 838, 810, + 796, 798, 794, 803, 806, 5920, 804, 808, 838, 810, 812, 832, 828, 824, 827, 829, 839, 836, 849, 842, 847, 851, 862, 858, 859, 860, 861, 864, 863, 877, 872, 870, 799, 874, 889, 875, 882, 886, 887, 892, @@ -783,21 +790,21 @@ static const flex_int16_t yy_base[3000] = 942, 943, 937, 944, 947, 950, 951, 952, 953, 961, 958, 959, 963, 964, 966, 967, 970, 972, 973, 975, - 977, 979, 978, 985, 988, 981, 994, 989, 5813, 996, - 998, 999, 1000, 1001, 1003, 5813, 1004, 1005, 1006, 1014, + 977, 979, 978, 985, 988, 981, 994, 989, 5920, 996, + 998, 999, 1000, 1001, 1003, 5920, 1004, 1005, 1006, 1014, 1017, 1016, 1013, 1023, 1027, 1028, 1029, 1030, 1039, 1012, 1041, 1040, 1036, 1042, 1046, 1048, 1049, 1051, 1052, 1054, - 1055, 1057, 1060, 1077, 5813, 1061, 1064, 1062, 1063, 1070, + 1055, 1057, 1060, 1077, 5920, 1061, 1064, 1062, 1063, 1070, 1080, 1089, 1072, 1090, 1088, 1065, 1105, 1092, 1106, 1100, 1101, 1111, 1102, 1113, 1107, 1116, 1115, 1117, 1118, 1119, - 1120, 1125, 1126, 1131, 5813, 1133, 1134, 1145, 1135, 1143, + 1120, 1125, 1126, 1131, 5920, 1133, 1134, 1145, 1135, 1143, 1132, 1146, 1148, 1149, 1150, 1152, 1153, 1156, 1162, 1172, 1157, 1174, 1159, 1170, 1175, 1176, 1177, 1178, 1179, 1180, 1193, 1184, 1186, 1200, 1207, 1203, 1205, 1212, 1190, 1210, 1209, 1208, 1215, 1216, 1217, 1218, 1220, 1221, 1230, 1228, 1226, 1229, 1231, 1242, 1233, 1235, 1240, 1237, 1245, 1247, - 1253, 1254, 1250, 1256, 5813, 1263, 1260, 1267, 1262, 1268, + 1253, 1254, 1250, 1256, 5920, 1263, 1260, 1267, 1262, 1268, 1272, 1274, 1261, 1276, 1278, 1280, 1281, 1282, 1284, 1287, 1289, 1290, 1291, 1292, 1301, 1297, 1307, 1314, 1313, 1315, 1299, 1305, 1324, 1321, 1328, 1327, 1329, 1337, 1325, 1332, @@ -809,601 +816,613 @@ static const flex_int16_t yy_base[3000] = 1416, 1417, 1418, 1419, 1420, 1423, 1424, 1183, 1425, 1440, 1426, 1430, 1438, 1441, 1447, 1446, 1450, 1454, 1444, 1456, 1457, 1458, 1460, 1461, 1465, 1464, 1471, 1468, 1474, 1476, - 1478, 1477, 1480, 1484, 1487, 1481, 5813, 1488, 1495, 1494, + 1478, 1477, 1480, 1484, 1487, 1481, 5920, 1488, 1495, 1494, 1496, 1497, 1499, 1501, 1508, 1503, 1505, 1504, 1506, 1510, - 1516, 5813, 1517, 5813, 5813, 1520, 5813, 5813, 1518, 1523, - 1526, 1536, 1533, 1543, 1298, 1539, 1541, 1545, 1552, 1566, + 1532, 5920, 1513, 5920, 5920, 1516, 5920, 5920, 1517, 1515, + 1518, 1523, 1535, 1538, 1298, 1525, 1542, 1520, 1553, 1557, - 1548, 1550, 1551, 1547, 1556, 1561, 1574, 1562, 1549, 1575, - 1577, 1580, 1586, 1513, 1587, 1579, 1554, 1588, 1590, 1589, - 1592, 1595, 1600, 1601, 1594, 1603, 1596, 1611, 1616, 1607, - 1623, 5813, 1619, 1626, 1631, 1627, 1634, 1630, 1629, 1636, - 1638, 1640, 1641, 1642, 1643, 1645, 1646, 1651, 1604, 1647, - 1659, 1654, 5813, 1657, 1658, 1656, 1662, 1669, 1663, 1664, - 1670, 1674, 1675, 1682, 1679, 1677, 1684, 1685, 1686, 1687, - 5813, 1689, 1697, 1693, 1699, 1700, 1702, 1705, 1701, 1706, - 1707, 1708, 1709, 1711, 1715, 1718, 1719, 1720, 1717, 1724, - 1727, 1730, 1735, 1742, 1737, 1739, 1743, 1745, 1746, 1747, + 1545, 1546, 1548, 1549, 1560, 1571, 1555, 1572, 1565, 1577, + 1579, 1582, 1581, 1587, 1583, 1588, 1590, 1591, 1593, 1592, + 1596, 1598, 1601, 1602, 1599, 1604, 1605, 1614, 1618, 1610, + 1625, 5920, 1621, 1628, 1635, 1631, 1638, 1630, 1634, 1637, + 1642, 1644, 1639, 1646, 1648, 1649, 1650, 1652, 1654, 1657, + 1661, 1658, 5920, 1659, 1662, 1667, 1666, 1670, 1674, 1606, + 1660, 1678, 1676, 1692, 1680, 1682, 1683, 1684, 1688, 1695, + 5920, 1694, 1700, 1690, 1703, 1701, 1704, 1705, 1707, 1710, + 1709, 1713, 1715, 1714, 1716, 1723, 1728, 1721, 1720, 1726, + 1738, 1727, 1742, 1746, 1731, 1734, 1748, 1749, 1750, 1752, - 1749, 1750, 1758, 1751, 1760, 1755, 1762, 1767, 1772, 1759, - 1771, 1774, 1764, 1780, 1788, 1784, 1777, 1773, 1796, 1789, - 1793, 1794, 1797, 1799, 1800, 1801, 1803, 1806, 1807, 1808, - 1810, 5813, 1811, 1816, 5813, 1814, 1817, 1839, 1818, 1820, - 1821, 1823, 1826, 1833, 1825, 1831, 1841, 1843, 1853, 1849, - 1854, 1856, 1859, 1861, 1862, 1865, 1867, 1869, 1878, 1879, - 1883, 1885, 1890, 1870, 1868, 1877, 1896, 1888, 1889, 1891, - 1899, 1906, 1893, 1901, 1903, 1908, 1912, 1914, 1919, 5813, - 1924, 1925, 1920, 1921, 1932, 1930, 1929, 1933, 1936, 1937, - 1944, 1940, 1941, 1946, 1943, 1947, 1950, 1952, 1956, 1957, + 1753, 1755, 1760, 1759, 1762, 1758, 1767, 1769, 1776, 1764, + 1765, 1766, 1779, 1781, 1790, 1786, 1787, 1788, 1797, 1792, + 1794, 1795, 1798, 1807, 1796, 1804, 1809, 1799, 1802, 1814, + 1815, 5920, 1816, 1817, 5920, 1818, 1820, 1842, 1823, 1825, + 1828, 1827, 1830, 1832, 1833, 1835, 1839, 1846, 1862, 1850, + 1865, 1837, 1867, 1854, 1868, 1857, 1859, 1870, 1877, 1885, + 1892, 1875, 1893, 1895, 1876, 1878, 1887, 1906, 1890, 1891, + 1894, 1899, 1900, 1904, 1910, 1903, 1915, 1916, 1922, 1919, + 5920, 1930, 1928, 1927, 1929, 1939, 1936, 1937, 1938, 1940, + 1943, 1950, 1945, 1948, 1952, 1951, 1955, 1953, 1958, 1963, - 1962, 1954, 1973, 5813, 1958, 5813, 1955, 1959, 1972, 1975, - 1976, 1977, 1978, 1980, 5813, 5813, 1981, 1984, 1987, 1996, - 1982, 5813, 1997, 2004, 2001, 2006, 2000, 1999, 2007, 2008, - 2011, 2016, 2012, 2023, 2015, 2022, 2020, 5813, 2028, 2018, - 2024, 2033, 2035, 2036, 2037, 2040, 5813, 2043, 2044, 2047, - 2054, 2046, 2050, 2055, 2058, 2056, 2062, 2063, 2064, 2065, - 2066, 2075, 2076, 2067, 2078, 2081, 2077, 5813, 2074, 2085, - 2093, 2089, 2091, 2088, 2095, 2096, 2098, 2099, 2100, 2103, - 2106, 2107, 2115, 2116, 2108, 2112, 2120, 2113, 2122, 2125, - 2128, 2127, 2129, 2130, 2131, 5813, 2133, 2135, 124, 2139, + 1965, 1960, 1961, 1968, 5920, 1964, 5920, 1975, 1976, 1979, + 1977, 1981, 1982, 1983, 1985, 5920, 5920, 1987, 1984, 1994, + 2006, 2001, 5920, 1986, 2009, 2011, 2004, 2005, 2010, 2013, + 2016, 2017, 2024, 2020, 2027, 2022, 2023, 2025, 5920, 2033, + 2026, 2038, 2041, 2034, 2044, 2048, 2042, 5920, 2045, 2052, + 2055, 2062, 2058, 2060, 2059, 2063, 2064, 2067, 2070, 2071, + 2072, 2073, 2080, 2082, 2078, 2079, 2087, 2094, 5920, 2081, + 2090, 2101, 2093, 2097, 2100, 2102, 2103, 2104, 2105, 2106, + 2112, 2113, 2114, 2122, 2124, 2119, 2115, 2127, 2123, 2129, + 2128, 2135, 2132, 2136, 2137, 2138, 5920, 2139, 2147, 124, - 2140, 2142, 2141, 2148, 2144, 2147, 2164, 2165, 2161, 2160, - 2163, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2177, 5813, - 2151, 2179, 2180, 2182, 2185, 2186, 2189, 5813, 2199, 2202, - 2188, 2201, 2209, 2204, 2210, 2211, 2213, 2218, 2214, 2217, - 5813, 2221, 2224, 2226, 2227, 2228, 2230, 2235, 2237, 2238, - 2239, 2242, 2240, 2241, 2245, 2243, 2246, 2250, 2259, 2249, - 2251, 2256, 2260, 5813, 2272, 2261, 2270, 2263, 2274, 2273, - 2287, 2277, 2280, 2282, 2288, 2297, 2290, 2284, 2298, 2299, - 2304, 2308, 2307, 2313, 2314, 2311, 2315, 2321, 2323, 2324, - 2325, 2329, 2327, 2330, 2331, 2332, 2339, 2340, 2337, 2348, + 2141, 2144, 2148, 2149, 2152, 2165, 2151, 2168, 2172, 2169, + 2173, 2176, 2153, 2170, 2177, 2178, 2179, 2180, 2185, 2183, + 5920, 2189, 2190, 2191, 2186, 2197, 2192, 2194, 5920, 2195, + 2206, 2215, 2216, 2205, 2217, 2207, 2218, 2221, 2222, 2224, + 2228, 2229, 2225, 5920, 2232, 2234, 2237, 2235, 2241, 2245, + 2238, 2248, 2250, 2251, 2252, 2253, 2254, 2257, 2256, 2258, + 2259, 2260, 2267, 2271, 2272, 2274, 5920, 2284, 2262, 2273, + 2280, 2285, 2286, 2294, 2287, 2289, 2295, 2296, 2309, 2299, + 2301, 2311, 2315, 2302, 2304, 2325, 2321, 2324, 2330, 2320, + 2333, 2335, 2323, 2327, 2337, 2336, 2339, 2347, 2342, 2354, - 2346, 2353, 2351, 2356, 5813, 2357, 2358, 2341, 2363, 2371, - 2368, 2369, 2375, 2376, 2377, 2378, 2379, 2386, 2381, 2383, - 2384, 2387, 2388, 2394, 2395, 2399, 2400, 2407, 2401, 2409, - 2410, 5813, 2411, 2415, 2404, 2417, 2419, 2421, 2428, 2429, - 2431, 2422, 2425, 2433, 2434, 2435, 2437, 2439, 2440, 2445, - 2442, 5813, 2448, 2450, 2453, 2456, 2455, 2459, 2462, 2468, - 2466, 2452, 2472, 2473, 2474, 5813, 2481, 2482, 2479, 2483, - 2485, 2486, 2488, 2490, 2491, 5813, 2492, 2493, 2501, 2502, - 2497, 5813, 2504, 2500, 2506, 2507, 2508, 2509, 2517, 2510, - 2513, 2515, 2523, 2525, 2521, 2529, 5813, 2531, 2541, 2536, + 2355, 2352, 2358, 2350, 2371, 2353, 2363, 5920, 2365, 2367, + 2373, 2375, 2386, 2376, 2378, 2379, 2381, 2377, 2387, 2388, + 2395, 2399, 2397, 2394, 2404, 2401, 2403, 2392, 2407, 2411, + 2414, 2418, 2420, 2421, 5920, 2422, 2424, 2417, 2426, 2428, + 2430, 2438, 2439, 2441, 2431, 2434, 2443, 2444, 2445, 2447, + 2449, 2451, 2456, 2453, 5920, 2459, 2457, 2461, 2463, 2465, + 2469, 2470, 2476, 2478, 2479, 2480, 2481, 2482, 5920, 2490, + 2491, 2487, 2499, 2489, 2494, 2496, 2501, 2502, 5920, 2503, + 2504, 2511, 2512, 2508, 5920, 2515, 2510, 2516, 2517, 2518, + 2519, 2520, 2525, 2526, 2528, 2533, 2535, 2531, 2539, 5920, - 2537, 2539, 2542, 2543, 2545, 2557, 2549, 2552, 2559, 2564, - 2561, 2548, 2555, 2569, 2570, 2571, 2573, 2574, 5813, 2576, - 2577, 2579, 2582, 2580, 2585, 2586, 2598, 2588, 2591, 2593, - 2596, 2599, 2601, 2604, 2606, 2612, 2608, 2615, 2618, 2616, - 2621, 2602, 2625, 2628, 2635, 2632, 2636, 5813, 2639, 2640, - 2634, 2641, 2642, 2645, 2646, 2647, 2649, 2650, 2652, 2651, - 2654, 2667, 2676, 2662, 2663, 2655, 2668, 2671, 2672, 2678, - 2679, 2683, 2690, 2681, 2685, 2694, 2689, 2692, 2702, 2691, - 2693, 2695, 2700, 2703, 2704, 2705, 2706, 2713, 2709, 2723, - 2724, 2726, 2715, 2718, 2731, 2732, 5813, 2735, 2733, 2736, + 2540, 2548, 2543, 2541, 2549, 2552, 2553, 2555, 2564, 2556, + 2560, 5920, 2571, 2563, 2575, 2582, 2577, 2562, 2579, 2578, + 2580, 2584, 2585, 5920, 2587, 2590, 2591, 2592, 2595, 2594, + 2600, 2610, 2602, 2603, 2606, 2611, 2613, 2615, 2616, 2617, + 2618, 2607, 2627, 2629, 2631, 2632, 2633, 2635, 2643, 2645, + 2641, 2647, 5920, 2650, 2651, 2644, 2652, 2657, 2658, 2656, + 2659, 2661, 2664, 2662, 2665, 2666, 2675, 2683, 2668, 2686, + 2676, 2678, 2680, 2691, 2684, 2690, 2693, 2698, 2694, 2700, + 2707, 2702, 2706, 2714, 2704, 2705, 2709, 2713, 2715, 2716, + 2718, 2719, 2722, 2727, 2731, 2735, 2734, 2736, 2741, 2742, - 2737, 2742, 2745, 2749, 2739, 2746, 2747, 2757, 2758, 2755, - 2760, 2763, 2770, 2766, 5813, 2767, 5813, 2768, 2769, 2771, - 2779, 2776, 5813, 2781, 5813, 2784, 2791, 2777, 2782, 5813, - 2792, 2786, 2788, 2799, 2794, 2801, 2802, 2803, 2804, 2810, - 2805, 2812, 2807, 2813, 2815, 2816, 2819, 2820, 2826, 2833, - 2828, 2830, 2817, 2836, 2838, 2840, 2841, 5813, 2844, 2845, - 2850, 2849, 2851, 2852, 2853, 2855, 2856, 2858, 2857, 2862, - 2861, 2870, 2874, 2886, 2871, 2888, 5813, 2873, 2884, 2875, - 2889, 5813, 2885, 2892, 2896, 2898, 2893, 2900, 2902, 2901, - 2905, 2903, 2908, 2919, 2920, 2921, 2923, 2924, 2909, 2910, + 2745, 5920, 2743, 2744, 2746, 2752, 2754, 2756, 2763, 2758, + 2762, 2760, 2767, 2770, 2769, 2772, 2776, 2783, 2779, 5920, + 2780, 5920, 2781, 2782, 2784, 2792, 2788, 5920, 2794, 5920, + 2797, 2804, 2791, 2795, 5920, 2806, 2799, 2801, 2812, 2805, + 2814, 2815, 2816, 2817, 2822, 2818, 2824, 2825, 2826, 2828, + 2829, 2832, 2830, 2841, 2844, 2833, 2851, 2838, 2843, 2855, + 2846, 2856, 5920, 2858, 2849, 2862, 2863, 2864, 2866, 2868, + 2870, 2872, 2873, 2871, 2874, 2877, 2884, 2885, 2887, 2888, + 2895, 5920, 2896, 2899, 2894, 2900, 5920, 2902, 2901, 2903, + 2911, 2905, 2909, 2914, 2915, 2916, 2920, 2921, 2928, 2930, - 2933, 2930, 2911, 2938, 2942, 2940, 2931, 2941, 2943, 2946, - 2947, 2954, 2955, 2951, 2958, 2953, 2960, 2964, 2967, 2957, - 2961, 2968, 2969, 2970, 2973, 2974, 2977, 2978, 2979, 2980, - 2982, 5813, 2990, 2986, 2991, 2992, 2995, 2997, 3000, 3001, - 3004, 3002, 3005, 3009, 3007, 5813, 3014, 5813, 3008, 3022, - 3016, 3027, 3020, 3028, 3035, 3031, 3036, 3037, 3039, 3040, - 3041, 3042, 3043, 3047, 3050, 3048, 3061, 3054, 3051, 3063, - 3064, 3065, 3067, 3068, 5813, 3069, 3070, 3072, 3074, 3075, - 3081, 3077, 3087, 3085, 3089, 3091, 3101, 5813, 3093, 3097, - 3098, 3106, 3108, 3104, 3114, 3121, 3118, 3125, 3124, 5813, + 2933, 2923, 5920, 2935, 2940, 2922, 2936, 2943, 2948, 2949, + 2951, 2960, 2956, 2955, 2957, 2958, 2959, 2962, 2969, 2970, + 2966, 2973, 2972, 2976, 2983, 2980, 2974, 2978, 2984, 2986, + 2987, 2990, 2993, 2994, 2989, 2991, 2996, 2997, 5920, 3008, + 2999, 3012, 3013, 3005, 3015, 3003, 3016, 3021, 3022, 3024, + 3023, 3025, 5920, 3028, 5920, 3026, 3033, 3039, 3045, 3040, + 3042, 3046, 3054, 3050, 3047, 3056, 3057, 3055, 3059, 3058, + 3064, 3068, 3069, 3071, 3073, 3070, 3076, 3079, 3081, 3082, + 3084, 5920, 3085, 3086, 3087, 3091, 3092, 3094, 3102, 3100, + 3093, 3105, 3106, 3114, 5920, 3115, 3116, 3118, 3120, 3127, - 3116, 3117, 3132, 3127, 3134, 3135, 5813, 3133, 5813, 3128, - 3138, 3142, 3139, 3145, 3146, 3149, 3151, 3153, 3160, 3161, - 3156, 3144, 3162, 3166, 3168, 3173, 3170, 3171, 3172, 5813, - 3176, 3177, 3178, 3179, 3183, 3186, 3189, 3193, 5813, 3194, - 3196, 3199, 3200, 3201, 3203, 3205, 3204, 3210, 3213, 3207, - 3208, 3221, 3217, 3206, 3227, 3231, 3232, 3237, 5813, 3234, - 3214, 3244, 3241, 3242, 3243, 3246, 3247, 3248, 3250, 3251, - 3252, 3253, 3259, 3258, 3255, 3256, 3261, 3264, 3275, 3272, - 3263, 3276, 3277, 3280, 3283, 3282, 3286, 3289, 3291, 3292, - 3302, 3303, 3294, 3297, 3306, 3307, 3314, 3310, 5813, 3322, + 3119, 3123, 3134, 3130, 3138, 3133, 5920, 3136, 3141, 3148, + 3144, 3143, 3151, 5920, 3150, 5920, 3147, 3149, 3153, 3154, + 3159, 3160, 3162, 3164, 3170, 3171, 3180, 3175, 3167, 3177, + 3179, 3181, 3189, 3182, 3184, 3185, 5920, 3193, 3186, 3197, + 3202, 3205, 3208, 3190, 3196, 5920, 3209, 3212, 3214, 3215, + 3216, 3218, 3220, 3221, 3225, 3226, 3222, 3223, 3236, 3232, + 3229, 3239, 3249, 3250, 3252, 5920, 3254, 3231, 3261, 3257, + 3246, 3260, 3263, 3264, 3265, 3267, 3268, 3269, 3270, 3271, + 3273, 3272, 3280, 3275, 3291, 3276, 3278, 3298, 3300, 3290, + 3282, 3292, 3299, 3304, 3307, 3309, 3313, 3315, 3305, 3317, - 3299, 3325, 3309, 3320, 3327, 3328, 3330, 3331, 3321, 3332, - 3339, 3335, 5813, 3348, 3337, 3336, 3346, 3349, 3359, 3354, - 3340, 3356, 3362, 3358, 3365, 3367, 3368, 3369, 3372, 3373, - 5813, 5813, 3375, 3376, 3379, 5813, 3380, 3378, 3391, 3382, - 3383, 3392, 3395, 3394, 3386, 3396, 3398, 3400, 5813, 3405, - 3414, 3406, 3411, 3415, 3419, 3421, 3417, 3423, 3425, 3427, - 3428, 3430, 3429, 3431, 3434, 3442, 3438, 3437, 3439, 5813, - 3441, 3444, 3448, 3450, 3451, 3454, 5813, 3455, 3456, 3462, - 3463, 3465, 3467, 3473, 3476, 3477, 3478, 3480, 3481, 3482, - 3483, 3485, 3490, 3488, 3495, 3496, 3487, 5813, 3500, 3501, + 3326, 3318, 3320, 3329, 3330, 3337, 3332, 5920, 3342, 3322, + 3344, 3324, 3343, 3348, 3350, 3358, 3353, 3354, 3355, 3362, + 3357, 5920, 3369, 3345, 3371, 3370, 3361, 3384, 3379, 3360, + 3364, 3383, 3386, 3389, 3387, 3391, 3392, 3395, 3396, 5920, + 5920, 3398, 3399, 3400, 5920, 3401, 3402, 3411, 3404, 3406, + 3414, 3408, 3417, 3418, 3419, 3421, 3422, 5920, 3425, 3434, + 3431, 3432, 3441, 3442, 3446, 3443, 3440, 3433, 3437, 3450, + 3452, 3454, 3457, 3458, 3466, 3461, 3463, 3464, 5920, 3465, + 3467, 3469, 3471, 3473, 3475, 5920, 3476, 3482, 3487, 3479, + 3497, 3494, 3491, 3500, 3480, 3503, 3504, 3505, 3506, 3508, - 3504, 3507, 3511, 3514, 3521, 3522, 3518, 3520, 3519, 3529, - 5813, 3526, 3528, 3527, 3530, 3540, 3535, 3542, 3533, 5813, - 3537, 3541, 3543, 5813, 3547, 3551, 3554, 3559, 3546, 3562, - 3561, 3563, 3564, 3565, 5813, 3571, 5813, 3569, 3573, 3577, - 5813, 3575, 3579, 3581, 3583, 3580, 3588, 3590, 3597, 3584, - 3592, 3594, 3598, 3599, 3600, 3608, 3606, 5813, 3609, 3607, - 3613, 3614, 3618, 3611, 3616, 3619, 3626, 5813, 5813, 3629, - 5813, 3630, 3631, 3632, 5813, 3634, 3636, 3641, 3638, 3642, - 3644, 3652, 3645, 5813, 3654, 3640, 3656, 3658, 3659, 3662, - 3663, 3664, 3665, 3666, 3671, 5813, 3668, 3670, 3673, 3669, + 3515, 3512, 3511, 3514, 3518, 3520, 5920, 3521, 3522, 3525, + 3532, 3535, 3542, 3543, 3546, 3529, 3539, 3547, 3554, 5920, + 3549, 3552, 3550, 3551, 3563, 3553, 3564, 3560, 5920, 3565, + 3566, 3568, 5920, 3567, 3578, 3581, 3583, 3569, 3590, 3586, + 3588, 3591, 3587, 5920, 3594, 5920, 3571, 3595, 3600, 5920, + 3598, 3602, 3603, 3605, 3606, 3611, 3612, 3619, 3609, 3613, + 3620, 3621, 3623, 3625, 3632, 3624, 3628, 3631, 3633, 5920, + 3634, 3636, 3639, 3643, 3641, 3645, 3651, 3653, 3652, 5920, + 5920, 3656, 5920, 3659, 3660, 3661, 5920, 3663, 3666, 3670, + 3667, 3668, 3671, 3675, 3679, 5920, 3681, 3682, 3685, 3683, - 3678, 3683, 3679, 3685, 5813, 3689, 3693, 3692, 3696, 3697, - 5813, 3699, 5813, 3700, 3702, 3703, 3707, 3706, 5813, 3712, - 3713, 3717, 3719, 3721, 3720, 3723, 3724, 3730, 3731, 3738, - 3734, 3733, 3735, 5813, 3736, 3740, 3742, 3749, 3737, 3744, - 3753, 3756, 3757, 3758, 3763, 3760, 3767, 3769, 3771, 3773, - 3765, 5813, 3775, 3777, 3776, 3791, 3786, 3781, 5813, 3782, - 3796, 3798, 5813, 3789, 3788, 3800, 3805, 3792, 3799, 3806, - 3807, 3811, 5813, 3812, 3813, 3814, 3815, 3818, 3819, 5813, - 5813, 3827, 5813, 3829, 3816, 3830, 3831, 3832, 3838, 3837, - 3841, 3843, 3840, 3844, 3851, 3852, 3861, 3864, 3868, 3863, + 3689, 3691, 3693, 3694, 3690, 3696, 3695, 5920, 3697, 3700, + 3699, 3704, 3707, 3715, 3708, 3709, 5920, 3719, 3721, 3720, + 3725, 3726, 5920, 3728, 5920, 3731, 3732, 3734, 3740, 3735, + 5920, 3743, 3736, 3748, 3739, 3751, 3753, 3752, 3758, 3744, + 3759, 3766, 3764, 3761, 3767, 5920, 3768, 3770, 3772, 3776, + 3773, 3778, 3786, 3785, 3781, 3789, 3792, 3782, 3795, 3799, + 3793, 3801, 3803, 5920, 3804, 3807, 3808, 3818, 3810, 3811, + 5920, 3814, 3815, 3822, 5920, 3824, 3825, 3830, 3832, 3828, + 3833, 3834, 3835, 3838, 5920, 3836, 3840, 3841, 3842, 3854, + 3855, 5920, 5920, 3856, 5920, 3857, 3843, 3858, 3860, 3844, - 3867, 3853, 5813, 5813, 3870, 3871, 3874, 3877, 3878, 3880, - 3881, 3888, 3884, 3890, 3894, 3895, 3902, 5813, 3901, 3887, - 3904, 5813, 3885, 3898, 3906, 3909, 3911, 3912, 3915, 3914, - 3917, 3918, 3920, 3919, 3922, 3923, 3927, 3926, 3928, 3936, - 5813, 3940, 3937, 3938, 3941, 3943, 3944, 3947, 3949, 3950, - 5813, 3951, 3953, 3955, 3959, 3960, 3962, 3969, 3977, 3979, - 3965, 3973, 3981, 3983, 3985, 3988, 5813, 3989, 3987, 3990, - 3991, 3997, 3999, 4000, 4002, 4004, 4006, 4008, 4009, 4012, - 4016, 4013, 4017, 4018, 4020, 5813, 4024, 4031, 4021, 4034, - 4025, 4035, 4042, 4036, 4047, 4038, 4044, 4048, 4050, 5813, + 3865, 3868, 3870, 3872, 3876, 3877, 3880, 3883, 3888, 3890, + 3892, 3891, 3889, 3893, 5920, 5920, 3899, 3900, 3902, 3904, + 3905, 3907, 3909, 3914, 3912, 3920, 3923, 3924, 3916, 5920, + 3928, 3918, 3930, 5920, 3925, 3931, 3933, 3937, 3935, 3939, + 3942, 3941, 3943, 3944, 3946, 3947, 3949, 3954, 3953, 3955, + 3962, 3960, 3963, 3968, 3970, 5920, 3972, 3971, 3973, 3974, + 3975, 3977, 3982, 3983, 3984, 5920, 3978, 3988, 3991, 3985, + 4000, 3989, 4006, 4009, 4011, 4001, 4004, 4012, 4015, 4019, + 4020, 5920, 4021, 4022, 4023, 4028, 4030, 4032, 4033, 4035, + 4036, 4038, 4041, 4039, 4046, 4048, 4049, 4050, 4051, 4053, - 4051, 4053, 4054, 4056, 4062, 4055, 4058, 4063, 5813, 4065, - 4066, 4068, 4070, 4072, 4077, 4079, 4080, 4082, 4083, 4089, - 5813, 4087, 4088, 4096, 4094, 4097, 4100, 4098, 4102, 5813, - 4106, 4108, 4112, 4120, 4104, 4122, 4118, 4124, 4115, 4117, - 4131, 4126, 4132, 4133, 4136, 4137, 4144, 4149, 4146, 5813, - 4139, 5813, 4147, 4152, 4154, 4157, 4155, 5813, 4160, 4162, - 4164, 4165, 4161, 5813, 4167, 4168, 4171, 4169, 5813, 4182, - 4183, 4172, 4187, 4174, 4189, 5813, 4194, 4195, 4191, 4203, - 4206, 4202, 4204, 4207, 4205, 4209, 4210, 4211, 5813, 4215, - 4213, 4221, 4222, 4224, 4214, 4226, 4232, 4225, 5813, 4235, + 5920, 4055, 4058, 4061, 4067, 4064, 4062, 4070, 4074, 4077, + 4069, 4071, 4078, 4084, 5920, 4079, 4081, 4085, 4087, 4093, + 4089, 4094, 4095, 5920, 4102, 4096, 4098, 4103, 4106, 4107, + 4111, 4112, 4114, 4118, 4126, 5920, 4115, 4128, 4130, 4122, + 4119, 4121, 4131, 4134, 5920, 4138, 4140, 4139, 4155, 4141, + 4156, 4148, 4152, 4151, 4158, 4161, 4159, 4163, 4165, 4166, + 4167, 4179, 4183, 4178, 5920, 4169, 5920, 4184, 4185, 4194, + 4190, 4180, 5920, 4187, 4192, 4196, 4197, 4198, 5920, 4201, + 4204, 4206, 4205, 5920, 4211, 4210, 4209, 4216, 4219, 4222, + 5920, 4225, 4227, 4226, 4238, 4239, 4235, 4236, 4240, 4237, - 4228, 4236, 4237, 4239, 4241, 4242, 4250, 4246, 4245, 5813, - 4249, 4253, 4260, 4259, 4255, 5813, 5813, 4262, 4268, 4270, - 4264, 4271, 5813, 4274, 4281, 4277, 4280, 4282, 5813, 5813, - 4284, 5813, 4285, 5813, 4286, 4288, 5813, 5813, 4287, 4293, - 4294, 4296, 4298, 5813, 4306, 5813, 4308, 4309, 4295, 4307, - 4312, 5813, 4313, 4314, 4316, 5813, 4318, 4328, 4320, 4321, - 5813, 4324, 4325, 4330, 5813, 4333, 4340, 4337, 4331, 4341, - 4346, 4343, 4347, 4352, 4353, 4354, 4335, 4357, 4364, 4368, - 4370, 4372, 4373, 4356, 4375, 4376, 4378, 4381, 4382, 4383, - 4384, 4387, 4388, 4390, 4392, 4395, 4396, 4397, 4398, 4399, + 4242, 4243, 4244, 4252, 4247, 4248, 5920, 4251, 4254, 4259, + 4260, 4263, 4264, 4266, 4268, 4269, 5920, 4271, 4273, 4274, + 4275, 4277, 4278, 4280, 4292, 4290, 4279, 5920, 4283, 4295, + 4307, 4302, 4303, 5920, 5920, 4304, 4287, 4306, 4291, 4311, + 5920, 4315, 4314, 4313, 4321, 4322, 5920, 5920, 4324, 5920, + 4316, 5920, 4326, 4327, 5920, 5920, 4328, 4329, 4330, 4332, + 4339, 5920, 4342, 5920, 4350, 4345, 4336, 4347, 4348, 5920, + 4349, 4351, 4357, 5920, 4358, 4360, 4359, 4361, 5920, 4365, + 4362, 4366, 5920, 4370, 4373, 4374, 4375, 4378, 4380, 4386, + 4382, 4383, 4389, 4390, 4391, 4394, 4403, 4405, 4407, 4409, - 4409, 4401, 4402, 4412, 4415, 4405, 4413, 4416, 4417, 4418, - 4425, 4427, 4420, 4423, 5813, 4428, 4430, 4434, 4437, 4439, - 4442, 4443, 4445, 4450, 4454, 5813, 4458, 5813, 4460, 4451, - 4456, 4462, 5813, 4463, 4464, 4465, 4466, 4468, 4470, 4471, - 4472, 5813, 4475, 4476, 4479, 4485, 5813, 4491, 4493, 4478, - 4494, 4495, 4499, 4497, 4501, 4504, 4503, 4506, 4508, 4516, - 4509, 4511, 4513, 4518, 4517, 4521, 4524, 4358, 4531, 4533, - 4539, 5813, 4525, 5813, 4534, 4528, 4536, 4540, 4545, 4542, - 4546, 5813, 5813, 4549, 4551, 4553, 4555, 4556, 4558, 4559, - 5813, 4561, 4564, 4567, 4571, 5813, 4572, 4573, 4578, 5813, + 4398, 4400, 4412, 4413, 4415, 4419, 4420, 4421, 4422, 4424, + 4425, 4427, 4429, 4434, 4430, 4433, 4435, 4436, 4443, 4437, + 4439, 4450, 4446, 4451, 4452, 4453, 4454, 4460, 4461, 4458, + 4464, 4465, 5920, 4463, 4468, 4469, 4470, 4471, 4482, 4483, + 4476, 4494, 4495, 5920, 4497, 5920, 4499, 4484, 4501, 4486, + 5920, 4489, 4503, 4491, 4504, 4506, 4507, 4508, 4511, 4514, + 4516, 4517, 5920, 4520, 4522, 4526, 4529, 5920, 4530, 4537, + 4523, 4525, 4533, 4538, 4542, 4545, 4546, 4547, 4549, 4551, + 4558, 4554, 4555, 4556, 4559, 4557, 4561, 4568, 4565, 4579, + 4569, 4583, 5920, 4574, 5920, 4576, 4580, 4584, 4586, 4587, - 4575, 4579, 4581, 4583, 4580, 4590, 4586, 4594, 4595, 4596, - 4598, 5813, 5813, 5813, 5813, 4600, 4602, 4605, 4606, 4607, - 4609, 4612, 4614, 4610, 5813, 4616, 5813, 5813, 4617, 4623, - 4626, 4627, 4629, 4630, 4633, 4631, 5813, 4635, 4636, 4638, - 4644, 4646, 4648, 4651, 4652, 4653, 4654, 4661, 4660, 4662, - 4664, 4668, 4667, 4670, 5813, 5813, 4674, 4676, 4677, 4684, - 4681, 4685, 4688, 4689, 4691, 4692, 4694, 4695, 4697, 4698, - 5813, 4699, 4705, 5813, 4700, 5813, 4706, 4713, 4707, 4714, - 4715, 4717, 4719, 4721, 5813, 5813, 4716, 4722, 4728, 4732, - 4729, 4734, 4723, 4737, 4733, 5813, 4739, 5813, 4740, 4741, + 4588, 4590, 5920, 5920, 4591, 4594, 4601, 4589, 4595, 4603, + 4610, 5920, 4605, 4612, 4618, 4615, 5920, 4607, 4619, 4622, + 5920, 4623, 4624, 4625, 4631, 4626, 4637, 4638, 4632, 4634, + 4640, 4647, 5920, 5920, 5920, 5920, 4648, 4642, 4654, 4644, + 4655, 4651, 4656, 4659, 4661, 5920, 4663, 5920, 5920, 4666, + 4667, 4669, 4670, 4673, 4674, 4677, 4679, 5920, 4680, 4684, + 4685, 4682, 4692, 4699, 4694, 4700, 4678, 4688, 4708, 4704, + 4710, 4703, 4707, 4714, 4716, 5920, 5920, 4717, 4720, 4721, + 4728, 4726, 4729, 4738, 4733, 4735, 4736, 4739, 4741, 4723, + 4748, 4752, 4750, 4747, 5920, 4751, 4757, 5920, 4753, 5920, - 4750, 4744, 4757, 4759, 4761, 4763, 4756, 4765, 5813, 4758, - 4766, 5813, 4768, 4771, 4773, 5813, 4774, 4777, 4781, 5813, - 4783, 4786, 4784, 5813, 4792, 5813, 4778, 4794, 4793, 4801, - 5813, 4787, 4796, 5813, 4803, 4809, 4810, 4804, 5813, 4806, - 5813, 4811, 4815, 4818, 4821, 4812, 4823, 4816, 4825, 4826, - 4834, 4833, 4835, 5813, 5813, 4842, 4830, 4837, 4838, 4844, - 4851, 4846, 4848, 4855, 5813, 5813, 4856, 5813, 4859, 4860, - 5813, 4847, 4862, 4864, 4868, 4866, 4849, 4874, 4876, 4870, - 4877, 4892, 4878, 4880, 4893, 4895, 4898, 4900, 4887, 4902, - 4890, 4883, 4904, 4905, 4906, 5813, 4912, 4914, 4915, 5813, + 4758, 4761, 4725, 4762, 4764, 4767, 4768, 4770, 5920, 5920, + 4771, 4772, 4774, 4778, 4780, 4782, 4781, 4784, 4785, 5920, + 4786, 5920, 4787, 4794, 4789, 4795, 4803, 4806, 4808, 4810, + 4805, 4811, 5920, 4812, 4814, 5920, 4815, 4817, 4818, 5920, + 4822, 4825, 4829, 5920, 4835, 4826, 4832, 5920, 4839, 5920, + 4836, 4840, 4841, 4848, 5920, 4843, 4849, 5920, 4852, 4855, + 4857, 4846, 5920, 4844, 5920, 4858, 4865, 4866, 4869, 4861, + 4871, 4872, 4873, 4874, 4881, 4880, 4882, 5920, 5920, 4890, + 4877, 4883, 4887, 4892, 4899, 4894, 4897, 4896, 5920, 5920, + 4904, 5920, 4902, 4905, 5920, 4906, 4911, 4912, 4913, 4915, - 4919, 4916, 4921, 4922, 5813, 4929, 4930, 4931, 4932, 5813, - 4924, 4935, 4943, 4936, 4937, 4950, 4938, 4946, 5813, 5813, - 5813, 4948, 4957, 5813, 4959, 4954, 4960, 4961, 5813, 4962, - 4963, 5813, 5813, 4964, 4965, 4966, 4973, 5813, 4969, 5813, - 4970, 5813, 4972, 4978, 4987, 4984, 5813, 4990, 4996, 5813, - 4999, 5002, 5004, 5005, 4992, 4994, 5006, 5813, 4982, 5010, - 5016, 5008, 5009, 5017, 5018, 5019, 5026, 5022, 5025, 5813, - 5029, 5028, 5030, 5813, 5032, 5813, 5033, 5036, 5035, 5042, - 5040, 5034, 5044, 5054, 5041, 5058, 5045, 5813, 5061, 5063, - 5813, 5055, 5813, 5066, 5813, 5068, 5069, 5070, 5072, 5813, + 4916, 4920, 4922, 4923, 4924, 4925, 4926, 4932, 4944, 4928, + 4942, 4948, 4950, 4952, 4954, 4946, 4956, 4957, 4958, 4959, + 4960, 4963, 5920, 4965, 4966, 4967, 5920, 4971, 4972, 4974, + 4976, 5920, 4987, 4982, 4988, 4989, 5920, 4975, 4995, 4992, + 4990, 5000, 5007, 5003, 5002, 5920, 5920, 5920, 5004, 5013, + 5920, 5018, 5005, 5008, 5010, 5920, 5014, 5020, 5920, 5920, + 5021, 5022, 5024, 5035, 5920, 5025, 5920, 5026, 5920, 5034, + 5036, 5042, 5040, 5920, 5045, 5051, 5920, 5054, 5057, 5059, + 5060, 5048, 5061, 5062, 5920, 5070, 5066, 5072, 5074, 5063, + 5065, 5078, 5075, 5082, 5079, 5085, 5920, 5087, 5089, 5090, - 5074, 5071, 5075, 5078, 5813, 5079, 5081, 5083, 5813, 5813, - 5087, 5094, 5096, 4634, 5090, 5093, 5099, 5103, 5100, 5104, - 5105, 5112, 5108, 5109, 5110, 5115, 5117, 5123, 5813, 5813, - 5813, 5116, 5118, 5132, 5134, 5136, 5135, 5131, 5813, 5137, - 5140, 5141, 5150, 5146, 5148, 5813, 5152, 5143, 5156, 5813, - 5154, 5158, 5161, 5155, 5167, 5171, 5174, 5176, 5177, 5813, - 5179, 5813, 5813, 5168, 5813, 5159, 5180, 5183, 5184, 5813, - 5189, 5186, 5190, 5192, 5194, 5813, 5197, 5195, 5198, 5199, - 5813, 5813, 5207, 5813, 5209, 5211, 5212, 5219, 5218, 5214, - 5221, 5223, 5813, 5224, 5225, 5227, 5229, 5231, 5813, 5234, + 5096, 5088, 5098, 5092, 5920, 5100, 5920, 5101, 5102, 5105, + 5108, 5103, 5106, 5030, 5111, 5110, 5121, 5118, 5920, 5123, + 5127, 5920, 5124, 5920, 5129, 5920, 5130, 5131, 5132, 5133, + 5920, 5135, 5139, 5140, 5141, 5920, 5142, 5144, 5150, 5920, + 5920, 5151, 5161, 5152, 5153, 5165, 5167, 5154, 5169, 5162, + 5170, 5156, 5178, 5177, 5180, 5181, 5183, 5184, 5185, 5920, + 5920, 5920, 5190, 5189, 5197, 5194, 5195, 5205, 5200, 5920, + 5203, 5206, 5204, 5213, 5210, 5215, 5920, 5212, 5216, 5217, + 5219, 5221, 5222, 5226, 5920, 5230, 5237, 5233, 5225, 5240, + 5244, 5247, 5249, 5250, 5920, 5252, 5920, 5920, 5253, 5920, - 5233, 5235, 5236, 5239, 5238, 5243, 5246, 5248, 5813, 5813, - 5249, 5250, 5813, 5813, 5259, 5265, 5247, 5813, 5813, 5813, - 5271, 5813, 5273, 5277, 5281, 5285, 5262, 5813, 5287, 5276, - 5284, 5813, 5268, 5280, 5290, 5292, 5813, 5813, 5289, 5196, - 5293, 5296, 5301, 5813, 5299, 5302, 5303, 5307, 5309, 5310, - 5313, 5312, 5328, 5326, 5315, 5319, 5323, 5330, 5331, 5329, - 5333, 5337, 5813, 5813, 5339, 5813, 5813, 5346, 5350, 5352, - 5354, 5356, 5358, 5360, 5813, 5361, 5363, 5364, 5365, 5347, - 5813, 5366, 5369, 5371, 5374, 5372, 5375, 5378, 5380, 5813, - 5813, 5381, 5388, 5382, 5389, 5383, 5813, 5392, 5400, 5396, + 5254, 5256, 5257, 5258, 5920, 5261, 5263, 5262, 5264, 5266, + 5920, 5274, 5267, 5269, 5270, 5920, 5920, 5281, 5920, 5284, + 5285, 5286, 5295, 5291, 5293, 5297, 5294, 5920, 5292, 5298, + 5302, 5304, 5305, 5920, 5306, 5308, 5309, 5310, 5313, 5317, + 5319, 5320, 5321, 5920, 5323, 5315, 5338, 5334, 5920, 5322, + 5340, 5920, 5920, 5325, 5344, 5345, 5920, 5920, 5920, 5347, + 5920, 5351, 5357, 5361, 5365, 5348, 5920, 5367, 5356, 5364, + 5920, 5360, 5368, 5370, 5372, 5920, 5920, 5369, 5376, 5373, + 5381, 5382, 5920, 5384, 5386, 5391, 5399, 5401, 5389, 5403, + 5405, 5412, 5385, 5393, 5407, 5409, 5410, 5416, 5413, 5420, - 5397, 5398, 5403, 5404, 5813, 5407, 5813, 5813, 5813, 5813, - 5813, 5813, 5813, 5813, 5406, 5813, 5405, 5412, 5414, 5416, - 5813, 5419, 5423, 5424, 5425, 5426, 5813, 5427, 5430, 5429, - 5341, 5431, 5435, 5438, 5433, 5437, 5443, 5439, 5447, 5444, - 5448, 5449, 5813, 5813, 5813, 5453, 5456, 5458, 5460, 5471, - 5472, 5475, 5478, 5461, 5463, 5479, 5481, 5484, 5466, 5485, - 5493, 5488, 5490, 5495, 5492, 5496, 5498, 5813, 5499, 5813, - 5501, 5813, 5813, 5504, 5505, 5508, 5509, 5517, 5518, 5513, - 5520, 5521, 5523, 5813, 5524, 5526, 5813, 5525, 5530, 5813, - 5529, 5531, 5532, 5535, 5537, 5538, 5542, 5553, 5813, 5541, + 5429, 5425, 5427, 5434, 5435, 5920, 5920, 5437, 5920, 5920, + 5439, 5442, 5444, 5446, 5448, 5450, 5452, 5920, 5387, 5454, + 5455, 5456, 5457, 5920, 5459, 5461, 5458, 5462, 5467, 5465, + 5469, 5471, 5920, 5920, 5463, 5480, 5472, 5485, 5474, 5920, + 5487, 5482, 5488, 5489, 5491, 5493, 5496, 5920, 5495, 5497, + 5920, 5920, 5499, 5920, 5920, 5920, 5920, 5920, 5920, 5920, + 5920, 5500, 5920, 5504, 5508, 5516, 5519, 5920, 5505, 5513, + 5424, 5509, 5520, 5920, 5521, 5524, 5525, 5531, 5523, 5526, + 5532, 5536, 5539, 5537, 5540, 5541, 5542, 5546, 5543, 5547, + 5549, 5920, 5920, 5920, 5548, 5550, 5560, 5552, 5569, 5571, - 5544, 5552, 5555, 5559, 5566, 5567, 5565, 5569, 5572, 5556, - 5579, 5581, 5578, 5585, 5813, 5582, 5576, 5587, 5588, 5589, - 5596, 5591, 5592, 5813, 5597, 5813, 5600, 5602, 5601, 5593, - 5603, 5604, 5615, 5613, 5619, 5813, 5609, 5620, 5623, 5624, - 5626, 5628, 5629, 5630, 5638, 5634, 5641, 5645, 5640, 5646, - 5631, 5651, 5648, 5813, 5655, 5652, 5813, 5657, 5658, 5659, - 5660, 5664, 5813, 5669, 5661, 5666, 5672, 5675, 5670, 5813, - 5682, 5684, 5686, 5813, 5687, 5813, 5813, 5689, 5676, 5688, - 5691, 5697, 5813, 5813, 5813, 5721, 5728, 5735, 5742, 5749, - 88, 5756, 5763, 5770, 5777, 5784, 5791, 5798, 5805 + 5574, 5576, 5563, 5566, 5577, 5578, 5579, 5581, 5585, 5593, + 5588, 5589, 5590, 5591, 5597, 5592, 5594, 5599, 5920, 5603, + 5920, 5604, 5920, 5920, 5609, 5614, 5612, 5605, 5616, 5623, + 5619, 5621, 5625, 5626, 5628, 5630, 5920, 5632, 5635, 5920, + 5636, 5637, 5920, 5638, 5640, 5642, 5639, 5643, 5646, 5649, + 5657, 5648, 5920, 5920, 5651, 5659, 5660, 5664, 5667, 5674, + 5669, 5673, 5675, 5676, 5666, 5688, 5920, 5684, 5686, 5690, + 5920, 5692, 5687, 5693, 5694, 5695, 5703, 5698, 5699, 5920, + 5701, 5920, 5705, 5707, 5710, 5708, 5709, 5711, 5720, 5718, + 5722, 5920, 5725, 5729, 5726, 5731, 5733, 5736, 5737, 5738, + 5740, 5742, 5746, 5750, 5752, 5753, 5743, 5756, 5754, 5920, + 5764, 5755, 5920, 5765, 5766, 5758, 5767, 5768, 5920, 5776, + 5772, 5778, 5779, 5782, 5783, 5920, 5785, 5788, 5789, 5920, + 5793, 5920, 5920, 5794, 5792, 5795, 5801, 5803, 5920, 5920, + 5920, 5828, 5835, 5842, 5849, 5856, 88, 5863, 5870, 5877, + 5884, 5891, 5898, 5905, 5912 } ; -static const flex_int16_t yy_def[3000] = +static const flex_int16_t yy_def[3056] = { 0, - 2985, 1, 2986, 2986, 2987, 2987, 2988, 2988, 2989, 2989, - 2990, 2990, 2985, 2991, 2985, 2985, 2985, 2985, 2992, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2993, 2985, 2985, 2985, 2993, 2994, 2985, 2985, - 2985, 2994, 2995, 2985, 2985, 2985, 2985, 2995, 2996, 2985, - 2985, 2985, 2996, 2997, 2985, 2998, 2985, 2997, 2997, 2991, - 2991, 2985, 2999, 2992, 2999, 2992, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, + 3041, 1, 3042, 3042, 3043, 3043, 3044, 3044, 3045, 3045, + 3046, 3046, 3041, 3047, 3041, 3041, 3041, 3041, 3048, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3049, 3041, 3041, 3041, 3049, 3050, 3041, 3041, + 3041, 3050, 3051, 3041, 3041, 3041, 3041, 3051, 3052, 3041, + 3041, 3041, 3052, 3053, 3041, 3054, 3041, 3053, 3053, 3047, + 3047, 3041, 3055, 3048, 3055, 3048, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2993, 2993, 2994, 2994, 2995, 2995, 2985, 2996, 2996, 2997, - 2997, 2998, 2998, 2997, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3049, 3049, 3050, 3050, 3051, 3051, 3041, 3052, 3052, 3053, + 3053, 3054, 3054, 3053, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2997, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3053, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2997, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3053, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, - 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2985, 2991, 2997, 2991, 2991, 2991, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, + 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3041, 3047, 3053, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2997, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2985, 2991, 2985, 2985, 2991, 2985, 2985, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3053, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3041, 3047, 3041, 3041, 3047, 3041, 3041, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2997, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2985, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3053, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3041, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2985, 2991, 2985, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2985, 2985, 2991, 2991, 2991, 2991, - 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2997, 2991, + 3047, 3047, 3047, 3047, 3041, 3047, 3041, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3041, 3041, 3047, 3047, 3047, + 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3053, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, - 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, + 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2985, 2991, 2985, 2991, 2991, 2991, - 2991, 2991, 2985, 2991, 2985, 2991, 2991, 2991, 2991, 2985, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, - 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, + 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, + 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3041, + 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3041, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2985, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, + 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3041, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2985, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, + 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, + 3047, 3047, 3047, 3041, 3047, 3041, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2985, 2985, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, - 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, + 3041, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, + 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, - 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2985, 2991, 2985, 2991, 2991, 2991, - 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2985, 2991, - 2985, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, + 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, + 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3041, 3047, 3041, 3047, 3047, 3047, 3041, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, + 3041, 3047, 3041, 3047, 3047, 3047, 3041, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, - 2985, 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2985, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, - 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2985, - 2985, 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, + 3047, 3047, 3041, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, + 3041, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3047, 3041, 3041, 3047, 3041, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2985, 2985, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, - 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3041, 3041, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, + 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, - 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, - 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2985, 2991, - 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, + 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3041, 3047, 3041, 3047, 3047, 3047, + 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3041, 3047, + 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, + 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, - 2991, 2991, 2991, 2991, 2991, 2985, 2985, 2991, 2991, 2991, - 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2985, 2985, - 2991, 2985, 2991, 2985, 2991, 2991, 2985, 2985, 2991, 2991, - 2991, 2991, 2991, 2985, 2991, 2985, 2991, 2991, 2991, 2991, - 2991, 2985, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, - 2985, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, + 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, + 3047, 3047, 3047, 3041, 3041, 3047, 3047, 3047, 3047, 3047, + 3041, 3047, 3047, 3047, 3047, 3047, 3041, 3041, 3047, 3041, + 3047, 3041, 3047, 3047, 3041, 3041, 3047, 3047, 3047, 3047, + 3047, 3041, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3041, + 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3041, 3047, + 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2985, 2991, 2991, - 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2985, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2985, 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2985, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2985, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2985, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3041, 3047, 3041, 3047, 3047, 3047, 3047, + 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3041, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3041, 3047, 3041, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2985, 2985, 2985, 2985, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2985, 2991, 2985, 2985, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2985, 2985, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2985, 2991, 2991, 2985, 2991, 2985, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2985, 2985, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2985, 2991, 2991, + 3047, 3047, 3041, 3041, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3041, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, + 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3041, 3041, 3041, 3041, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3041, 3041, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3041, 3041, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3041, 3047, 3041, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, - 2991, 2985, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2985, - 2991, 2991, 2991, 2985, 2991, 2985, 2991, 2991, 2991, 2991, - 2985, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2985, 2991, - 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2985, 2985, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2985, 2985, 2991, 2985, 2991, 2991, - 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2985, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3041, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, + 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3041, 3047, 3047, 3041, 3047, 3047, 3047, 3041, + 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3041, 3047, 3041, + 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3041, 3047, 3047, + 3047, 3047, 3041, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3041, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3041, + 3047, 3041, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2985, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2985, - 2985, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2985, 2991, - 2991, 2985, 2985, 2991, 2991, 2991, 2991, 2985, 2991, 2985, - 2991, 2985, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2985, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, - 2991, 2991, 2991, 2985, 2991, 2985, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, - 2985, 2991, 2985, 2991, 2985, 2991, 2991, 2991, 2991, 2985, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3041, 3047, 3047, 3047, 3041, 3047, 3047, 3047, + 3047, 3041, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3041, 3041, 3041, 3047, 3047, + 3041, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3041, 3041, + 3047, 3047, 3047, 3047, 3041, 3047, 3041, 3047, 3041, 3047, + 3047, 3047, 3047, 3041, 3047, 3047, 3041, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2985, 2985, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2985, - 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, - 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2985, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, - 2991, 2985, 2985, 2991, 2985, 2991, 2991, 2991, 2991, 2985, - 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, - 2985, 2985, 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2985, 2991, + 3047, 3047, 3047, 3047, 3041, 3047, 3041, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, + 3047, 3041, 3047, 3041, 3047, 3041, 3047, 3047, 3047, 3047, + 3041, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3041, + 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, + 3041, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, + 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3041, 3047, 3041, 3041, 3047, 3041, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2985, - 2991, 2991, 2985, 2985, 2991, 2991, 2991, 2985, 2985, 2985, - 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, - 2991, 2985, 2991, 2991, 2991, 2991, 2985, 2985, 2991, 2991, - 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2985, 2985, 2991, 2985, 2985, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, - 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, - 2985, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, + 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, + 3041, 3047, 3047, 3047, 3047, 3041, 3041, 3047, 3041, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, + 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3041, 3047, + 3047, 3041, 3041, 3047, 3047, 3047, 3041, 3041, 3041, 3047, + 3041, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, + 3041, 3047, 3047, 3047, 3047, 3041, 3041, 3047, 3047, 3047, + 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2985, 2991, 2985, 2985, 2985, 2985, - 2985, 2985, 2985, 2985, 2991, 2985, 2991, 2991, 2991, 2991, - 2985, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2985, 2985, 2985, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2985, - 2991, 2985, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2985, 2991, 2991, 2985, 2991, 2991, 2985, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2985, 2991, + 3047, 3047, 3047, 3047, 3047, 3041, 3041, 3047, 3041, 3041, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, + 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3041, 3041, 3047, 3047, 3047, 3047, 3047, 3041, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, + 3041, 3041, 3047, 3041, 3041, 3041, 3041, 3041, 3041, 3041, + 3041, 3047, 3041, 3047, 3047, 3047, 3047, 3041, 3047, 3047, + 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3041, 3041, 3041, 3047, 3047, 3047, 3047, 3047, 3047, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2985, 2991, 2985, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2985, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, 2991, - 2991, 2991, 2991, 2985, 2991, 2991, 2985, 2991, 2991, 2991, - 2991, 2991, 2985, 2991, 2991, 2991, 2991, 2991, 2991, 2985, - 2991, 2991, 2991, 2985, 2991, 2985, 2985, 2991, 2991, 2991, - 2991, 2991, 2985, 2985, 0, 2985, 2985, 2985, 2985, 2985, - 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985 + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, + 3041, 3047, 3041, 3041, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3041, + 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3041, 3041, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, + 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, + 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, + 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3047, 3041, + 3047, 3047, 3041, 3047, 3047, 3047, 3047, 3047, 3041, 3047, + 3047, 3047, 3047, 3047, 3047, 3041, 3047, 3047, 3047, 3041, + 3047, 3041, 3041, 3047, 3047, 3047, 3047, 3047, 3041, 3041, + 0, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, + 3041, 3041, 3041, 3041, 3041 } ; -static const flex_int16_t yy_nxt[5854] = +static const flex_int16_t yy_nxt[5961] = { 0, 14, 15, 16, 17, 18, 19, 18, 14, 14, 14, 14, 14, 18, 20, 21, 22, 23, 24, 25, 26, @@ -1550,7 +1569,7 @@ static const flex_int16_t yy_nxt[5854] = 71, 722, 71, 71, 71, 71, 729, 727, 738, 733, 71, 71, 71, 736, 71, 731, 739, 737, 71, 735, - 71, 734, 863, 740, 741, 742, 71, 71, 71, 743, + 71, 734, 864, 740, 741, 742, 71, 71, 71, 743, 745, 747, 746, 744, 71, 749, 71, 71, 71, 748, 71, 71, 71, 750, 752, 71, 758, 751, 71, 753, 71, 754, 71, 71, 71, 756, 757, 71, 755, 761, @@ -1572,486 +1591,497 @@ static const flex_int16_t yy_nxt[5854] = 71, 71, 838, 836, 829, 830, 834, 71, 71, 71, 71, 831, 71, 840, 71, 844, 71, 71, 71, 71, - 837, 71, 841, 71, 845, 846, 71, 839, 888, 71, - 71, 71, 843, 71, 850, 847, 71, 842, 851, 71, - 857, 852, 858, 849, 848, 855, 71, 861, 853, 71, - 856, 854, 71, 860, 71, 859, 71, 862, 71, 867, - 71, 71, 71, 71, 71, 71, 875, 71, 865, 71, - 864, 891, 879, 880, 71, 71, 882, 883, 866, 71, - 868, 869, 877, 870, 876, 878, 871, 71, 71, 884, - 71, 872, 71, 71, 881, 885, 886, 873, 874, 71, + 837, 71, 841, 71, 845, 846, 71, 839, 71, 71, + 71, 71, 843, 71, 859, 847, 71, 842, 71, 858, + 861, 856, 71, 849, 848, 71, 857, 860, 71, 862, + 850, 71, 863, 867, 851, 71, 865, 852, 71, 71, + 868, 71, 71, 876, 853, 854, 71, 855, 71, 866, + 71, 869, 870, 71, 871, 882, 880, 872, 71, 878, + 877, 151, 873, 881, 71, 71, 883, 879, 874, 875, + 71, 885, 71, 884, 71, 71, 71, 886, 887, 888, - 71, 71, 71, 71, 887, 71, 895, 71, 71, 71, - 894, 890, 889, 71, 71, 898, 71, 71, 902, 904, - 71, 892, 893, 896, 71, 899, 923, 897, 900, 71, - 905, 901, 71, 908, 903, 906, 71, 907, 909, 71, - 71, 911, 71, 71, 71, 910, 912, 71, 913, 71, - 915, 71, 916, 71, 71, 71, 71, 914, 71, 71, - 71, 919, 917, 922, 71, 920, 925, 71, 924, 71, - 71, 71, 71, 918, 929, 71, 71, 71, 921, 927, - 928, 932, 71, 71, 930, 931, 926, 71, 71, 937, - 71, 933, 71, 939, 938, 71, 935, 71, 71, 71, + 71, 71, 889, 71, 71, 71, 71, 892, 890, 71, + 896, 71, 71, 895, 71, 71, 899, 71, 71, 71, + 891, 903, 905, 71, 893, 894, 897, 71, 898, 901, + 900, 71, 906, 934, 71, 909, 904, 907, 71, 908, + 902, 71, 910, 71, 71, 912, 913, 71, 71, 911, + 71, 71, 71, 914, 916, 71, 917, 71, 915, 71, + 918, 71, 71, 71, 923, 71, 920, 71, 926, 921, + 71, 71, 71, 71, 71, 71, 924, 919, 925, 71, + 71, 928, 922, 71, 929, 930, 932, 71, 931, 71, + 927, 71, 933, 71, 940, 71, 71, 71, 935, 938, - 71, 936, 71, 944, 946, 940, 71, 942, 934, 947, - 71, 945, 71, 71, 71, 71, 941, 949, 71, 71, - 71, 71, 71, 943, 71, 960, 957, 948, 71, 955, - 71, 71, 71, 71, 950, 951, 953, 71, 952, 954, - 71, 961, 958, 71, 956, 962, 965, 959, 71, 963, - 71, 964, 71, 967, 968, 71, 71, 966, 71, 71, - 71, 970, 71, 71, 71, 977, 972, 979, 71, 981, - 969, 71, 71, 71, 982, 71, 971, 71, 978, 973, - 71, 975, 974, 976, 71, 71, 71, 71, 980, 983, - 71, 984, 987, 71, 989, 990, 985, 71, 988, 993, + 936, 71, 937, 71, 939, 71, 943, 71, 71, 947, + 941, 945, 948, 71, 71, 942, 71, 71, 71, 946, + 71, 950, 71, 71, 949, 944, 71, 71, 71, 71, + 961, 956, 958, 71, 71, 951, 71, 952, 953, 71, + 71, 71, 954, 955, 71, 959, 963, 71, 960, 957, + 962, 71, 964, 965, 967, 71, 971, 966, 969, 71, + 968, 71, 71, 71, 970, 71, 71, 978, 71, 980, + 973, 71, 71, 71, 982, 71, 983, 71, 71, 71, + 71, 972, 71, 974, 988, 976, 979, 975, 977, 71, + 986, 981, 71, 984, 71, 990, 985, 991, 987, 71, - 991, 71, 71, 994, 986, 996, 71, 71, 992, 71, - 71, 999, 151, 71, 71, 998, 71, 1002, 1001, 71, - 71, 71, 995, 71, 71, 997, 1005, 71, 1000, 71, - 71, 71, 1017, 71, 71, 1020, 71, 1018, 71, 71, - 1004, 1003, 1006, 1008, 71, 71, 71, 1009, 1007, 1019, - 1022, 1010, 71, 1023, 71, 1011, 71, 1012, 1024, 1025, - 1027, 1013, 71, 1014, 1021, 1028, 71, 71, 1015, 71, - 1026, 1030, 71, 1016, 71, 71, 1029, 1032, 71, 1034, - 71, 71, 71, 71, 1031, 1039, 1040, 1033, 1038, 1035, - 71, 71, 71, 1042, 1037, 1041, 71, 1043, 71, 1036, + 71, 71, 992, 71, 995, 71, 997, 71, 71, 71, + 71, 71, 71, 989, 994, 71, 999, 71, 993, 1000, + 151, 1002, 71, 1003, 1001, 996, 998, 71, 71, 71, + 71, 71, 1006, 71, 1004, 1005, 71, 1018, 71, 1021, + 71, 71, 1019, 71, 1009, 71, 71, 1007, 71, 1023, + 71, 1010, 71, 1008, 1011, 71, 1020, 1026, 1012, 71, + 1013, 1024, 1025, 71, 1014, 1033, 1015, 71, 1022, 1028, + 71, 1016, 71, 1027, 1029, 71, 1017, 1030, 71, 1036, + 71, 71, 1031, 71, 1038, 1034, 1037, 1044, 71, 71, + 71, 71, 1042, 1039, 1032, 1035, 1041, 1040, 71, 1043, - 1045, 71, 71, 71, 71, 1044, 71, 1055, 1046, 71, - 1047, 1059, 71, 1054, 71, 1048, 71, 1049, 1056, 71, - 1058, 71, 1060, 1050, 1057, 71, 1064, 71, 1051, 1052, - 1061, 1066, 71, 71, 71, 1053, 1065, 71, 71, 1070, - 1062, 1067, 71, 71, 1063, 71, 71, 1069, 1071, 71, - 71, 1076, 1068, 71, 71, 1073, 71, 71, 1074, 71, - 71, 1072, 1077, 71, 1079, 71, 1075, 71, 71, 71, - 71, 71, 71, 1078, 1081, 71, 1080, 1083, 1084, 1085, - 1088, 1086, 1090, 1082, 1087, 71, 71, 1089, 71, 71, - 71, 71, 1091, 71, 71, 71, 1096, 71, 1097, 1098, + 71, 1045, 1046, 71, 71, 71, 71, 71, 71, 1058, + 1048, 1047, 71, 71, 1061, 1057, 71, 71, 1049, 71, + 1050, 1059, 1062, 71, 1060, 1051, 149, 1052, 71, 71, + 1064, 1063, 71, 1053, 1067, 71, 1068, 1069, 1054, 1055, + 71, 71, 71, 71, 1070, 1056, 1073, 1065, 1066, 71, + 71, 71, 71, 71, 1074, 1072, 71, 1079, 71, 1071, + 1076, 71, 1077, 71, 71, 71, 71, 1080, 71, 1075, + 1082, 71, 1078, 71, 71, 1091, 71, 71, 71, 1089, + 1081, 71, 1084, 1086, 1083, 1087, 1085, 1088, 71, 71, + 71, 1090, 71, 1092, 71, 71, 71, 71, 71, 71, - 71, 1100, 1093, 1101, 1092, 1095, 1099, 1094, 1102, 71, - 71, 1104, 71, 71, 71, 1106, 1105, 71, 1107, 71, - 71, 71, 1108, 1114, 71, 71, 1103, 1109, 71, 71, - 1116, 71, 1110, 71, 1112, 71, 71, 71, 1111, 1113, - 1118, 71, 1122, 1117, 1120, 1115, 71, 1119, 71, 71, - 71, 1123, 1121, 71, 1125, 1126, 71, 71, 1132, 71, - 71, 1131, 1128, 71, 1124, 1127, 1130, 71, 71, 71, - 1136, 71, 1133, 1129, 1135, 71, 71, 71, 71, 71, - 71, 1140, 1142, 1143, 1147, 1144, 1134, 71, 71, 71, - 71, 71, 1141, 1137, 71, 1138, 1145, 1139, 71, 1146, + 71, 1099, 1093, 1100, 1096, 1101, 1102, 71, 1103, 1094, + 1098, 1095, 1097, 1104, 71, 1106, 1107, 71, 71, 71, + 1111, 1108, 71, 71, 71, 1109, 71, 1105, 1110, 71, + 71, 1117, 1112, 71, 1119, 71, 71, 71, 71, 71, + 71, 1121, 1115, 1113, 1114, 1116, 71, 71, 147, 1123, + 1120, 71, 1122, 1118, 71, 71, 1125, 71, 71, 1126, + 1124, 71, 1128, 1127, 1131, 71, 1129, 1130, 71, 1134, + 1135, 71, 71, 71, 1133, 71, 71, 71, 1139, 1138, + 71, 1132, 1136, 71, 71, 71, 71, 1145, 1143, 1146, + 1137, 71, 71, 71, 71, 71, 1147, 1148, 1140, 1144, - 1150, 71, 71, 1152, 71, 1148, 71, 1151, 71, 71, - 1153, 71, 71, 71, 1156, 1157, 71, 1154, 1149, 71, - 71, 71, 1162, 1163, 1158, 71, 71, 1155, 71, 71, - 1165, 1160, 1166, 71, 1159, 71, 1164, 1170, 71, 1161, - 71, 71, 71, 71, 71, 1167, 71, 1176, 71, 1168, - 1169, 1172, 71, 71, 71, 71, 1182, 71, 1171, 1180, - 71, 71, 1173, 1197, 71, 1175, 1177, 1179, 1178, 1174, - 1181, 1184, 1185, 71, 71, 1187, 71, 71, 71, 1186, - 1183, 1188, 71, 71, 71, 71, 71, 71, 71, 1191, - 71, 151, 71, 71, 1194, 71, 1189, 1190, 71, 71, + 71, 1150, 1141, 71, 1142, 1149, 71, 71, 1153, 1155, + 71, 1154, 1151, 71, 71, 71, 71, 71, 71, 71, + 1159, 1160, 1156, 1152, 1157, 71, 71, 71, 71, 1165, + 1161, 1166, 71, 1168, 1158, 71, 71, 71, 1163, 1169, + 71, 71, 71, 1162, 1173, 71, 1164, 1167, 71, 71, + 71, 71, 71, 1172, 71, 1170, 1171, 71, 1175, 1179, + 71, 71, 71, 1174, 71, 71, 71, 1183, 1180, 1176, + 146, 1178, 1181, 1182, 1184, 1187, 1177, 1185, 71, 1188, + 1192, 71, 71, 71, 1186, 71, 71, 1189, 1190, 71, + 71, 71, 71, 71, 1191, 1194, 71, 1193, 71, 71, - 1192, 71, 71, 1195, 1201, 1193, 1198, 1203, 1209, 1196, - 1200, 1199, 71, 1207, 71, 71, 1204, 71, 1205, 1202, - 1208, 1206, 71, 71, 71, 1211, 71, 71, 1210, 1214, - 71, 71, 1213, 1219, 71, 1212, 1216, 71, 1217, 71, - 71, 71, 1220, 71, 1221, 1215, 1223, 1224, 71, 1218, - 71, 71, 71, 71, 71, 71, 71, 1225, 71, 71, - 1222, 1231, 71, 71, 71, 1226, 1227, 1229, 1230, 71, - 1232, 1228, 71, 71, 71, 1233, 71, 1237, 1236, 1241, - 1234, 1235, 1240, 71, 1238, 71, 71, 71, 1242, 1239, - 71, 1243, 1245, 71, 1247, 71, 1244, 71, 1246, 1248, + 1197, 1200, 71, 71, 71, 71, 1195, 71, 71, 1210, + 71, 1196, 1206, 1198, 1203, 1199, 1204, 1201, 71, 71, + 71, 1207, 1202, 1208, 1211, 1205, 1209, 1212, 71, 71, + 71, 71, 1214, 1215, 71, 71, 1213, 71, 71, 1216, + 1219, 71, 71, 1218, 1224, 71, 1221, 71, 71, 1217, + 71, 71, 1225, 1222, 71, 1226, 1220, 1223, 71, 1228, + 1230, 71, 1229, 71, 71, 71, 71, 71, 1227, 71, + 71, 71, 71, 71, 1236, 71, 1231, 1234, 1232, 1241, + 71, 1235, 1237, 1233, 71, 71, 71, 71, 1238, 1247, + 1240, 1246, 1239, 71, 1248, 1242, 1245, 71, 71, 71, - 71, 71, 1252, 71, 149, 1261, 1260, 1250, 1251, 1249, - 71, 71, 71, 1262, 1265, 1253, 1259, 71, 1254, 1255, - 71, 71, 1263, 1256, 71, 1268, 71, 71, 71, 1257, - 1264, 1266, 1267, 1258, 71, 1270, 71, 71, 71, 1271, - 71, 1272, 71, 71, 71, 71, 1280, 1281, 1277, 1269, - 71, 1275, 71, 71, 71, 1282, 1274, 1273, 1278, 71, - 1276, 71, 1290, 1279, 71, 1283, 71, 1289, 1284, 71, - 71, 71, 1294, 1285, 1292, 1286, 71, 1287, 1296, 1288, - 1291, 71, 71, 1297, 71, 1295, 1293, 1299, 71, 71, - 71, 71, 71, 1305, 71, 1306, 71, 71, 1301, 71, + 71, 1252, 71, 1250, 1243, 1244, 1253, 71, 71, 71, + 1257, 1251, 71, 1249, 71, 71, 1255, 71, 1266, 1254, + 1268, 1256, 71, 1265, 71, 1264, 1269, 1258, 71, 1267, + 1259, 1260, 1270, 71, 71, 1261, 71, 71, 71, 1271, + 71, 1262, 1272, 71, 1273, 1263, 71, 1275, 71, 71, + 71, 1276, 71, 1277, 1274, 71, 1278, 1282, 1279, 1280, + 71, 1285, 1286, 71, 1295, 71, 71, 71, 71, 1281, + 1287, 71, 1289, 1284, 1283, 1288, 71, 1290, 71, 1291, + 71, 1292, 1297, 1293, 71, 1294, 71, 1296, 71, 71, + 71, 71, 71, 1301, 71, 1298, 1304, 1300, 1302, 71, - 71, 71, 1300, 1298, 1307, 1309, 1304, 71, 71, 1302, - 1303, 1308, 71, 71, 71, 1310, 1311, 71, 1314, 1315, - 71, 1317, 71, 71, 71, 1318, 1312, 1319, 71, 1316, - 71, 1323, 71, 1320, 71, 71, 1321, 1313, 71, 1322, - 1325, 71, 71, 1326, 71, 1330, 71, 71, 71, 1327, - 71, 1332, 71, 71, 1324, 71, 1328, 1334, 71, 1329, - 1336, 71, 1335, 71, 1338, 71, 71, 1331, 71, 71, - 1333, 1340, 71, 1337, 1341, 71, 1342, 1343, 1339, 71, - 1344, 71, 1345, 1347, 1346, 71, 71, 71, 1351, 1352, - 1354, 1348, 71, 1349, 71, 71, 71, 1353, 71, 71, + 71, 71, 1310, 1306, 1299, 71, 1305, 71, 71, 1307, + 71, 1303, 71, 1311, 71, 1309, 71, 71, 1312, 1308, + 71, 1313, 1314, 1317, 71, 1316, 1320, 71, 1315, 1319, + 71, 71, 1322, 71, 71, 71, 1323, 71, 1324, 71, + 1328, 71, 1325, 71, 71, 1318, 1321, 71, 1327, 1326, + 1330, 71, 71, 1331, 71, 1335, 71, 71, 71, 1332, + 71, 1337, 71, 1329, 71, 1333, 71, 1339, 1334, 71, + 71, 1341, 71, 1340, 71, 1343, 71, 1336, 71, 1345, + 1338, 1346, 71, 71, 1342, 1344, 1347, 1348, 1349, 71, + 1350, 71, 71, 71, 71, 71, 1351, 1356, 1357, 1353, - 1350, 71, 1358, 71, 71, 71, 71, 1355, 1362, 1363, - 71, 1365, 1357, 71, 71, 71, 1364, 71, 1356, 71, - 71, 71, 71, 71, 1359, 1360, 71, 1366, 71, 1361, - 71, 1372, 1369, 1367, 71, 1370, 71, 1377, 71, 1368, - 1371, 1376, 71, 1373, 71, 147, 1375, 1379, 1381, 71, - 71, 1374, 71, 1382, 71, 71, 71, 1378, 71, 1384, - 1385, 71, 71, 1380, 1392, 71, 1394, 1383, 71, 1386, - 71, 1387, 71, 1388, 71, 1390, 1389, 71, 1391, 1393, - 1397, 1395, 71, 71, 71, 1396, 71, 71, 1400, 71, - 71, 1402, 71, 71, 1398, 71, 1407, 1408, 71, 71, + 71, 1354, 71, 71, 71, 1358, 1359, 71, 1355, 71, + 1352, 1360, 71, 1363, 71, 71, 71, 71, 1367, 1368, + 1362, 71, 1370, 71, 71, 71, 1361, 1369, 71, 71, + 71, 71, 71, 71, 1377, 1364, 1365, 1371, 71, 71, + 1366, 71, 1374, 1372, 71, 1375, 71, 1382, 71, 1373, + 1376, 1381, 71, 71, 71, 1386, 71, 1384, 1378, 1380, + 1387, 71, 71, 1389, 1379, 71, 71, 1383, 71, 71, + 1390, 1397, 1385, 71, 1388, 71, 71, 71, 1399, 1391, + 1400, 1392, 1395, 1393, 71, 1396, 1394, 1398, 71, 1402, + 71, 71, 71, 71, 1403, 71, 1407, 71, 71, 1401, - 1399, 71, 1401, 1404, 71, 1411, 71, 1403, 1405, 71, - 1406, 71, 71, 1412, 71, 71, 1409, 71, 1410, 71, - 1414, 71, 1418, 1413, 1415, 71, 1419, 1416, 71, 71, - 1420, 71, 1423, 1417, 71, 1428, 1426, 1422, 71, 1421, - 1425, 71, 1429, 1427, 1424, 71, 1430, 71, 71, 71, - 1431, 1432, 71, 71, 71, 71, 1434, 1433, 71, 71, - 71, 1439, 71, 71, 71, 71, 1438, 71, 71, 1436, - 1442, 1441, 1435, 1437, 1445, 71, 71, 1450, 1443, 1446, - 71, 71, 1440, 1447, 71, 71, 1444, 1451, 1448, 71, - 1454, 71, 71, 1453, 71, 1449, 71, 1458, 71, 1459, + 71, 1405, 1409, 71, 71, 71, 1414, 71, 71, 1404, + 1406, 1408, 1415, 71, 1411, 71, 71, 1418, 1410, 71, + 71, 1412, 1413, 71, 71, 1416, 71, 1419, 71, 71, + 71, 71, 1417, 1421, 1425, 1420, 1427, 1426, 1428, 1422, + 71, 1423, 71, 1430, 71, 71, 71, 1424, 71, 1429, + 1435, 1432, 1436, 1434, 71, 1437, 71, 71, 71, 1431, + 71, 1438, 1439, 71, 71, 71, 1441, 1433, 1440, 71, + 71, 71, 71, 1446, 71, 71, 1445, 71, 71, 71, + 1449, 71, 1452, 1442, 1443, 1448, 1444, 1453, 71, 71, + 1454, 71, 1450, 71, 1447, 1455, 71, 71, 1451, 71, - 1452, 1461, 71, 71, 71, 71, 71, 71, 71, 1464, - 1455, 1463, 1456, 71, 1457, 71, 71, 71, 71, 71, - 1472, 1462, 71, 1465, 1460, 1466, 71, 1467, 71, 1473, - 1469, 71, 1468, 1471, 1474, 1475, 71, 71, 1470, 71, - 1479, 1478, 1476, 1477, 71, 71, 71, 1481, 71, 71, - 71, 1482, 71, 1484, 1488, 71, 1490, 1480, 71, 71, - 71, 1485, 71, 1489, 1483, 1493, 1487, 1491, 71, 1486, - 71, 71, 1492, 71, 1494, 1495, 71, 1499, 1500, 71, - 71, 71, 71, 71, 71, 1504, 1505, 1503, 1496, 71, - 71, 1497, 71, 1507, 71, 71, 1498, 71, 1501, 71, + 1457, 1456, 1460, 71, 71, 1465, 71, 71, 1458, 1461, + 1459, 71, 1466, 71, 1468, 71, 1462, 71, 71, 71, + 71, 1471, 71, 1463, 1464, 1470, 71, 71, 71, 71, + 144, 71, 71, 1479, 1469, 71, 1472, 1473, 1480, 1467, + 71, 1474, 1476, 1482, 71, 1475, 1478, 71, 71, 71, + 1477, 1484, 1481, 1483, 71, 71, 71, 71, 71, 71, + 1488, 1491, 1485, 1486, 1489, 71, 1495, 71, 1487, 71, + 1497, 71, 1492, 71, 1496, 71, 71, 1490, 1500, 1493, + 71, 1494, 71, 71, 1501, 71, 1498, 1502, 1499, 71, + 1506, 1507, 71, 71, 71, 71, 71, 71, 1511, 1512, - 1508, 71, 1502, 1509, 71, 71, 1510, 71, 1512, 1506, - 1514, 1511, 71, 1515, 71, 71, 71, 71, 71, 1513, - 71, 1519, 1516, 71, 1521, 71, 71, 1525, 71, 71, - 71, 1520, 71, 71, 1518, 1517, 1522, 1528, 1530, 71, - 1523, 71, 1526, 71, 1533, 1524, 71, 1527, 1529, 71, - 1531, 71, 1534, 71, 71, 1536, 1539, 71, 71, 1538, - 1535, 1532, 71, 71, 71, 71, 71, 1546, 71, 71, - 71, 71, 1537, 1547, 71, 71, 1540, 1541, 1544, 1550, - 1551, 1542, 1543, 71, 71, 1553, 71, 71, 71, 1548, - 1545, 1549, 1554, 1555, 1552, 1557, 1559, 71, 71, 71, + 1510, 71, 1503, 1504, 71, 71, 1514, 71, 71, 1505, + 71, 1508, 71, 1515, 71, 1509, 1516, 71, 71, 71, + 1517, 1513, 1519, 1521, 1518, 71, 1522, 71, 71, 71, + 71, 71, 1520, 1523, 1526, 71, 1528, 71, 71, 71, + 1532, 71, 71, 71, 1527, 71, 71, 1525, 1524, 1529, + 1535, 71, 1530, 1537, 71, 1533, 71, 71, 1536, 71, + 1534, 1538, 71, 1531, 71, 1540, 1539, 1542, 71, 71, + 1546, 71, 1543, 1541, 1545, 71, 71, 71, 1544, 71, + 1547, 71, 1553, 71, 71, 71, 71, 71, 1554, 1548, + 71, 1551, 1558, 1557, 1562, 1549, 1550, 71, 71, 1560, - 1558, 71, 71, 1562, 1556, 71, 71, 1560, 1561, 71, - 1564, 71, 1565, 71, 71, 71, 71, 1569, 71, 1570, - 1566, 71, 71, 71, 71, 1584, 1581, 1576, 1571, 1563, - 1568, 1567, 71, 71, 71, 1573, 71, 71, 1574, 1577, - 1582, 1572, 1579, 71, 71, 1578, 71, 1580, 1583, 1586, - 1575, 71, 1585, 71, 71, 71, 71, 1588, 1587, 71, - 71, 1593, 1594, 1592, 71, 1596, 71, 71, 71, 1595, - 71, 71, 1589, 71, 71, 1590, 1599, 71, 1598, 1591, - 71, 71, 71, 71, 1608, 1600, 71, 71, 1601, 1597, - 71, 71, 71, 71, 1602, 71, 1604, 1605, 1606, 71, + 71, 71, 1564, 1561, 1552, 1555, 1556, 71, 71, 71, + 1559, 1566, 71, 71, 71, 71, 71, 1571, 71, 1568, + 1569, 1563, 71, 1565, 71, 1572, 1567, 71, 71, 71, + 1577, 1576, 1573, 71, 71, 71, 71, 1583, 1570, 1585, + 1574, 71, 1575, 71, 1580, 1578, 71, 1581, 71, 71, + 1591, 1584, 1590, 71, 1579, 1586, 71, 1587, 1588, 1582, + 1589, 71, 71, 1593, 71, 1594, 1592, 1595, 71, 71, + 71, 71, 71, 71, 1596, 71, 1602, 1603, 1601, 71, + 1605, 1597, 71, 71, 1604, 71, 71, 71, 1598, 71, + 1599, 71, 1600, 71, 1607, 1608, 71, 71, 1609, 71, - 1607, 1603, 1613, 71, 71, 71, 1616, 1611, 71, 1615, - 71, 1609, 1610, 71, 71, 71, 1612, 71, 71, 1614, - 71, 71, 71, 1617, 1618, 1623, 1621, 71, 1631, 71, - 1622, 1624, 1620, 71, 1625, 71, 1626, 1619, 1630, 1632, - 71, 71, 1627, 1636, 71, 1633, 1629, 1628, 71, 71, - 71, 1635, 71, 71, 71, 71, 71, 1639, 1640, 1634, - 71, 71, 1637, 71, 71, 1643, 1649, 71, 1648, 1638, - 1647, 1642, 1645, 1641, 71, 1646, 71, 71, 71, 1644, - 71, 71, 71, 71, 1650, 71, 1658, 71, 71, 1651, - 71, 1662, 1653, 1655, 71, 1652, 1654, 1660, 71, 1661, + 71, 1617, 71, 71, 71, 1610, 71, 71, 1606, 71, + 71, 1611, 71, 1613, 1614, 1615, 71, 1612, 71, 1616, + 1622, 71, 1618, 1620, 1619, 71, 71, 1625, 71, 71, + 1624, 1621, 1623, 1626, 71, 71, 71, 71, 71, 71, + 1628, 71, 1627, 1630, 1632, 1633, 71, 1629, 1634, 1639, + 1631, 1640, 71, 71, 1635, 71, 1636, 1641, 71, 71, + 71, 1637, 1644, 71, 1638, 1642, 1645, 71, 71, 71, + 71, 71, 71, 1643, 1648, 1649, 1646, 71, 1657, 1647, + 1652, 71, 71, 71, 71, 1658, 71, 1650, 1651, 71, + 1654, 1656, 71, 1655, 71, 71, 1653, 71, 71, 71, - 71, 1657, 71, 1659, 71, 1663, 71, 1656, 1669, 1664, - 71, 71, 1665, 1670, 71, 1675, 1666, 71, 146, 71, - 1671, 71, 1668, 1667, 1674, 1672, 1677, 71, 1678, 71, - 71, 71, 1680, 1673, 71, 1676, 1679, 71, 71, 1684, - 71, 71, 1688, 1681, 1683, 71, 71, 71, 71, 1682, - 1686, 71, 71, 1685, 1689, 71, 1687, 71, 71, 71, - 1690, 1693, 71, 1692, 71, 1698, 71, 1700, 1701, 71, - 1691, 1694, 1695, 71, 71, 71, 1696, 1703, 1697, 71, - 1707, 71, 1702, 71, 71, 71, 71, 1699, 1711, 71, - 71, 71, 71, 1704, 1706, 1713, 71, 1714, 1705, 71, + 71, 1667, 1660, 1659, 71, 71, 71, 71, 1662, 1664, + 1661, 1663, 1670, 71, 1669, 71, 1671, 1666, 71, 71, + 1668, 1678, 1673, 1665, 1675, 1674, 1679, 71, 71, 71, + 1672, 71, 71, 71, 1684, 1686, 71, 1677, 1683, 1676, + 71, 1687, 1680, 71, 1681, 1689, 71, 71, 1688, 71, + 1685, 71, 1690, 1682, 71, 1693, 71, 71, 1697, 1695, + 71, 71, 71, 71, 71, 1696, 71, 71, 1692, 1691, + 1694, 1698, 71, 71, 1701, 71, 1702, 71, 1709, 1699, + 71, 1700, 1707, 71, 71, 1703, 1704, 1710, 71, 1705, + 71, 1706, 71, 71, 71, 71, 1716, 71, 71, 71, - 1709, 1715, 71, 1710, 1716, 1708, 71, 71, 1720, 71, - 1712, 1717, 71, 71, 71, 1724, 71, 71, 71, 71, - 71, 71, 1719, 71, 1726, 1722, 71, 71, 1731, 1718, - 71, 1721, 1725, 1723, 71, 1727, 1739, 1733, 1728, 1729, - 71, 1730, 1732, 1735, 71, 71, 1734, 71, 1736, 1737, - 71, 1740, 1738, 1741, 71, 71, 71, 71, 1743, 71, - 71, 71, 1744, 71, 71, 71, 71, 1742, 71, 71, - 1749, 71, 71, 1753, 71, 1750, 71, 71, 1754, 1759, - 1745, 1747, 1748, 1746, 1751, 71, 1752, 1758, 71, 71, - 71, 1755, 1757, 71, 1756, 71, 71, 1760, 1764, 71, + 1712, 1711, 71, 71, 1708, 1720, 71, 1715, 1713, 71, + 71, 1714, 1726, 1718, 1722, 71, 1719, 1717, 71, 1721, + 1723, 71, 71, 1724, 1729, 71, 1725, 71, 71, 71, + 1733, 71, 1727, 71, 71, 71, 71, 1728, 71, 71, + 1731, 1735, 71, 1740, 71, 71, 1730, 1734, 1732, 71, + 1736, 1737, 71, 1748, 1738, 142, 1739, 1741, 1743, 71, + 1742, 1744, 71, 71, 1746, 71, 1745, 71, 1749, 1750, + 71, 1751, 1747, 71, 71, 1752, 71, 71, 71, 1753, + 71, 71, 71, 71, 71, 71, 71, 1758, 71, 71, + 1762, 71, 1759, 71, 1768, 71, 1760, 1754, 1756, 1757, - 1767, 1768, 71, 1769, 71, 71, 1762, 71, 1761, 1765, - 71, 1766, 71, 1763, 1771, 71, 71, 1772, 1775, 71, - 71, 1777, 71, 71, 1776, 1770, 1778, 71, 1773, 1779, - 1780, 1774, 1781, 71, 71, 71, 1783, 1786, 71, 1784, - 71, 71, 1785, 71, 71, 71, 1793, 1782, 71, 71, - 71, 1798, 71, 71, 1791, 1795, 1787, 1788, 1789, 71, - 1796, 71, 71, 1790, 1797, 1792, 1801, 71, 1794, 71, - 1799, 71, 71, 1803, 1805, 71, 1802, 1800, 71, 1807, - 71, 71, 71, 1810, 1811, 71, 71, 1813, 71, 71, - 1804, 71, 71, 71, 1819, 71, 71, 1806, 1818, 71, + 1755, 1761, 1763, 71, 71, 71, 1769, 1771, 1765, 1766, + 1770, 71, 71, 71, 1773, 1764, 1767, 71, 71, 1776, + 71, 1774, 71, 1779, 1772, 1780, 71, 1781, 71, 1783, + 71, 71, 1775, 71, 1777, 71, 1778, 71, 1782, 71, + 1784, 1787, 71, 71, 1789, 71, 71, 1788, 1790, 1791, + 71, 1793, 1785, 1792, 1786, 71, 71, 71, 71, 1795, + 1796, 71, 1794, 71, 1797, 1798, 71, 71, 71, 1805, + 71, 71, 1809, 71, 71, 71, 1807, 71, 1799, 1800, + 1801, 1808, 71, 71, 71, 1802, 1810, 1803, 1804, 1812, + 1806, 1813, 71, 1815, 1811, 1817, 71, 71, 1816, 71, - 1808, 1815, 1816, 1809, 71, 71, 1812, 71, 71, 71, - 1825, 71, 1817, 71, 1814, 1822, 1823, 1820, 71, 71, - 1821, 1829, 1832, 1828, 71, 1824, 1833, 71, 71, 1827, - 71, 1831, 71, 1834, 71, 1835, 71, 1826, 71, 1830, - 71, 71, 71, 71, 71, 1836, 1840, 71, 1843, 1844, - 71, 71, 71, 1839, 71, 71, 1847, 71, 1837, 1838, - 1841, 71, 1852, 71, 71, 1846, 1851, 71, 71, 71, - 1842, 1845, 1848, 1856, 1849, 71, 71, 1859, 71, 1850, - 71, 1857, 1854, 1853, 1860, 1858, 71, 1855, 1863, 71, - 71, 71, 1870, 71, 71, 71, 71, 1861, 71, 1867, + 71, 1814, 71, 1819, 71, 71, 1822, 1823, 71, 71, + 1825, 71, 71, 71, 71, 71, 1831, 71, 1830, 71, + 1820, 71, 1827, 1828, 71, 1818, 1821, 71, 1834, 1824, + 71, 71, 71, 1837, 71, 71, 1829, 1826, 71, 1835, + 1832, 1841, 1833, 1840, 71, 71, 71, 71, 1844, 1845, + 71, 1839, 1843, 71, 71, 71, 71, 1836, 1846, 71, + 1838, 1847, 1848, 71, 1842, 71, 1849, 71, 1852, 1850, + 71, 71, 1855, 1856, 71, 1851, 71, 71, 71, 71, + 71, 1859, 71, 1864, 71, 1853, 71, 1863, 71, 71, + 3041, 1858, 71, 71, 1857, 71, 1854, 1860, 1861, 1868, - 71, 71, 1862, 71, 1875, 1865, 1872, 1873, 71, 71, - 1874, 1864, 1866, 71, 71, 1868, 1869, 71, 1871, 1880, - 71, 1882, 1876, 1881, 71, 1877, 1883, 71, 1884, 1885, - 1878, 71, 71, 71, 71, 71, 1889, 1879, 1887, 71, - 71, 71, 71, 71, 1888, 1891, 71, 1894, 71, 1896, - 71, 1890, 1892, 71, 71, 71, 71, 1886, 1897, 71, - 71, 1900, 1898, 1901, 71, 1902, 1903, 71, 1893, 1906, - 1895, 1904, 71, 1899, 71, 71, 71, 71, 71, 1905, - 1907, 1908, 71, 1909, 71, 1912, 71, 1910, 71, 1911, - 71, 1914, 71, 71, 71, 1918, 71, 71, 1913, 1917, + 71, 1870, 1862, 1866, 71, 1865, 1869, 71, 1867, 1871, + 71, 1872, 1875, 71, 1876, 1873, 71, 71, 71, 71, + 1874, 71, 1882, 1879, 71, 71, 1885, 71, 71, 1884, + 1877, 71, 1886, 71, 71, 71, 1878, 1887, 71, 1880, + 1883, 1881, 71, 1888, 1892, 71, 1889, 1893, 71, 1894, + 1896, 1890, 71, 1897, 1895, 71, 71, 1899, 1891, 71, + 71, 1901, 71, 71, 71, 71, 71, 71, 1898, 1903, + 1906, 1908, 1900, 71, 1902, 1904, 71, 71, 71, 71, + 71, 71, 71, 1913, 71, 1909, 1912, 1924, 1907, 1905, + 1910, 71, 1914, 1915, 71, 1916, 71, 1918, 1911, 71, - 1915, 71, 1919, 71, 1916, 71, 1920, 71, 1921, 1922, - 71, 71, 71, 71, 1924, 1929, 1927, 1923, 1928, 71, - 71, 71, 71, 1931, 71, 1925, 71, 71, 1935, 71, - 1926, 71, 71, 1930, 1932, 1934, 1937, 1939, 1933, 71, - 1936, 1941, 71, 71, 71, 71, 1942, 71, 1947, 71, - 1938, 71, 1940, 71, 71, 71, 1949, 71, 71, 1950, - 1943, 1944, 1945, 1946, 1951, 71, 1952, 71, 1948, 71, - 1955, 71, 71, 1954, 1953, 71, 71, 71, 71, 71, - 1956, 71, 71, 71, 71, 1967, 71, 1958, 1959, 1960, - 1963, 71, 71, 1957, 1962, 1966, 71, 1971, 71, 1970, + 71, 71, 1917, 71, 71, 1919, 1920, 71, 71, 1922, + 1921, 71, 1923, 71, 1926, 71, 71, 1930, 71, 71, + 1925, 1929, 71, 1927, 71, 71, 71, 1928, 1931, 1932, + 1933, 1934, 71, 71, 71, 1936, 71, 71, 71, 1941, + 1939, 71, 1935, 1940, 71, 71, 71, 71, 1946, 71, + 1943, 1937, 71, 1938, 71, 1942, 71, 1950, 71, 1947, + 1945, 1949, 1944, 1951, 71, 71, 71, 1948, 1956, 71, + 1952, 1954, 71, 71, 71, 1957, 71, 1962, 1955, 71, + 71, 71, 1964, 71, 71, 1953, 1965, 1966, 71, 1958, + 1959, 1960, 71, 1961, 71, 71, 71, 1963, 71, 1970, - 1968, 1965, 71, 1964, 1961, 71, 71, 1973, 1974, 71, - 71, 1969, 71, 71, 1976, 71, 71, 1977, 1972, 71, - 71, 1978, 1982, 1975, 1980, 71, 71, 1984, 1981, 1986, - 71, 1979, 71, 71, 71, 1989, 71, 71, 1983, 1988, - 1985, 1990, 1991, 71, 71, 1994, 71, 71, 71, 71, - 71, 71, 1995, 71, 2000, 71, 1997, 71, 1987, 1996, - 2004, 1992, 71, 2001, 1993, 2002, 71, 1999, 1998, 71, - 71, 71, 2006, 71, 2005, 2009, 71, 2003, 71, 2007, - 71, 2011, 71, 2012, 71, 2010, 71, 2008, 71, 71, - 71, 2014, 2018, 2013, 71, 71, 2015, 2016, 2020, 71, + 1967, 1968, 71, 71, 71, 1971, 71, 71, 71, 71, + 71, 1982, 71, 71, 1978, 1969, 1973, 71, 1974, 1975, + 71, 71, 71, 1972, 1977, 1981, 1986, 1979, 71, 1976, + 1980, 1985, 71, 71, 71, 1983, 1989, 1988, 71, 71, + 1984, 71, 1987, 1991, 71, 71, 1992, 71, 71, 71, + 1993, 1990, 71, 71, 1995, 1997, 71, 71, 1999, 1996, + 2001, 71, 1994, 2000, 71, 71, 71, 1998, 2004, 2003, + 2005, 71, 71, 2009, 71, 2007, 2006, 71, 2002, 71, + 71, 71, 2010, 71, 2015, 71, 71, 2011, 2012, 71, + 2016, 71, 2008, 2019, 71, 71, 2021, 2014, 71, 71, - 2017, 71, 71, 2021, 71, 71, 2023, 2024, 2022, 71, - 2019, 71, 71, 71, 2025, 2027, 2026, 2030, 71, 71, - 71, 2028, 2029, 2031, 71, 71, 71, 71, 71, 71, - 2032, 71, 71, 2039, 2034, 2033, 2040, 2036, 2037, 2035, - 71, 2041, 71, 71, 71, 71, 2042, 2038, 2044, 2050, - 71, 71, 2045, 71, 71, 2052, 71, 71, 2046, 2043, - 2049, 2054, 2047, 2051, 71, 71, 71, 144, 2057, 2055, - 2048, 2059, 2053, 2058, 71, 2060, 71, 71, 2056, 2061, - 71, 71, 2064, 71, 71, 2065, 2063, 71, 2062, 2069, - 71, 71, 2070, 71, 71, 2073, 2068, 71, 71, 2066, + 2013, 2017, 71, 2020, 2024, 71, 71, 2025, 71, 2026, + 2022, 2018, 71, 2027, 71, 2028, 71, 71, 2023, 2029, + 71, 71, 2033, 71, 71, 2035, 2031, 71, 71, 2032, + 2036, 71, 2037, 2040, 2030, 71, 2038, 71, 71, 2039, + 2041, 71, 2034, 71, 2045, 71, 71, 71, 71, 71, + 2042, 71, 2044, 71, 71, 71, 71, 71, 2043, 2046, + 2054, 2051, 2049, 2048, 2047, 2052, 2050, 71, 71, 71, + 71, 71, 2055, 71, 2053, 2057, 2059, 2056, 71, 2060, + 2065, 71, 2063, 71, 2067, 71, 2061, 2064, 2058, 71, + 71, 2062, 2066, 71, 2069, 2072, 71, 2074, 2070, 2075, - 71, 71, 2074, 71, 2075, 2071, 2076, 71, 71, 2078, - 2067, 71, 2072, 2077, 71, 71, 2083, 71, 2079, 71, - 2080, 2081, 71, 2082, 71, 71, 2089, 71, 71, 2086, - 71, 71, 71, 71, 2090, 71, 71, 2085, 2092, 71, - 71, 71, 2084, 2087, 2088, 2096, 2091, 2094, 2099, 71, - 71, 71, 2097, 71, 71, 2095, 71, 71, 2093, 2098, - 71, 2100, 71, 71, 71, 2110, 71, 142, 71, 2101, - 2102, 2111, 71, 71, 2107, 71, 2105, 2103, 71, 2109, - 2104, 2106, 71, 2115, 2108, 2112, 71, 2113, 2114, 2116, - 71, 2117, 71, 2118, 71, 2120, 71, 2123, 71, 2119, + 2073, 71, 71, 71, 71, 71, 71, 2076, 2068, 2071, + 2077, 2079, 71, 71, 2080, 71, 2084, 71, 71, 2085, + 71, 2088, 71, 2093, 2083, 71, 2078, 71, 2081, 71, + 2089, 71, 2086, 71, 2090, 2091, 71, 71, 71, 2082, + 2087, 71, 2092, 71, 71, 2094, 71, 2096, 71, 2098, + 71, 2095, 71, 2101, 71, 71, 71, 71, 2107, 71, + 71, 2105, 71, 2097, 2108, 2100, 71, 71, 71, 2099, + 2102, 2103, 2110, 71, 2104, 71, 71, 2109, 2114, 2106, + 2112, 71, 2117, 71, 71, 71, 71, 71, 71, 2115, + 71, 71, 2111, 2118, 2113, 71, 71, 71, 71, 2116, - 71, 71, 71, 71, 71, 2121, 2124, 2125, 2122, 2129, - 71, 2130, 71, 71, 2132, 71, 2128, 71, 2134, 71, - 2126, 71, 71, 2127, 2137, 71, 71, 2136, 2138, 71, - 71, 71, 2131, 71, 71, 2133, 2135, 71, 71, 2140, - 2139, 71, 2143, 2144, 71, 2141, 2146, 71, 71, 71, - 2150, 71, 2142, 2145, 2148, 71, 2147, 71, 2149, 2152, - 71, 71, 2156, 71, 71, 2151, 71, 71, 71, 71, - 2153, 71, 2154, 2160, 2161, 71, 71, 2165, 71, 71, - 2155, 71, 2159, 71, 2157, 71, 2163, 2162, 2167, 2158, - 71, 2164, 71, 71, 2172, 71, 71, 2168, 2174, 2166, + 2128, 71, 71, 2119, 71, 2120, 2127, 2129, 2125, 2123, + 2121, 2130, 2122, 71, 71, 2132, 2124, 71, 2126, 71, + 2133, 2134, 71, 2135, 71, 71, 2138, 2131, 71, 2136, + 2137, 2141, 71, 71, 71, 71, 71, 2139, 2142, 2143, + 2140, 71, 2147, 71, 2148, 71, 71, 2150, 71, 71, + 2152, 71, 71, 2146, 71, 2144, 2145, 2154, 2155, 71, + 2156, 71, 71, 71, 71, 2149, 71, 2151, 71, 2153, + 2162, 71, 2158, 2161, 71, 71, 2157, 71, 2159, 2164, + 71, 2166, 71, 71, 71, 2160, 2167, 71, 2168, 2170, + 71, 71, 71, 2163, 71, 2165, 2174, 71, 71, 2172, - 71, 71, 71, 2169, 2173, 2175, 2179, 71, 2170, 71, - 71, 71, 2178, 71, 2180, 71, 2184, 71, 2171, 71, - 2176, 71, 2177, 2182, 2186, 71, 2187, 2189, 71, 2191, - 71, 71, 2181, 71, 2183, 71, 2192, 71, 2190, 71, - 2188, 2185, 2193, 2195, 71, 71, 71, 2196, 2197, 71, - 71, 2202, 71, 2194, 2198, 2199, 2203, 71, 2200, 71, - 71, 2208, 71, 2204, 2201, 71, 2207, 71, 71, 2206, - 71, 2209, 2205, 71, 71, 71, 2215, 71, 71, 2210, - 71, 71, 71, 2217, 71, 71, 2226, 71, 2211, 2213, - 2212, 2214, 2218, 2216, 2221, 71, 71, 2219, 2222, 2220, + 71, 2171, 71, 2169, 2178, 2179, 71, 71, 71, 71, + 2173, 71, 2175, 2177, 2183, 71, 71, 2176, 2185, 71, + 71, 2180, 2181, 2182, 71, 71, 2190, 71, 71, 2184, + 2186, 71, 71, 2192, 71, 71, 2191, 2187, 2188, 71, + 2196, 71, 2193, 71, 71, 2200, 2197, 71, 2198, 2202, + 2189, 71, 71, 71, 71, 2201, 2204, 2194, 2205, 2195, + 2199, 71, 2207, 2209, 71, 71, 2210, 2206, 71, 71, + 2211, 71, 71, 2203, 71, 2208, 71, 2214, 71, 71, + 71, 2215, 71, 3041, 2213, 2216, 2220, 2217, 2218, 2212, + 2221, 71, 71, 71, 2219, 2222, 71, 71, 71, 2225, - 71, 2223, 71, 2227, 71, 2224, 2228, 71, 71, 2230, - 2231, 2229, 2225, 2232, 2233, 71, 71, 71, 71, 71, - 71, 2235, 71, 71, 71, 2239, 71, 71, 71, 2241, - 2236, 2234, 2240, 2242, 71, 71, 2237, 71, 71, 71, - 2243, 71, 2238, 2246, 2247, 71, 2244, 2245, 71, 71, - 71, 2248, 71, 2249, 71, 71, 2253, 2256, 71, 71, - 2255, 2250, 71, 71, 2252, 2257, 71, 2261, 71, 2251, - 2263, 2260, 71, 71, 2254, 71, 2258, 71, 2259, 2985, - 2262, 71, 2265, 71, 71, 2268, 2266, 71, 2270, 2264, - 71, 2269, 2272, 71, 71, 71, 2274, 71, 71, 71, + 71, 2226, 2223, 71, 2227, 71, 2224, 71, 2233, 71, + 71, 71, 2228, 2229, 71, 2230, 2231, 71, 71, 71, + 2235, 2232, 71, 71, 71, 2234, 2236, 2240, 2241, 71, + 2239, 2244, 71, 2237, 2238, 71, 2245, 2246, 71, 71, + 71, 2243, 2242, 2247, 2248, 2249, 2250, 2251, 71, 71, + 71, 71, 71, 71, 2253, 71, 71, 71, 2257, 2258, + 71, 71, 2254, 2252, 71, 71, 2260, 71, 2261, 2255, + 2262, 2263, 71, 71, 2259, 2256, 71, 71, 2264, 71, + 2268, 71, 71, 2267, 71, 2265, 71, 71, 71, 2270, + 71, 71, 71, 71, 2274, 2269, 71, 2266, 2276, 2277, - 71, 71, 2271, 2267, 2273, 2278, 71, 71, 71, 71, - 2282, 71, 2280, 2276, 2281, 2284, 2275, 2277, 2283, 71, - 71, 71, 71, 2285, 2286, 71, 71, 71, 2291, 71, - 2288, 71, 2279, 71, 71, 2293, 2296, 71, 71, 2290, - 2292, 71, 2287, 71, 71, 2289, 71, 2299, 71, 2295, - 71, 2294, 2300, 71, 71, 2301, 71, 2297, 2305, 71, - 71, 2298, 2302, 2303, 2304, 71, 71, 71, 2310, 71, - 71, 71, 2309, 2395, 2306, 2311, 2312, 71, 2308, 2307, - 2313, 71, 2314, 71, 2315, 71, 71, 2317, 71, 71, - 2319, 71, 2320, 2318, 71, 71, 71, 71, 2316, 2325, + 71, 2286, 2273, 71, 71, 71, 2271, 2272, 71, 2278, + 2279, 2275, 2280, 2281, 2282, 71, 71, 71, 2284, 71, + 71, 2291, 2287, 2283, 71, 2289, 71, 71, 71, 71, + 2288, 2285, 2290, 2293, 71, 71, 2295, 71, 2292, 71, + 71, 71, 71, 71, 2294, 71, 2299, 2296, 2301, 71, + 2302, 2303, 71, 2297, 2304, 71, 2298, 2305, 71, 2306, + 71, 71, 71, 71, 71, 2307, 2309, 2314, 2300, 2312, + 71, 71, 71, 71, 71, 71, 2311, 2317, 71, 71, + 2313, 2310, 2308, 71, 2320, 2321, 71, 71, 71, 2316, + 2315, 71, 2322, 71, 2318, 71, 71, 2319, 2325, 71, - 71, 71, 2327, 71, 2328, 71, 2321, 2322, 71, 71, - 71, 71, 71, 2324, 71, 71, 2323, 2331, 71, 2329, - 2326, 2330, 71, 2332, 2337, 71, 71, 2334, 71, 71, - 71, 71, 2333, 71, 2335, 2336, 71, 2338, 71, 2344, - 71, 71, 2341, 71, 2339, 2343, 2340, 71, 2346, 2345, - 71, 2347, 71, 2351, 2342, 71, 71, 2355, 71, 2348, - 2353, 2354, 2356, 71, 71, 2349, 2352, 71, 2357, 71, - 2350, 71, 2358, 71, 2359, 71, 71, 71, 71, 71, - 2361, 71, 2360, 71, 71, 71, 2370, 2371, 71, 71, - 2367, 71, 71, 2985, 2362, 2364, 2363, 2374, 71, 2366, + 2324, 2326, 71, 71, 71, 3041, 2323, 71, 2330, 2327, + 2328, 71, 2332, 71, 2329, 2333, 71, 2334, 71, 2335, + 71, 2336, 71, 2337, 2331, 71, 71, 2340, 71, 2341, + 2339, 2338, 71, 71, 71, 71, 2346, 71, 71, 2348, + 71, 2349, 71, 71, 2342, 2343, 71, 71, 71, 71, + 71, 2345, 71, 2352, 2344, 2351, 71, 2347, 2350, 71, + 2353, 2355, 2358, 71, 71, 71, 71, 71, 2359, 2354, + 2356, 71, 2357, 71, 71, 2365, 71, 71, 71, 2362, + 2366, 71, 71, 71, 71, 2361, 2372, 2364, 2376, 71, + 2360, 2363, 2367, 2368, 2369, 71, 71, 71, 2373, 71, - 2365, 2373, 2369, 2368, 71, 2376, 71, 71, 71, 2377, - 71, 2372, 71, 2375, 71, 2379, 71, 71, 2385, 71, - 2386, 71, 71, 2387, 71, 2378, 71, 2380, 2381, 71, - 71, 71, 2382, 2383, 71, 2384, 2391, 71, 71, 2389, - 2388, 71, 2394, 2396, 71, 2390, 71, 71, 2397, 71, - 2392, 2398, 71, 71, 2393, 71, 2400, 2399, 71, 71, - 2401, 2402, 71, 2404, 71, 2409, 71, 2408, 71, 71, - 2412, 71, 71, 2403, 71, 2405, 2413, 71, 2406, 2416, - 71, 2415, 2407, 2410, 71, 71, 71, 2411, 71, 2414, - 2420, 71, 71, 71, 71, 2424, 71, 2417, 2423, 71, + 2374, 2375, 71, 2370, 71, 2371, 2377, 71, 71, 2378, + 71, 2379, 71, 2380, 71, 2381, 71, 71, 2383, 71, + 71, 71, 2384, 2390, 71, 2382, 2386, 71, 2388, 71, + 71, 2394, 2395, 71, 2385, 71, 71, 2387, 71, 71, + 2389, 2398, 71, 71, 2391, 2392, 71, 2393, 2397, 2400, + 71, 71, 2399, 2403, 2401, 71, 2402, 2396, 71, 71, + 71, 2409, 71, 2410, 71, 2411, 2404, 71, 71, 71, + 71, 71, 71, 2405, 71, 2407, 2406, 2415, 71, 2408, + 2419, 71, 71, 2413, 2421, 2412, 2418, 71, 2414, 71, + 2416, 2420, 71, 71, 2417, 2422, 71, 71, 2424, 71, - 2421, 2422, 2426, 71, 2427, 2418, 2419, 71, 71, 71, - 2431, 71, 2425, 71, 2432, 71, 2428, 2434, 71, 71, - 71, 2430, 71, 71, 2429, 71, 2439, 71, 2441, 71, - 71, 2437, 2435, 2436, 2438, 2442, 71, 2433, 2440, 71, - 71, 2443, 71, 71, 71, 2445, 71, 71, 71, 71, - 2446, 71, 2449, 2444, 2451, 2448, 2452, 71, 2454, 71, - 2455, 71, 2447, 2450, 71, 71, 71, 71, 2460, 2680, - 2457, 2456, 2453, 71, 71, 71, 2462, 71, 2461, 2465, - 71, 71, 2466, 71, 2458, 2459, 2464, 71, 2468, 71, - 71, 2470, 2463, 2469, 71, 2474, 2471, 71, 71, 2472, + 71, 71, 71, 71, 71, 2428, 2423, 71, 71, 2426, + 2432, 3041, 2425, 2433, 71, 2436, 71, 2434, 71, 2427, + 71, 2429, 2430, 71, 2431, 71, 2435, 2437, 71, 2439, + 2440, 71, 71, 2438, 2444, 71, 71, 71, 71, 71, + 2442, 2441, 2447, 2448, 71, 71, 2446, 71, 2445, 2450, + 71, 71, 2443, 71, 2452, 71, 2451, 71, 2449, 2455, + 71, 71, 2456, 2453, 71, 2454, 2458, 71, 71, 71, + 2459, 2463, 71, 2461, 71, 2465, 71, 2457, 2462, 71, + 71, 2460, 71, 71, 2466, 2467, 71, 71, 2469, 2464, + 71, 71, 71, 71, 2470, 71, 2468, 71, 71, 2472, - 2467, 71, 71, 2473, 71, 71, 2475, 71, 71, 2476, - 71, 71, 71, 71, 2477, 2480, 2479, 2482, 71, 71, - 71, 2483, 2478, 2481, 2485, 2484, 71, 71, 71, 71, - 71, 2486, 71, 2491, 71, 71, 71, 2489, 2487, 2490, - 2488, 71, 71, 2492, 2496, 71, 71, 71, 2493, 2500, - 71, 2499, 71, 71, 71, 2494, 2498, 71, 2504, 2985, - 2495, 2497, 2505, 71, 2507, 2501, 2508, 2502, 2509, 71, - 71, 71, 71, 2503, 71, 2510, 71, 2511, 71, 71, - 2513, 71, 2506, 2512, 71, 2515, 71, 71, 2518, 2519, - 71, 71, 2514, 2520, 71, 2521, 71, 71, 2516, 71, + 2473, 71, 2475, 2476, 2478, 71, 2471, 71, 2474, 2482, + 2477, 2479, 71, 71, 2480, 2484, 71, 71, 2481, 2483, + 71, 71, 2485, 71, 2486, 2488, 2489, 71, 2490, 71, + 71, 2487, 2492, 71, 71, 2494, 71, 2493, 71, 71, + 2495, 71, 71, 2491, 2496, 2498, 71, 2497, 71, 71, + 2499, 71, 71, 2500, 71, 2505, 2514, 2504, 2501, 2506, + 71, 71, 2503, 71, 71, 71, 71, 2502, 2507, 2509, + 71, 71, 2508, 2510, 71, 71, 2512, 71, 2511, 2513, + 71, 71, 2518, 71, 71, 71, 2516, 71, 2515, 2517, + 2523, 71, 2519, 71, 71, 71, 2527, 71, 71, 71, - 71, 2517, 2523, 2522, 2524, 71, 71, 71, 2528, 71, - 2531, 2525, 2526, 2529, 71, 2532, 71, 71, 2527, 71, - 2530, 2533, 71, 71, 71, 71, 2534, 2538, 71, 71, - 2535, 71, 2539, 2540, 71, 2542, 71, 2536, 71, 71, - 2541, 2546, 2543, 71, 2537, 2547, 71, 71, 71, 2549, - 71, 71, 2548, 2545, 2550, 71, 2544, 71, 2555, 71, - 71, 71, 71, 2554, 71, 2557, 2551, 2558, 71, 71, - 2552, 2553, 71, 71, 2559, 71, 2561, 71, 2563, 71, - 2560, 71, 2568, 71, 2556, 2562, 2566, 71, 2570, 71, - 71, 71, 2576, 71, 2564, 2565, 71, 2567, 2572, 2573, + 71, 2532, 71, 2520, 2525, 2521, 2522, 71, 71, 2526, + 2534, 2531, 2524, 2535, 2529, 2536, 71, 2528, 71, 71, + 2530, 71, 2537, 71, 71, 71, 2538, 71, 71, 2539, + 71, 71, 2542, 2533, 2540, 71, 2545, 2546, 71, 71, + 2541, 2547, 71, 2549, 2543, 71, 2544, 2548, 71, 71, + 2550, 2551, 71, 71, 71, 2555, 71, 71, 2553, 71, + 2556, 71, 71, 2558, 2559, 71, 2554, 2560, 71, 2552, + 71, 71, 2562, 2561, 71, 2563, 2557, 2565, 71, 71, + 2566, 2567, 71, 2569, 71, 71, 71, 71, 2573, 2568, + 71, 2564, 2574, 71, 71, 71, 71, 2576, 2570, 2575, - 71, 2569, 2571, 71, 2574, 71, 71, 2577, 71, 2578, - 2575, 71, 2579, 71, 2580, 71, 2581, 71, 71, 71, - 2582, 2985, 2584, 2583, 2588, 71, 2585, 71, 71, 71, - 2589, 2591, 71, 2593, 71, 71, 2592, 71, 2586, 2587, - 2594, 2595, 71, 71, 71, 71, 2590, 2600, 71, 71, - 71, 71, 2596, 2597, 2598, 2599, 71, 2604, 2602, 71, - 2601, 71, 2605, 71, 2606, 2603, 2608, 71, 2607, 2609, - 71, 2610, 71, 71, 71, 71, 71, 71, 71, 71, - 2619, 2611, 71, 71, 2614, 71, 71, 2617, 2615, 2636, - 2622, 71, 2613, 2985, 2620, 71, 2623, 71, 2612, 2618, + 71, 2572, 2577, 71, 2571, 71, 2582, 71, 2585, 71, + 71, 2581, 71, 2578, 2584, 71, 2579, 71, 71, 71, + 2580, 2588, 2586, 2587, 71, 71, 71, 2590, 71, 71, + 3041, 2593, 2583, 71, 2597, 71, 71, 71, 71, 71, + 2599, 71, 2591, 2592, 2589, 71, 2594, 2596, 2600, 2595, + 2598, 2604, 2601, 2603, 2607, 71, 2605, 71, 2602, 71, + 2606, 71, 2608, 71, 2609, 71, 2610, 71, 2611, 71, + 71, 71, 71, 71, 2613, 2612, 71, 2619, 71, 71, + 71, 2616, 2620, 2622, 71, 71, 2624, 71, 71, 71, + 2614, 3041, 2623, 2617, 2625, 71, 2618, 2615, 2621, 2626, - 71, 2624, 2616, 71, 2621, 71, 2625, 71, 2626, 71, - 2627, 2629, 71, 2628, 2630, 71, 2631, 71, 71, 71, - 2639, 71, 71, 71, 2635, 2633, 2634, 2632, 2637, 71, - 71, 71, 71, 2644, 2638, 71, 2642, 2646, 71, 71, - 2640, 71, 71, 71, 2650, 71, 71, 71, 71, 71, - 2643, 2641, 2653, 71, 71, 71, 2648, 71, 71, 2651, - 2645, 2647, 2652, 2649, 2654, 2657, 2656, 71, 71, 2655, - 2660, 71, 2658, 2662, 71, 2663, 71, 2661, 2665, 71, - 2659, 71, 71, 71, 71, 71, 2670, 71, 71, 2664, - 2669, 71, 71, 2674, 71, 2676, 71, 2666, 2667, 2668, + 71, 71, 71, 71, 2627, 71, 2630, 2631, 71, 2632, + 2628, 2629, 2633, 71, 2635, 71, 71, 71, 71, 2636, + 71, 71, 2639, 71, 2638, 2640, 71, 71, 2634, 2637, + 2641, 71, 2642, 71, 71, 71, 2645, 71, 71, 71, + 3041, 2644, 2650, 71, 2648, 2646, 2643, 71, 71, 71, + 2651, 2692, 2653, 71, 2654, 71, 2655, 2649, 71, 2647, + 2652, 71, 2656, 2657, 71, 2658, 2660, 71, 2659, 2661, + 71, 2662, 71, 71, 71, 71, 71, 2667, 71, 71, + 2666, 2664, 2663, 71, 2668, 71, 2670, 71, 71, 2675, + 2669, 71, 71, 2665, 2671, 71, 2673, 2677, 71, 2672, - 71, 2678, 2681, 71, 2671, 2682, 71, 71, 2675, 71, - 2673, 2672, 71, 71, 2679, 2684, 71, 71, 71, 2689, - 2677, 71, 71, 71, 2686, 71, 2687, 2693, 71, 71, - 71, 71, 2683, 2694, 2691, 2685, 71, 2695, 2688, 2698, - 2690, 2696, 2701, 2692, 71, 71, 2699, 71, 71, 71, - 71, 2697, 2700, 71, 71, 2703, 71, 2706, 2704, 71, - 2709, 71, 2702, 71, 2710, 71, 2713, 71, 71, 71, - 2714, 71, 71, 2705, 71, 2711, 2707, 2708, 2712, 2715, - 71, 71, 2716, 2718, 71, 2717, 2719, 71, 2720, 71, - 71, 2722, 71, 71, 2724, 2721, 71, 71, 2727, 71, + 71, 71, 71, 71, 2678, 71, 2674, 2679, 2680, 71, + 2681, 71, 2685, 71, 71, 71, 71, 2676, 71, 71, + 2682, 71, 2688, 71, 71, 2684, 2683, 2686, 2687, 2693, + 2689, 71, 2690, 2695, 71, 2697, 71, 71, 2691, 2698, + 71, 2700, 71, 71, 71, 71, 71, 2705, 71, 2694, + 2696, 2704, 71, 71, 71, 71, 2709, 71, 2699, 2701, + 2702, 2703, 2711, 71, 71, 71, 71, 71, 2713, 71, + 2714, 2710, 2706, 2708, 71, 71, 2707, 2716, 71, 2717, + 71, 2719, 71, 71, 2712, 2724, 2721, 2718, 2715, 2723, + 71, 71, 2722, 71, 71, 2728, 71, 71, 71, 2730, - 2723, 2728, 71, 71, 2733, 71, 2732, 71, 71, 71, - 71, 71, 71, 2729, 2731, 2725, 2783, 2736, 2726, 2737, - 71, 2738, 71, 2730, 71, 71, 2741, 71, 2734, 2739, - 2735, 71, 71, 2744, 71, 2743, 71, 71, 71, 2740, - 71, 2745, 71, 2742, 71, 2748, 71, 71, 71, 71, - 2750, 71, 71, 2985, 2749, 2751, 71, 2746, 2747, 71, - 71, 71, 71, 71, 2765, 2752, 2760, 2756, 2753, 2754, - 2755, 2763, 71, 2757, 2758, 71, 2762, 2764, 71, 2774, - 2759, 71, 2761, 2766, 71, 2767, 71, 2768, 2769, 71, - 71, 2770, 2771, 71, 71, 2772, 2773, 71, 71, 2775, + 2729, 2720, 71, 71, 2733, 2726, 2734, 71, 71, 2725, + 71, 2735, 2736, 71, 2727, 2731, 71, 71, 71, 71, + 2741, 2738, 2732, 71, 2739, 71, 71, 2744, 71, 71, + 71, 2737, 71, 2749, 71, 71, 2740, 2745, 71, 71, + 2742, 2743, 2752, 71, 3041, 2748, 71, 2746, 2751, 2753, + 71, 2754, 2755, 71, 2750, 2747, 2757, 71, 2756, 2758, + 71, 2759, 71, 71, 2761, 71, 71, 71, 2760, 71, + 71, 71, 2766, 2767, 71, 71, 71, 71, 2771, 71, + 71, 2772, 71, 71, 3041, 2762, 2770, 71, 2775, 2763, + 2768, 2764, 2765, 2776, 71, 2769, 2777, 71, 71, 71, - 71, 2778, 71, 71, 2781, 71, 71, 2776, 2780, 71, - 2784, 2777, 71, 2779, 71, 71, 71, 2789, 2785, 2790, - 71, 2791, 71, 71, 2788, 71, 71, 2782, 71, 2786, - 2787, 2793, 71, 2798, 2794, 2796, 71, 2795, 2792, 71, - 2797, 71, 71, 71, 71, 2805, 71, 2800, 2802, 2803, - 71, 2807, 71, 2799, 71, 2806, 2854, 2801, 2808, 71, - 71, 2804, 2809, 71, 2810, 71, 2811, 71, 2812, 71, - 2813, 71, 2814, 71, 71, 2816, 71, 71, 71, 71, - 2819, 2821, 71, 2815, 71, 71, 2817, 71, 71, 2825, - 2818, 71, 2827, 71, 71, 71, 71, 2824, 2820, 2822, + 2773, 2774, 2780, 2778, 71, 71, 71, 71, 71, 2783, + 71, 71, 2784, 2779, 2782, 71, 2781, 71, 71, 71, + 2787, 71, 71, 71, 2789, 2785, 71, 2790, 71, 2788, + 71, 2786, 71, 71, 71, 71, 71, 2806, 71, 2799, + 2791, 2800, 2792, 2793, 2794, 2802, 2795, 71, 2801, 2796, + 2797, 71, 2803, 71, 2798, 2804, 2807, 71, 71, 2809, + 71, 71, 2808, 2810, 71, 2817, 2805, 2811, 2812, 71, + 71, 2813, 2814, 71, 71, 2815, 2816, 71, 71, 2818, + 71, 71, 71, 71, 2824, 71, 71, 2819, 2823, 71, + 2827, 2820, 2841, 2821, 71, 71, 2826, 71, 71, 71, - 2823, 71, 71, 2831, 2829, 71, 2826, 2834, 2833, 71, - 71, 71, 2828, 71, 2832, 2836, 71, 71, 71, 71, - 71, 2830, 2841, 2835, 2843, 71, 2844, 71, 2845, 71, - 2837, 2842, 71, 2839, 2838, 2840, 71, 71, 71, 71, - 71, 2848, 71, 71, 71, 2847, 71, 2853, 71, 2856, - 71, 71, 71, 2850, 2852, 2846, 71, 71, 2849, 2855, - 71, 71, 71, 2851, 2857, 2858, 71, 2865, 2859, 71, - 2868, 71, 2860, 71, 71, 2862, 71, 2861, 2863, 71, - 2866, 2864, 2869, 2870, 71, 71, 2871, 2872, 71, 2867, - 2873, 71, 71, 2874, 71, 2876, 2875, 71, 71, 2877, + 71, 2822, 71, 2828, 71, 2832, 71, 2825, 2831, 2862, + 2829, 2833, 71, 2834, 71, 2830, 71, 2835, 71, 2839, + 71, 2836, 71, 71, 2840, 71, 71, 2837, 2845, 71, + 2838, 2842, 2848, 71, 2846, 2843, 2849, 71, 71, 2851, + 71, 2897, 71, 2844, 2850, 2847, 2852, 71, 71, 2854, + 71, 2855, 71, 2853, 2856, 71, 2857, 71, 2858, 71, + 2859, 71, 2860, 71, 2861, 71, 2863, 71, 71, 71, + 71, 71, 71, 2868, 71, 71, 71, 2864, 71, 2872, + 71, 2865, 71, 2874, 71, 71, 2869, 71, 2870, 2881, + 2866, 2867, 2871, 71, 2875, 71, 2876, 2873, 71, 2878, - 2881, 71, 2878, 71, 2879, 71, 71, 2884, 71, 71, - 2887, 71, 71, 2880, 71, 2882, 2890, 71, 71, 2891, - 2885, 71, 71, 2883, 2894, 2895, 71, 2888, 2886, 2892, - 71, 71, 2889, 71, 71, 2899, 71, 71, 71, 71, - 2896, 2893, 71, 71, 71, 71, 2897, 2903, 71, 2905, - 71, 71, 2902, 2898, 71, 71, 2985, 71, 2900, 2901, - 2910, 2907, 2904, 2908, 2906, 71, 71, 2915, 71, 71, - 2909, 2911, 71, 2917, 2912, 2913, 2985, 2916, 71, 71, - 71, 2918, 71, 2919, 2914, 71, 2923, 2920, 2922, 71, - 2921, 71, 71, 2924, 71, 71, 2925, 2926, 71, 2927, + 71, 71, 71, 2880, 71, 2879, 71, 2883, 71, 71, + 71, 2877, 71, 71, 2887, 2882, 2890, 71, 71, 2888, + 2892, 71, 71, 2884, 2885, 2886, 71, 2889, 2893, 71, + 2891, 2894, 71, 71, 71, 2896, 71, 71, 71, 71, + 2905, 2895, 2898, 2902, 71, 71, 2903, 2899, 2901, 71, + 71, 2904, 71, 71, 71, 71, 71, 2900, 2906, 71, + 71, 71, 71, 71, 2912, 71, 2909, 2916, 2907, 2911, + 2908, 2913, 2919, 71, 2920, 2917, 71, 2914, 2910, 71, + 2915, 2921, 71, 2918, 71, 2922, 2923, 71, 2924, 71, + 71, 71, 71, 2927, 71, 2925, 2928, 2929, 71, 2926, - 71, 71, 71, 2932, 71, 71, 71, 2929, 2928, 71, - 71, 2935, 2936, 71, 71, 71, 71, 71, 2934, 2939, - 2930, 2931, 71, 2933, 2937, 2940, 71, 2938, 71, 2943, - 2942, 2944, 71, 71, 2947, 2941, 71, 71, 2949, 71, - 2950, 71, 71, 71, 71, 2945, 2951, 71, 2946, 2952, - 2954, 71, 2955, 71, 71, 2948, 2956, 2957, 71, 71, - 2958, 71, 2953, 2960, 71, 71, 2959, 2963, 71, 2961, - 71, 71, 71, 71, 71, 2965, 2966, 71, 2969, 71, - 2962, 2970, 71, 71, 2964, 71, 2973, 2974, 71, 71, - 2975, 2967, 2968, 2971, 2976, 71, 2977, 71, 2972, 71, + 2932, 71, 71, 71, 71, 71, 71, 71, 2935, 2937, + 71, 2940, 71, 2931, 2934, 2933, 71, 71, 71, 2930, + 2938, 2943, 71, 2947, 2936, 71, 2939, 71, 2944, 71, + 2948, 2941, 71, 2945, 71, 2942, 71, 2946, 71, 71, + 2953, 71, 2954, 71, 2952, 71, 2949, 2950, 71, 71, + 71, 71, 71, 71, 2958, 71, 71, 2951, 2960, 71, + 2967, 71, 71, 2957, 71, 2962, 2955, 2965, 2956, 2963, + 71, 2959, 71, 71, 2961, 2966, 2971, 71, 2964, 71, + 71, 2973, 71, 2974, 2968, 2972, 71, 71, 71, 71, + 2969, 2975, 2970, 2976, 2977, 2979, 2980, 71, 2978, 71, - 71, 71, 71, 2983, 71, 2979, 2978, 2980, 2981, 2984, - 71, 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, - 2982, 43, 43, 43, 43, 43, 43, 43, 48, 48, - 48, 48, 48, 48, 48, 53, 53, 53, 53, 53, - 53, 53, 59, 59, 59, 59, 59, 59, 59, 64, - 64, 64, 64, 64, 64, 64, 74, 74, 2985, 74, - 74, 74, 74, 141, 141, 2985, 2985, 2985, 141, 141, - 143, 143, 2985, 2985, 143, 2985, 143, 145, 2985, 2985, - 2985, 2985, 2985, 145, 148, 148, 2985, 2985, 2985, 148, - 148, 150, 2985, 2985, 2985, 2985, 2985, 150, 152, 152, + 71, 71, 2982, 71, 2981, 71, 71, 71, 71, 2983, + 2988, 71, 71, 2985, 71, 2991, 71, 2992, 71, 2984, + 71, 71, 71, 71, 71, 2990, 2986, 2987, 2995, 2993, + 2989, 71, 2994, 71, 2999, 71, 3000, 2998, 71, 71, + 2996, 2997, 71, 3003, 71, 3005, 71, 3006, 3001, 71, + 71, 71, 3010, 71, 3007, 71, 71, 3008, 3004, 71, + 3011, 3012, 3013, 71, 3002, 71, 71, 71, 71, 71, + 3009, 71, 3014, 3015, 3017, 3016, 3019, 71, 71, 71, + 71, 71, 3025, 3021, 3022, 71, 3018, 3020, 3026, 71, + 3023, 71, 71, 3029, 3030, 71, 71, 3032, 71, 3024, - 2985, 152, 152, 152, 152, 75, 75, 2985, 75, 75, - 75, 75, 13, 2985, 2985, 2985, 2985, 2985, 2985, 2985, - 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, - 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, - 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, - 2985, 2985, 2985 + 3033, 71, 71, 3031, 3027, 71, 71, 71, 71, 3034, + 3028, 3035, 3036, 3039, 71, 3040, 71, 3041, 3041, 3041, + 3041, 3041, 3041, 3041, 3037, 3041, 3041, 3038, 43, 43, + 43, 43, 43, 43, 43, 48, 48, 48, 48, 48, + 48, 48, 53, 53, 53, 53, 53, 53, 53, 59, + 59, 59, 59, 59, 59, 59, 64, 64, 64, 64, + 64, 64, 64, 74, 74, 3041, 74, 74, 74, 74, + 141, 141, 3041, 3041, 3041, 141, 141, 143, 143, 3041, + 3041, 143, 3041, 143, 145, 3041, 3041, 3041, 3041, 3041, + 145, 148, 148, 3041, 3041, 3041, 148, 148, 150, 3041, + + 3041, 3041, 3041, 3041, 150, 152, 152, 3041, 152, 152, + 152, 152, 75, 75, 3041, 75, 75, 75, 75, 13, + 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, + 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, + 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, + 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041 } ; -static const flex_int16_t yy_chk[5854] = +static const flex_int16_t yy_chk[5961] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -2061,13 +2091,13 @@ static const flex_int16_t yy_chk[5854] = 5, 3, 6, 20, 4, 20, 20, 5, 20, 6, 7, 7, 7, 7, 20, 7, 8, 8, 8, 8, 29, 8, 7, 9, 9, 9, 22, 22, 8, 10, - 10, 10, 15, 25, 9, 29, 15, 25, 2991, 31, + 10, 10, 15, 25, 9, 29, 15, 25, 3047, 31, 10, 11, 11, 11, 11, 11, 11, 19, 79, 19, 19, 30, 19, 11, 31, 79, 30, 25, 19, 19, 47, 47, 11, 12, 12, 12, 12, 12, 12, 21, 23, 23, 21, 21, 24, 12, 21, 81, 23, 24, - 34, 21, 23, 24, 12, 23, 24, 999, 24, 24, + 34, 21, 23, 24, 12, 23, 24, 1000, 24, 24, 21, 26, 26, 27, 27, 90, 28, 81, 32, 32, 28, 34, 27, 28, 33, 33, 26, 32, 36, 33, 28, 35, 28, 32, 90, 42, 35, 32, 52, 84, @@ -2220,483 +2250,494 @@ static const flex_int16_t yy_chk[5854] = 665, 668, 669, 666, 660, 661, 664, 670, 669, 671, 672, 662, 673, 671, 674, 675, 676, 678, 677, 679, - 668, 675, 672, 680, 676, 677, 714, 670, 714, 681, - 683, 689, 674, 686, 681, 678, 690, 673, 681, 691, - 689, 681, 690, 680, 679, 683, 693, 693, 681, 692, - 686, 681, 696, 692, 697, 691, 694, 694, 698, 699, - 704, 701, 709, 702, 703, 699, 701, 717, 697, 705, - 696, 717, 705, 706, 706, 708, 708, 709, 698, 700, - 700, 700, 703, 700, 702, 704, 700, 707, 710, 710, - 711, 700, 716, 712, 707, 711, 712, 700, 700, 713, + 668, 675, 672, 680, 676, 677, 683, 670, 690, 686, + 689, 691, 674, 698, 690, 678, 692, 673, 696, 689, + 692, 683, 70, 680, 679, 681, 686, 691, 693, 693, + 681, 694, 694, 698, 681, 697, 696, 681, 701, 702, + 699, 703, 704, 701, 681, 681, 699, 681, 707, 697, + 700, 700, 700, 705, 700, 707, 705, 700, 709, 703, + 702, 64, 700, 706, 706, 708, 708, 704, 700, 700, + 710, 710, 711, 709, 713, 712, 715, 711, 712, 713, - 715, 718, 720, 719, 713, 721, 721, 725, 722, 727, - 720, 716, 715, 723, 724, 724, 726, 749, 728, 730, - 730, 718, 719, 722, 728, 725, 749, 723, 726, 729, - 731, 727, 733, 734, 729, 731, 731, 733, 735, 734, - 736, 737, 739, 738, 735, 736, 738, 737, 739, 740, - 741, 741, 742, 742, 743, 744, 745, 740, 746, 747, - 750, 745, 743, 748, 748, 746, 751, 752, 750, 756, - 754, 755, 751, 744, 756, 757, 759, 760, 747, 754, - 755, 759, 758, 761, 757, 758, 752, 762, 763, 764, - 766, 760, 765, 765, 764, 764, 762, 767, 768, 769, + 714, 716, 714, 717, 718, 720, 719, 717, 715, 721, + 721, 722, 725, 720, 723, 724, 724, 726, 727, 760, + 716, 728, 730, 730, 718, 719, 722, 728, 723, 726, + 725, 729, 731, 760, 733, 734, 729, 731, 731, 733, + 727, 734, 735, 738, 736, 737, 738, 739, 735, 736, + 740, 737, 743, 739, 741, 741, 742, 742, 740, 744, + 743, 745, 746, 747, 748, 748, 745, 749, 751, 746, + 750, 752, 754, 761, 751, 755, 749, 744, 750, 757, + 756, 754, 747, 758, 755, 756, 758, 759, 757, 763, + 752, 762, 759, 765, 765, 766, 767, 768, 761, 764, - 770, 763, 772, 770, 772, 766, 774, 768, 761, 773, - 773, 770, 775, 776, 779, 777, 767, 775, 778, 780, - 781, 782, 783, 769, 784, 786, 783, 774, 785, 781, - 789, 786, 787, 788, 776, 777, 779, 790, 778, 780, - 791, 787, 784, 792, 782, 788, 791, 785, 793, 789, - 795, 790, 796, 793, 794, 794, 797, 792, 798, 799, - 800, 796, 801, 802, 804, 803, 798, 805, 806, 807, - 795, 803, 810, 805, 808, 807, 797, 813, 804, 799, - 808, 801, 800, 802, 811, 809, 818, 812, 806, 809, - 817, 810, 812, 814, 814, 815, 811, 816, 813, 818, + 762, 769, 763, 774, 764, 764, 768, 772, 770, 772, + 766, 770, 773, 773, 776, 767, 775, 777, 778, 770, + 779, 775, 781, 780, 774, 769, 782, 784, 783, 785, + 786, 781, 783, 789, 788, 776, 786, 777, 778, 790, + 792, 787, 779, 780, 795, 784, 788, 796, 785, 782, + 787, 791, 789, 790, 792, 793, 796, 791, 794, 794, + 793, 797, 798, 799, 795, 800, 801, 803, 802, 805, + 798, 806, 804, 803, 807, 805, 808, 810, 811, 812, + 807, 797, 808, 799, 812, 801, 804, 800, 802, 809, + 811, 806, 813, 809, 814, 814, 810, 815, 811, 816, - 816, 815, 820, 819, 811, 821, 821, 822, 817, 819, - 823, 824, 824, 825, 826, 823, 827, 827, 826, 828, - 829, 830, 820, 831, 833, 822, 830, 836, 825, 834, - 837, 839, 839, 840, 841, 842, 842, 840, 845, 843, - 829, 828, 831, 834, 846, 70, 844, 836, 833, 841, - 844, 837, 838, 845, 847, 838, 848, 838, 846, 847, - 849, 838, 850, 838, 843, 849, 849, 851, 838, 852, - 848, 851, 853, 838, 854, 855, 850, 853, 856, 854, - 857, 865, 858, 864, 852, 859, 860, 853, 858, 855, - 866, 859, 860, 862, 857, 861, 861, 863, 862, 856, + 817, 818, 816, 815, 819, 820, 821, 821, 822, 825, + 819, 823, 828, 813, 818, 829, 823, 826, 817, 824, + 824, 826, 827, 827, 825, 820, 822, 830, 831, 833, + 834, 836, 830, 837, 828, 829, 839, 839, 840, 842, + 842, 841, 840, 843, 834, 844, 845, 831, 846, 844, + 852, 836, 847, 833, 837, 838, 841, 847, 838, 848, + 838, 845, 846, 850, 838, 852, 838, 854, 843, 849, + 856, 838, 857, 848, 849, 849, 838, 850, 851, 854, + 853, 855, 851, 858, 856, 853, 855, 862, 862, 865, + 859, 866, 860, 857, 851, 853, 859, 858, 860, 861, - 865, 868, 869, 863, 870, 864, 873, 869, 866, 867, - 867, 873, 871, 868, 874, 867, 875, 867, 870, 872, - 872, 876, 874, 867, 871, 877, 878, 878, 867, 867, - 875, 881, 879, 883, 884, 867, 879, 881, 882, 885, - 876, 882, 887, 886, 877, 885, 888, 884, 886, 889, - 890, 891, 883, 892, 893, 888, 895, 891, 889, 894, - 896, 887, 892, 897, 894, 898, 890, 902, 907, 899, - 900, 905, 908, 893, 896, 901, 895, 898, 899, 900, - 903, 901, 907, 897, 902, 909, 903, 905, 910, 911, - 912, 913, 908, 914, 917, 921, 913, 918, 914, 917, + 867, 863, 864, 869, 870, 861, 863, 871, 864, 870, + 866, 865, 872, 873, 873, 869, 876, 874, 867, 868, + 868, 871, 874, 875, 872, 868, 59, 868, 877, 878, + 876, 875, 880, 868, 879, 879, 880, 882, 868, 868, + 884, 883, 885, 882, 883, 868, 886, 877, 878, 887, + 888, 889, 886, 890, 887, 885, 891, 892, 893, 884, + 889, 894, 890, 892, 896, 895, 898, 893, 897, 888, + 895, 899, 891, 902, 903, 904, 900, 906, 901, 902, + 894, 904, 897, 899, 896, 900, 898, 901, 908, 909, + 911, 903, 910, 906, 912, 913, 914, 919, 915, 924, - 919, 919, 910, 920, 909, 912, 918, 911, 921, 920, - 923, 924, 928, 927, 925, 925, 924, 924, 925, 926, - 929, 930, 926, 932, 931, 933, 923, 927, 935, 932, - 934, 940, 928, 937, 930, 936, 934, 941, 929, 931, - 936, 939, 941, 935, 939, 933, 942, 937, 943, 944, - 945, 942, 940, 946, 944, 945, 948, 949, 952, 952, - 950, 951, 948, 953, 943, 946, 950, 951, 954, 956, - 956, 955, 953, 949, 955, 957, 958, 959, 960, 961, - 964, 960, 962, 963, 967, 964, 954, 969, 962, 963, - 967, 965, 961, 957, 966, 958, 965, 959, 970, 966, + 918, 914, 908, 915, 911, 918, 919, 920, 920, 909, + 913, 910, 912, 921, 922, 924, 925, 927, 928, 921, + 927, 925, 925, 929, 926, 926, 930, 922, 926, 931, + 932, 933, 928, 934, 935, 936, 937, 933, 938, 941, + 935, 937, 931, 929, 930, 932, 940, 944, 54, 940, + 936, 942, 938, 934, 943, 947, 942, 945, 949, 943, + 941, 946, 945, 944, 949, 950, 946, 947, 951, 952, + 953, 953, 955, 954, 951, 952, 956, 957, 957, 956, + 958, 950, 954, 959, 960, 961, 962, 963, 961, 964, + 955, 965, 966, 963, 970, 964, 965, 966, 958, 962, - 971, 974, 972, 973, 973, 969, 971, 972, 975, 976, - 974, 977, 978, 979, 977, 978, 980, 975, 970, 981, - 982, 985, 983, 984, 979, 986, 988, 976, 983, 984, - 986, 981, 987, 987, 980, 989, 985, 991, 990, 982, - 992, 991, 993, 994, 995, 988, 997, 998, 998, 989, - 990, 993, 1000, 1001, 1003, 1002, 1005, 1005, 992, 1003, - 1006, 1004, 994, 1021, 1021, 997, 1000, 1002, 1001, 995, - 1004, 1007, 1008, 1010, 1009, 1010, 1011, 1007, 1008, 1009, - 1006, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1014, - 1019, 64, 1022, 1023, 1017, 1024, 1012, 1013, 1025, 1026, + 967, 968, 959, 971, 960, 967, 973, 968, 972, 974, + 974, 973, 970, 975, 972, 976, 977, 978, 979, 980, + 978, 979, 975, 971, 976, 981, 982, 983, 987, 984, + 980, 985, 986, 987, 977, 984, 989, 985, 982, 988, + 988, 991, 990, 981, 992, 993, 983, 986, 992, 994, + 995, 996, 998, 991, 1001, 989, 990, 1002, 994, 999, + 999, 1003, 1004, 993, 1007, 1005, 1013, 1004, 1001, 995, + 53, 998, 1002, 1003, 1005, 1008, 996, 1006, 1006, 1009, + 1013, 1008, 1010, 1014, 1007, 1009, 1011, 1010, 1011, 1012, + 1015, 1016, 1017, 1018, 1012, 1015, 1020, 1014, 1019, 1025, - 1015, 1031, 1027, 1018, 1025, 1016, 1022, 1027, 1031, 1019, - 1024, 1023, 1029, 1029, 1032, 1030, 1027, 1034, 1027, 1026, - 1030, 1027, 1033, 1035, 1036, 1033, 1037, 1039, 1032, 1036, - 1040, 1038, 1035, 1042, 1042, 1034, 1038, 1043, 1039, 1044, - 1045, 1046, 1043, 1047, 1044, 1037, 1046, 1047, 1048, 1040, - 1049, 1050, 1051, 1053, 1054, 1052, 1056, 1048, 1055, 1057, - 1045, 1054, 1060, 1058, 1061, 1049, 1050, 1052, 1053, 1062, - 1055, 1051, 1059, 1063, 1066, 1056, 1068, 1060, 1059, 1065, - 1057, 1058, 1063, 1067, 1061, 1065, 1070, 1069, 1066, 1062, - 1072, 1067, 1069, 1073, 1071, 1074, 1068, 1078, 1070, 1071, + 1018, 1022, 1022, 1023, 1024, 1027, 1016, 1028, 1030, 1030, + 1026, 1017, 1028, 1019, 1025, 1020, 1026, 1023, 1034, 1031, + 1036, 1028, 1024, 1028, 1031, 1027, 1028, 1032, 1032, 1033, + 1035, 1037, 1034, 1035, 1038, 1039, 1033, 1040, 1043, 1036, + 1039, 1041, 1042, 1038, 1045, 1045, 1041, 1046, 1048, 1037, + 1047, 1051, 1046, 1042, 1049, 1047, 1040, 1043, 1050, 1049, + 1051, 1052, 1050, 1053, 1054, 1055, 1056, 1057, 1048, 1059, + 1058, 1060, 1061, 1062, 1057, 1069, 1052, 1055, 1053, 1062, + 1063, 1056, 1058, 1054, 1064, 1065, 1070, 1066, 1059, 1069, + 1061, 1068, 1060, 1071, 1070, 1063, 1066, 1068, 1072, 1073, - 1071, 1075, 1075, 1077, 59, 1079, 1078, 1073, 1074, 1072, - 1076, 1079, 1080, 1080, 1083, 1076, 1077, 1081, 1076, 1076, - 1083, 1082, 1081, 1076, 1086, 1086, 1084, 1085, 1087, 1076, - 1082, 1084, 1085, 1076, 1088, 1088, 1089, 1090, 1091, 1089, - 1093, 1089, 1092, 1094, 1095, 1096, 1097, 1098, 1094, 1087, - 1099, 1092, 1097, 1098, 1108, 1099, 1091, 1090, 1095, 1101, - 1093, 1100, 1103, 1096, 1103, 1100, 1102, 1102, 1101, 1104, - 1106, 1107, 1108, 1101, 1106, 1101, 1109, 1101, 1110, 1101, - 1104, 1111, 1112, 1110, 1110, 1109, 1107, 1112, 1113, 1114, - 1115, 1116, 1117, 1118, 1119, 1119, 1120, 1121, 1114, 1118, + 1075, 1074, 1076, 1072, 1064, 1065, 1074, 1074, 1077, 1078, + 1078, 1073, 1080, 1071, 1081, 1084, 1076, 1085, 1082, 1075, + 1084, 1077, 1079, 1081, 1082, 1080, 1085, 1079, 1083, 1083, + 1079, 1079, 1086, 1090, 1087, 1079, 1093, 1088, 1086, 1087, + 1094, 1079, 1088, 1089, 1089, 1079, 1091, 1091, 1092, 1096, + 1095, 1092, 1097, 1092, 1090, 1099, 1093, 1097, 1094, 1095, + 1098, 1100, 1101, 1104, 1106, 1102, 1106, 1100, 1101, 1096, + 1102, 1103, 1104, 1099, 1098, 1103, 1107, 1104, 1109, 1104, + 1110, 1104, 1109, 1104, 1105, 1105, 1111, 1107, 1112, 1114, + 1118, 1115, 1116, 1113, 1117, 1110, 1115, 1112, 1113, 1113, - 1122, 1123, 1113, 1111, 1120, 1122, 1117, 1124, 1125, 1115, - 1116, 1121, 1126, 1127, 1129, 1123, 1124, 1135, 1127, 1128, - 1128, 1130, 1130, 1131, 1133, 1131, 1125, 1133, 1134, 1129, - 1136, 1137, 1137, 1134, 1138, 1142, 1135, 1126, 1143, 1136, - 1139, 1139, 1140, 1140, 1141, 1144, 1144, 1145, 1146, 1141, - 1147, 1146, 1148, 1149, 1138, 1151, 1142, 1148, 1150, 1143, - 1150, 1153, 1149, 1154, 1153, 1162, 1155, 1145, 1157, 1156, - 1147, 1155, 1158, 1151, 1156, 1159, 1157, 1158, 1154, 1161, - 1159, 1160, 1160, 1162, 1161, 1163, 1164, 1165, 1167, 1168, - 1170, 1163, 1169, 1164, 1167, 1168, 1170, 1169, 1171, 1172, + 1119, 1120, 1121, 1117, 1111, 1128, 1116, 1124, 1121, 1118, + 1123, 1114, 1122, 1122, 1126, 1120, 1127, 1125, 1123, 1119, + 1129, 1124, 1125, 1128, 1130, 1127, 1131, 1131, 1126, 1130, + 1138, 1132, 1133, 1133, 1134, 1136, 1134, 1137, 1136, 1139, + 1140, 1140, 1137, 1141, 1145, 1129, 1132, 1146, 1139, 1138, + 1142, 1142, 1143, 1143, 1144, 1147, 1147, 1148, 1149, 1144, + 1150, 1149, 1151, 1141, 1152, 1145, 1154, 1151, 1146, 1153, + 1157, 1153, 1156, 1152, 1158, 1156, 1159, 1148, 1160, 1158, + 1150, 1159, 1161, 1162, 1154, 1157, 1160, 1161, 1162, 1163, + 1163, 1164, 1165, 1166, 1167, 1168, 1164, 1170, 1171, 1166, - 1165, 1173, 1174, 1174, 1175, 1177, 1178, 1171, 1179, 1180, - 1181, 1183, 1173, 1184, 1179, 1180, 1181, 1183, 1172, 1185, - 1186, 1187, 1188, 1190, 1175, 1177, 1191, 1184, 1192, 1178, - 1189, 1189, 1186, 1184, 1195, 1187, 1193, 1194, 1194, 1185, - 1188, 1193, 1196, 1190, 1198, 54, 1192, 1196, 1199, 1200, - 1201, 1191, 1202, 1199, 1199, 1203, 1204, 1195, 1205, 1201, - 1202, 1212, 1207, 1198, 1207, 1208, 1209, 1200, 1213, 1203, - 1206, 1204, 1209, 1205, 1211, 1206, 1205, 1210, 1206, 1208, - 1212, 1210, 1214, 1215, 1216, 1211, 1217, 1218, 1215, 1220, - 1221, 1217, 1222, 1224, 1213, 1223, 1223, 1224, 1225, 1226, + 1172, 1167, 1174, 1170, 1171, 1172, 1173, 1175, 1168, 1176, + 1165, 1174, 1173, 1177, 1177, 1178, 1180, 1181, 1182, 1183, + 1176, 1184, 1186, 1187, 1182, 1183, 1175, 1184, 1186, 1188, + 1189, 1190, 1191, 1192, 1192, 1178, 1180, 1187, 1193, 1194, + 1181, 1195, 1189, 1187, 1198, 1190, 1196, 1197, 1197, 1188, + 1191, 1196, 1199, 1201, 1204, 1202, 1203, 1199, 1193, 1195, + 1202, 1202, 1205, 1204, 1194, 1206, 1207, 1198, 1208, 1210, + 1205, 1210, 1201, 1211, 1203, 1218, 1214, 1209, 1213, 1206, + 1214, 1207, 1209, 1208, 1213, 1209, 1208, 1211, 1215, 1216, + 1217, 1220, 1219, 1221, 1216, 1216, 1220, 1222, 1223, 1215, - 1214, 1228, 1216, 1220, 1229, 1227, 1230, 1218, 1221, 1231, - 1222, 1227, 1232, 1228, 1233, 1242, 1225, 1234, 1226, 1235, - 1230, 1237, 1234, 1229, 1231, 1236, 1235, 1232, 1238, 1240, - 1236, 1239, 1239, 1233, 1241, 1244, 1242, 1238, 1243, 1237, - 1241, 1244, 1245, 1243, 1240, 1246, 1246, 1251, 1245, 1247, - 1247, 1249, 1249, 1250, 1252, 1253, 1251, 1250, 1254, 1255, - 1256, 1256, 1257, 1258, 1260, 1259, 1255, 1261, 1266, 1253, - 1259, 1258, 1252, 1254, 1262, 1264, 1265, 1265, 1260, 1262, - 1262, 1267, 1257, 1263, 1268, 1269, 1261, 1266, 1263, 1263, - 1269, 1270, 1271, 1268, 1274, 1264, 1272, 1273, 1275, 1274, + 1225, 1218, 1222, 1226, 1227, 1228, 1228, 1230, 1229, 1217, + 1219, 1221, 1229, 1231, 1225, 1233, 1234, 1232, 1223, 1235, + 1242, 1226, 1227, 1232, 1236, 1230, 1237, 1233, 1238, 1239, + 1240, 1241, 1231, 1235, 1239, 1234, 1241, 1240, 1242, 1236, + 1243, 1237, 1244, 1244, 1245, 1246, 1247, 1238, 1248, 1243, + 1249, 1246, 1250, 1248, 1251, 1251, 1249, 1256, 1250, 1245, + 1252, 1252, 1254, 1254, 1255, 1257, 1256, 1247, 1255, 1260, + 1258, 1259, 1261, 1261, 1262, 1264, 1260, 1263, 1265, 1266, + 1264, 1269, 1267, 1257, 1258, 1263, 1259, 1267, 1267, 1271, + 1268, 1272, 1265, 1273, 1262, 1268, 1268, 1275, 1266, 1270, - 1267, 1276, 1277, 1273, 1280, 1278, 1281, 1276, 1282, 1279, - 1270, 1278, 1271, 1283, 1272, 1279, 1284, 1285, 1286, 1287, - 1287, 1277, 1289, 1280, 1275, 1281, 1288, 1282, 1293, 1288, - 1284, 1294, 1283, 1286, 1289, 1290, 1290, 1291, 1285, 1292, - 1294, 1293, 1291, 1292, 1295, 1296, 1299, 1296, 1298, 1300, - 1301, 1296, 1305, 1298, 1302, 1302, 1304, 1295, 1303, 1306, - 1307, 1299, 1304, 1303, 1296, 1307, 1301, 1305, 1310, 1300, - 1308, 1309, 1306, 1311, 1308, 1309, 1312, 1313, 1314, 1314, - 1316, 1318, 1319, 1313, 1320, 1320, 1321, 1319, 1310, 1322, - 1328, 1311, 1321, 1324, 1324, 1329, 1312, 1326, 1316, 1332, + 1270, 1269, 1273, 1276, 1274, 1278, 1277, 1279, 1271, 1274, + 1272, 1278, 1279, 1280, 1281, 1282, 1275, 1285, 1286, 1283, + 1281, 1284, 1287, 1276, 1277, 1283, 1288, 1284, 1289, 1290, + 48, 1291, 1292, 1292, 1282, 1293, 1285, 1286, 1293, 1280, + 1294, 1287, 1289, 1295, 1295, 1288, 1291, 1297, 1296, 1298, + 1290, 1297, 1294, 1296, 1299, 1300, 1303, 1304, 1301, 1305, + 1301, 1303, 1298, 1299, 1301, 1306, 1307, 1307, 1300, 1308, + 1309, 1310, 1304, 1312, 1308, 1311, 1309, 1301, 1312, 1305, + 1313, 1306, 1315, 1314, 1313, 1316, 1310, 1314, 1311, 1317, + 1318, 1319, 1319, 1321, 1323, 1324, 1318, 1325, 1325, 1326, - 1326, 1333, 1318, 1327, 1327, 1331, 1328, 1335, 1331, 1322, - 1333, 1329, 1334, 1334, 1336, 1337, 1338, 1339, 1341, 1332, - 1343, 1338, 1335, 1340, 1340, 1342, 1344, 1344, 1345, 1346, - 1353, 1339, 1347, 1348, 1337, 1336, 1341, 1347, 1349, 1349, - 1342, 1351, 1345, 1352, 1352, 1343, 1350, 1346, 1348, 1354, - 1350, 1355, 1353, 1356, 1357, 1355, 1359, 1359, 1360, 1357, - 1354, 1351, 1362, 1361, 1363, 1364, 1365, 1365, 1366, 1367, - 1369, 1368, 1356, 1366, 1371, 1370, 1360, 1361, 1363, 1369, - 1370, 1362, 1362, 1372, 1375, 1372, 1378, 1373, 1380, 1367, - 1364, 1368, 1373, 1374, 1371, 1376, 1379, 1379, 1383, 1374, + 1324, 1327, 1315, 1316, 1333, 1326, 1329, 1329, 1334, 1317, + 1331, 1321, 1337, 1331, 1338, 1323, 1332, 1332, 1340, 1336, + 1333, 1327, 1336, 1338, 1334, 1339, 1339, 1341, 1342, 1343, + 1344, 1346, 1337, 1340, 1343, 1345, 1345, 1347, 1348, 1349, + 1349, 1350, 1351, 1353, 1344, 1352, 1356, 1342, 1341, 1346, + 1352, 1358, 1347, 1354, 1354, 1350, 1359, 1355, 1353, 1361, + 1351, 1355, 1365, 1348, 1357, 1357, 1356, 1359, 1360, 1362, + 1364, 1364, 1360, 1358, 1362, 1366, 1367, 1368, 1361, 1369, + 1365, 1370, 1370, 1371, 1374, 1372, 1373, 1375, 1371, 1366, + 1376, 1368, 1375, 1374, 1379, 1367, 1367, 1377, 1378, 1377, - 1378, 1376, 1381, 1383, 1375, 1384, 1387, 1380, 1381, 1385, - 1385, 1386, 1386, 1388, 1390, 1389, 1392, 1390, 1391, 1391, - 1387, 1393, 1399, 1400, 1403, 1403, 1400, 1395, 1392, 1384, - 1389, 1388, 1394, 1395, 1396, 1394, 1397, 1398, 1394, 1396, - 1401, 1393, 1398, 1402, 1407, 1397, 1401, 1399, 1402, 1405, - 1394, 1404, 1404, 1406, 1408, 1405, 1409, 1407, 1406, 1410, - 1411, 1412, 1413, 1411, 1414, 1415, 1416, 1412, 1413, 1414, - 1420, 1415, 1408, 1417, 1421, 1409, 1418, 1418, 1417, 1410, - 1419, 1422, 1423, 1424, 1427, 1419, 1425, 1426, 1420, 1416, - 1427, 1428, 1429, 1430, 1421, 1431, 1423, 1424, 1425, 1434, + 1379, 1380, 1381, 1378, 1369, 1372, 1373, 1385, 1381, 1383, + 1376, 1384, 1384, 1386, 1389, 1388, 1390, 1390, 1392, 1386, + 1388, 1380, 1393, 1383, 1391, 1391, 1385, 1394, 1395, 1396, + 1396, 1395, 1392, 1397, 1398, 1406, 1402, 1400, 1389, 1402, + 1393, 1399, 1394, 1400, 1399, 1397, 1401, 1399, 1404, 1407, + 1408, 1401, 1407, 1405, 1398, 1402, 1408, 1404, 1405, 1399, + 1406, 1409, 1410, 1410, 1411, 1411, 1409, 1412, 1414, 1413, + 1415, 1416, 1417, 1412, 1413, 1418, 1419, 1420, 1418, 1421, + 1422, 1414, 1419, 1420, 1421, 1423, 1422, 1427, 1415, 1424, + 1416, 1428, 1417, 1426, 1424, 1425, 1425, 1429, 1426, 1430, - 1426, 1422, 1433, 1433, 1435, 1436, 1436, 1430, 1437, 1435, - 1438, 1428, 1429, 1439, 1440, 1442, 1431, 1441, 1443, 1434, - 1445, 1449, 1444, 1437, 1438, 1443, 1441, 1447, 1451, 1451, - 1442, 1444, 1440, 1453, 1444, 1450, 1445, 1439, 1450, 1452, - 1452, 1454, 1447, 1456, 1456, 1453, 1449, 1447, 1455, 1457, - 1458, 1455, 1459, 1460, 1461, 1462, 1463, 1459, 1460, 1454, - 1464, 1466, 1457, 1465, 1469, 1463, 1468, 1468, 1467, 1458, - 1466, 1462, 1465, 1461, 1467, 1465, 1470, 1471, 1472, 1464, - 1473, 1474, 1476, 1477, 1469, 1478, 1478, 1479, 1480, 1470, - 1482, 1482, 1472, 1474, 1481, 1471, 1473, 1480, 1484, 1481, + 1431, 1434, 1435, 1432, 1436, 1427, 1433, 1434, 1423, 1437, + 1438, 1428, 1441, 1430, 1431, 1432, 1446, 1429, 1444, 1433, + 1440, 1440, 1435, 1437, 1436, 1442, 1443, 1443, 1445, 1447, + 1442, 1438, 1441, 1444, 1448, 1449, 1451, 1450, 1452, 1456, + 1446, 1454, 1445, 1448, 1450, 1451, 1457, 1447, 1451, 1457, + 1449, 1458, 1458, 1460, 1452, 1461, 1454, 1459, 1459, 1462, + 1465, 1454, 1462, 1464, 1456, 1460, 1463, 1463, 1468, 1466, + 1467, 1470, 1469, 1461, 1466, 1467, 1464, 1471, 1474, 1465, + 1470, 1472, 1473, 1476, 1474, 1475, 1475, 1468, 1469, 1477, + 1472, 1473, 1478, 1472, 1479, 1480, 1471, 1481, 1483, 1484, - 1483, 1477, 1485, 1479, 1486, 1482, 1489, 1476, 1487, 1483, - 1490, 1491, 1483, 1487, 1487, 1493, 1484, 1494, 53, 1492, - 1489, 1493, 1486, 1485, 1492, 1490, 1495, 1495, 1496, 1501, - 1502, 1497, 1498, 1491, 1496, 1494, 1497, 1499, 1498, 1503, - 1504, 1510, 1506, 1499, 1502, 1503, 1508, 1505, 1506, 1501, - 1505, 1511, 1513, 1504, 1508, 1512, 1505, 1522, 1514, 1515, - 1510, 1513, 1516, 1512, 1517, 1518, 1518, 1519, 1520, 1521, - 1511, 1514, 1515, 1519, 1520, 1523, 1516, 1522, 1517, 1524, - 1526, 1525, 1521, 1527, 1528, 1529, 1526, 1518, 1531, 1531, - 1532, 1533, 1534, 1523, 1525, 1533, 1535, 1534, 1524, 1536, + 1485, 1485, 1477, 1476, 1486, 1487, 1491, 1488, 1479, 1481, + 1478, 1480, 1488, 1490, 1487, 1489, 1489, 1484, 1492, 1493, + 1486, 1494, 1490, 1483, 1491, 1490, 1494, 1494, 1496, 1497, + 1489, 1498, 1501, 1499, 1500, 1502, 1502, 1493, 1499, 1492, + 1500, 1503, 1496, 1504, 1497, 1505, 1506, 1503, 1504, 1508, + 1501, 1505, 1506, 1498, 1509, 1510, 1512, 1511, 1513, 1512, + 1517, 1510, 1518, 1515, 1513, 1512, 1519, 1520, 1509, 1508, + 1511, 1515, 1521, 1522, 1519, 1523, 1520, 1524, 1526, 1517, + 1529, 1518, 1525, 1525, 1526, 1521, 1522, 1527, 1528, 1523, + 1530, 1524, 1531, 1527, 1532, 1534, 1533, 1535, 1536, 1539, - 1528, 1535, 1537, 1529, 1536, 1527, 1538, 1540, 1541, 1541, - 1532, 1537, 1542, 1543, 1544, 1545, 1545, 1547, 1546, 1554, - 1550, 1551, 1540, 1548, 1547, 1543, 1549, 1561, 1552, 1538, - 1553, 1542, 1546, 1544, 1552, 1548, 1561, 1554, 1549, 1550, - 1555, 1551, 1553, 1556, 1556, 1557, 1555, 1560, 1557, 1558, - 1558, 1562, 1560, 1563, 1563, 1564, 1565, 1562, 1565, 1566, - 1567, 1568, 1566, 1569, 1570, 1571, 1572, 1564, 1575, 1576, - 1571, 1574, 1573, 1575, 1577, 1572, 1581, 1578, 1576, 1580, - 1567, 1569, 1570, 1568, 1573, 1580, 1574, 1579, 1579, 1582, - 1583, 1576, 1578, 1584, 1577, 1586, 1585, 1581, 1585, 1587, + 1529, 1528, 1533, 1544, 1525, 1538, 1538, 1532, 1530, 1545, + 1540, 1531, 1544, 1535, 1540, 1541, 1536, 1534, 1542, 1539, + 1541, 1543, 1547, 1542, 1548, 1548, 1543, 1549, 1550, 1551, + 1552, 1552, 1545, 1553, 1554, 1557, 1558, 1547, 1555, 1556, + 1550, 1554, 1561, 1559, 1568, 1560, 1549, 1553, 1551, 1559, + 1555, 1556, 1562, 1568, 1557, 43, 1558, 1560, 1562, 1571, + 1561, 1563, 1563, 1564, 1565, 1565, 1564, 1567, 1569, 1570, + 1570, 1571, 1567, 1572, 1569, 1572, 1573, 1574, 1575, 1573, + 1576, 1577, 1578, 1579, 1580, 1582, 1581, 1578, 1584, 1586, + 1582, 1587, 1579, 1583, 1586, 1591, 1580, 1574, 1576, 1577, - 1587, 1588, 1588, 1589, 1589, 1590, 1583, 1593, 1582, 1586, - 1594, 1586, 1601, 1584, 1591, 1591, 1592, 1592, 1595, 1595, - 1596, 1597, 1603, 1598, 1596, 1590, 1598, 1597, 1593, 1600, - 1601, 1594, 1602, 1604, 1609, 1600, 1604, 1607, 1602, 1605, - 1605, 1606, 1606, 1607, 1608, 1610, 1611, 1603, 1612, 1616, - 1615, 1616, 1611, 1621, 1609, 1614, 1608, 1608, 1608, 1617, - 1614, 1614, 1618, 1608, 1615, 1610, 1619, 1620, 1612, 1622, - 1617, 1624, 1619, 1621, 1623, 1623, 1620, 1618, 1625, 1625, - 1626, 1627, 1628, 1628, 1629, 1629, 1630, 1633, 1633, 1634, - 1622, 1638, 1635, 1637, 1640, 1640, 1641, 1624, 1639, 1645, + 1575, 1581, 1583, 1590, 1585, 1592, 1587, 1589, 1584, 1585, + 1588, 1588, 1593, 1589, 1591, 1583, 1585, 1594, 1599, 1594, + 1595, 1592, 1596, 1596, 1590, 1597, 1597, 1598, 1598, 1600, + 1600, 1602, 1593, 1603, 1595, 1610, 1595, 1612, 1599, 1601, + 1601, 1604, 1604, 1605, 1606, 1607, 14, 1605, 1607, 1609, + 1606, 1611, 1602, 1610, 1603, 1609, 1613, 1611, 1624, 1613, + 1614, 1614, 1612, 1615, 1615, 1616, 1617, 1618, 1619, 1620, + 1621, 1616, 1624, 1630, 1627, 1620, 1623, 1631, 1617, 1617, + 1617, 1623, 1623, 1626, 1625, 1617, 1625, 1618, 1619, 1627, + 1621, 1628, 1629, 1630, 1626, 1632, 1632, 1628, 1631, 1633, - 1626, 1635, 1637, 1627, 1639, 1642, 1630, 1644, 1643, 1646, - 1646, 1647, 1638, 1648, 1634, 1643, 1644, 1641, 1650, 1652, - 1642, 1651, 1654, 1650, 1653, 1645, 1655, 1651, 1654, 1648, - 1657, 1653, 1655, 1656, 1656, 1657, 1658, 1647, 1659, 1652, - 1660, 1661, 1663, 1662, 1664, 1658, 1662, 1665, 1665, 1666, - 1668, 1667, 1669, 1661, 1671, 1666, 1669, 1672, 1659, 1660, - 1663, 1673, 1674, 1674, 1675, 1668, 1673, 1676, 1678, 1679, - 1664, 1667, 1669, 1679, 1671, 1680, 1681, 1682, 1682, 1672, - 1683, 1680, 1676, 1675, 1683, 1681, 1684, 1678, 1685, 1685, - 1686, 1687, 1692, 1688, 1689, 1690, 1691, 1684, 1692, 1689, + 1635, 1629, 1634, 1634, 1636, 1637, 1637, 1638, 1638, 1639, + 1642, 1642, 1643, 1644, 1646, 1647, 1649, 1649, 1648, 1650, + 1635, 1652, 1644, 1646, 1648, 1633, 1636, 1651, 1652, 1639, + 1653, 1654, 1655, 1655, 1656, 1657, 1647, 1643, 1659, 1653, + 1650, 1660, 1651, 1659, 1661, 1662, 1668, 1660, 1663, 1664, + 1669, 1657, 1662, 1667, 1663, 1664, 1666, 1654, 1665, 1665, + 1656, 1666, 1667, 1670, 1661, 1671, 1668, 1672, 1671, 1669, + 1673, 1674, 1674, 1675, 1676, 1670, 1677, 1678, 1680, 1675, + 1681, 1678, 1682, 1683, 1683, 1672, 1684, 1682, 1685, 1687, + 13, 1677, 1690, 1695, 1676, 1688, 1673, 1678, 1680, 1688, - 1697, 1694, 1684, 1693, 1697, 1687, 1694, 1695, 1695, 1696, - 1696, 1686, 1688, 1699, 1700, 1690, 1691, 1701, 1693, 1702, - 1702, 1704, 1699, 1703, 1703, 1700, 1704, 1704, 1705, 1706, - 1700, 1707, 1709, 1708, 1705, 1706, 1710, 1701, 1708, 1712, - 1714, 1713, 1710, 1715, 1709, 1713, 1719, 1716, 1717, 1718, - 1721, 1712, 1714, 1716, 1722, 1718, 1723, 1707, 1719, 1729, - 1725, 1723, 1721, 1725, 1726, 1726, 1727, 1727, 1715, 1730, - 1717, 1728, 1728, 1722, 1731, 1730, 1732, 1733, 1734, 1729, - 1731, 1732, 1738, 1733, 1736, 1738, 1739, 1734, 1742, 1736, - 1740, 1740, 1743, 1746, 1744, 1745, 1745, 1750, 1739, 1744, + 1689, 1690, 1681, 1685, 1693, 1684, 1689, 1692, 1687, 1691, + 1691, 1692, 1694, 1694, 1695, 1693, 1696, 1697, 1698, 1699, + 1693, 1700, 1701, 1698, 1703, 1702, 1704, 1704, 1701, 1703, + 1696, 1705, 1705, 1706, 1708, 1709, 1697, 1706, 1710, 1699, + 1702, 1700, 1716, 1708, 1711, 1711, 1709, 1712, 1712, 1713, + 1714, 1709, 1717, 1715, 1713, 1713, 1714, 1717, 1710, 1715, + 1718, 1719, 1721, 1723, 1724, 1722, 1726, 1719, 1716, 1722, + 1725, 1727, 1718, 1728, 1721, 1723, 1725, 1727, 1730, 1731, + 1734, 1732, 1738, 1734, 1747, 1728, 1732, 1747, 1726, 1724, + 1730, 1735, 1735, 1736, 1736, 1737, 1737, 1739, 1731, 1740, - 1742, 1747, 1746, 1748, 1743, 1751, 1747, 1752, 1748, 1749, - 1749, 1753, 1754, 1755, 1751, 1756, 1754, 1750, 1755, 1757, - 1760, 1756, 1759, 1759, 1764, 1752, 1761, 1762, 1762, 1765, - 1753, 1763, 1766, 1757, 1759, 1761, 1764, 1766, 1760, 1767, - 1763, 1770, 1770, 1772, 1773, 1774, 1772, 1776, 1778, 1777, - 1765, 1779, 1767, 1786, 1778, 1780, 1780, 1781, 1783, 1781, - 1773, 1774, 1776, 1777, 1782, 1782, 1783, 1785, 1779, 1787, - 1787, 1788, 1789, 1786, 1785, 1790, 1791, 1792, 1793, 1794, - 1788, 1797, 1800, 1798, 1795, 1799, 1799, 1790, 1791, 1792, - 1795, 1801, 1803, 1789, 1794, 1798, 1802, 1803, 1804, 1802, + 1743, 1741, 1738, 1739, 1742, 1740, 1741, 1745, 1748, 1743, + 1742, 1751, 1745, 1749, 1749, 1752, 1753, 1754, 1754, 1755, + 1748, 1753, 1759, 1751, 1756, 1757, 1760, 1752, 1755, 1756, + 1757, 1758, 1758, 1761, 1762, 1760, 1763, 1766, 1764, 1765, + 1763, 1767, 1759, 1764, 1768, 1765, 1769, 1771, 1771, 1772, + 1767, 1761, 1773, 1762, 1775, 1766, 1774, 1774, 1776, 1771, + 1769, 1773, 1768, 1775, 1777, 1779, 1778, 1772, 1782, 1782, + 1776, 1778, 1784, 1785, 1786, 1784, 1788, 1790, 1779, 1789, + 1791, 1792, 1792, 1790, 1793, 1777, 1793, 1794, 1794, 1785, + 1786, 1788, 1795, 1789, 1797, 1798, 1800, 1791, 1799, 1799, - 1800, 1797, 1806, 1795, 1793, 1808, 1807, 1806, 1807, 1809, - 1810, 1801, 1812, 1814, 1809, 1815, 1816, 1810, 1804, 1818, - 1817, 1812, 1817, 1808, 1815, 1820, 1821, 1820, 1816, 1822, - 1822, 1814, 1823, 1825, 1824, 1825, 1826, 1827, 1818, 1824, - 1821, 1826, 1827, 1828, 1829, 1830, 1832, 1831, 1833, 1835, - 1839, 1830, 1831, 1836, 1837, 1837, 1833, 1840, 1823, 1832, - 1841, 1828, 1838, 1838, 1829, 1839, 1841, 1836, 1835, 1842, - 1843, 1844, 1843, 1846, 1842, 1845, 1845, 1840, 1851, 1844, - 1847, 1847, 1848, 1848, 1849, 1846, 1850, 1844, 1853, 1855, - 1854, 1850, 1854, 1849, 1858, 1860, 1851, 1853, 1856, 1857, + 1795, 1797, 1801, 1805, 1802, 1800, 1803, 1804, 1807, 1806, + 1809, 1811, 1811, 1810, 1807, 1798, 1802, 1812, 1803, 1804, + 1813, 1815, 1816, 1801, 1806, 1810, 1815, 1807, 1814, 1805, + 1809, 1814, 1818, 1820, 1819, 1812, 1819, 1818, 1821, 1822, + 1813, 1824, 1816, 1821, 1826, 1827, 1822, 1828, 1830, 1833, + 1824, 1820, 1835, 1829, 1827, 1829, 1832, 1840, 1832, 1828, + 1834, 1834, 1826, 1833, 1836, 1838, 1837, 1830, 1837, 1836, + 1838, 1839, 1841, 1842, 1844, 1840, 1839, 1843, 1835, 1842, + 1845, 1847, 1843, 1848, 1849, 1849, 1851, 1844, 1845, 1850, + 1850, 1852, 1841, 1853, 1855, 1858, 1855, 1848, 1854, 1853, - 1853, 1865, 1864, 1856, 1856, 1868, 1858, 1860, 1857, 1861, - 1855, 1862, 1869, 1866, 1861, 1864, 1862, 1867, 1867, 1870, - 1871, 1865, 1866, 1868, 1872, 1874, 1875, 1876, 1877, 1885, - 1869, 1878, 1879, 1877, 1871, 1870, 1878, 1874, 1875, 1872, - 1882, 1879, 1884, 1886, 1887, 1888, 1882, 1876, 1884, 1890, - 1890, 1889, 1885, 1893, 1891, 1892, 1892, 1894, 1886, 1882, - 1889, 1894, 1887, 1891, 1895, 1896, 1902, 48, 1897, 1895, - 1888, 1898, 1893, 1897, 1897, 1899, 1900, 1898, 1896, 1900, - 1901, 1899, 1905, 1905, 1906, 1906, 1902, 1907, 1901, 1908, - 1908, 1909, 1909, 1910, 1911, 1912, 1907, 1913, 1923, 1906, + 1847, 1851, 1856, 1854, 1857, 1857, 1861, 1858, 1859, 1859, + 1856, 1852, 1860, 1860, 1862, 1861, 1863, 1865, 1856, 1862, + 1866, 1867, 1866, 1869, 1870, 1868, 1865, 1872, 1873, 1865, + 1868, 1868, 1869, 1873, 1863, 1874, 1870, 1876, 1877, 1872, + 1874, 1880, 1867, 1878, 1879, 1879, 1881, 1882, 1883, 1886, + 1876, 1884, 1878, 1887, 1888, 1889, 1897, 1900, 1877, 1880, + 1889, 1886, 1883, 1882, 1881, 1887, 1884, 1890, 1891, 1894, + 1896, 1898, 1890, 1899, 1888, 1894, 1896, 1891, 1901, 1897, + 1902, 1902, 1900, 1903, 1904, 1904, 1898, 1901, 1894, 1905, + 1906, 1899, 1903, 1907, 1906, 1909, 1908, 1910, 1907, 1911, - 1920, 1912, 1913, 1914, 1914, 1910, 1915, 1915, 1916, 1917, - 1906, 1924, 1911, 1916, 1919, 1917, 1924, 1921, 1919, 1925, - 1920, 1921, 1926, 1923, 1927, 1928, 1930, 1930, 1929, 1927, - 1931, 1932, 1934, 1933, 1931, 1935, 1936, 1926, 1933, 1938, - 1937, 1939, 1925, 1928, 1929, 1937, 1932, 1935, 1940, 1940, - 1943, 1944, 1938, 1942, 1945, 1936, 1946, 1947, 1934, 1939, - 1948, 1942, 1949, 1950, 1952, 1953, 1953, 43, 1954, 1943, - 1944, 1954, 1955, 1956, 1949, 1957, 1947, 1945, 1961, 1952, - 1946, 1948, 1958, 1958, 1950, 1955, 1962, 1956, 1957, 1959, - 1959, 1960, 1960, 1961, 1963, 1963, 1964, 1965, 1965, 1962, + 1909, 1909, 1913, 1910, 1912, 1911, 1914, 1912, 1905, 1908, + 1913, 1917, 1917, 1918, 1918, 1919, 1920, 1920, 1921, 1921, + 1922, 1924, 1923, 1929, 1919, 1925, 1914, 1924, 1918, 1929, + 1925, 1932, 1922, 1926, 1926, 1927, 1927, 1928, 1935, 1918, + 1923, 1931, 1928, 1933, 1936, 1931, 1937, 1933, 1939, 1936, + 1938, 1932, 1940, 1939, 1942, 1941, 1943, 1944, 1945, 1945, + 1946, 1943, 1947, 1935, 1946, 1938, 1949, 1948, 1950, 1937, + 1940, 1941, 1948, 1952, 1942, 1951, 1953, 1947, 1952, 1944, + 1950, 1954, 1955, 1955, 1958, 1957, 1959, 1960, 1961, 1953, + 1962, 1967, 1949, 1957, 1951, 1963, 1964, 1965, 1970, 1954, - 1969, 1966, 1968, 1970, 1971, 1964, 1966, 1968, 1964, 1972, - 1972, 1973, 1973, 1974, 1975, 1975, 1971, 1976, 1977, 1977, - 1969, 1978, 1979, 1970, 1980, 1980, 1982, 1979, 1981, 1981, - 1983, 1984, 1974, 1985, 1989, 1976, 1978, 1987, 1991, 1983, - 1982, 14, 1987, 1988, 1988, 1984, 1990, 1990, 1992, 1994, - 1994, 1996, 1985, 1989, 1992, 1993, 1991, 1997, 1993, 1995, - 1995, 1998, 1999, 1999, 2001, 1994, 2002, 2003, 2006, 2004, - 1996, 2007, 1997, 2004, 2005, 2005, 2008, 2010, 2010, 2011, - 1998, 2012, 2003, 2013, 2001, 2014, 2007, 2006, 2012, 2002, - 2015, 2008, 2016, 2017, 2017, 2018, 2019, 2013, 2019, 2011, + 1968, 1968, 1972, 1958, 1969, 1959, 1967, 1969, 1964, 1962, + 1960, 1970, 1961, 1971, 1976, 1972, 1963, 1977, 1965, 1973, + 1973, 1974, 1974, 1975, 1975, 1978, 1978, 1971, 1979, 1976, + 1977, 1980, 1980, 1981, 1983, 1984, 1985, 1979, 1981, 1983, + 1979, 1986, 1987, 1987, 1988, 1988, 1989, 1990, 1990, 1991, + 1992, 1992, 1994, 1986, 1993, 1984, 1985, 1994, 1995, 1995, + 1996, 1996, 1997, 1998, 1999, 1989, 2000, 1991, 2002, 1993, + 2003, 2003, 1998, 2002, 2004, 2007, 1997, 2006, 1999, 2005, + 2005, 2007, 2011, 2008, 2012, 2000, 2008, 2009, 2009, 2010, + 2010, 2013, 2016, 2004, 2017, 2006, 2014, 2014, 2018, 2012, - 2022, 2023, 2020, 2014, 2018, 2020, 2023, 2025, 2015, 2024, - 2026, 2028, 2022, 2027, 2024, 2029, 2028, 2035, 2016, 2031, - 2020, 2032, 2020, 2026, 2031, 2033, 2032, 2034, 2039, 2036, - 2040, 2037, 2025, 2034, 2027, 2036, 2037, 2038, 2035, 2042, - 2033, 2029, 2038, 2040, 2041, 2043, 2044, 2041, 2042, 2045, - 2046, 2047, 2051, 2039, 2043, 2044, 2048, 2047, 2045, 2049, - 2053, 2055, 2048, 2049, 2046, 2054, 2054, 2055, 2057, 2053, - 2056, 2056, 2051, 2059, 2063, 2060, 2061, 2061, 2062, 2056, - 2065, 2066, 2068, 2063, 2067, 2072, 2074, 2074, 2057, 2059, - 2057, 2060, 2065, 2062, 2068, 2070, 2071, 2066, 2070, 2067, + 2019, 2011, 2021, 2009, 2019, 2020, 2020, 2022, 2023, 2026, + 2013, 2027, 2016, 2018, 2025, 2025, 2028, 2017, 2027, 2029, + 2030, 2021, 2022, 2023, 2031, 2032, 2032, 2033, 2037, 2026, + 2028, 2034, 2041, 2034, 2042, 2040, 2033, 2029, 2030, 2035, + 2037, 2038, 2035, 2039, 2043, 2041, 2038, 2044, 2039, 2043, + 2031, 2046, 2048, 2047, 2050, 2042, 2046, 2035, 2047, 2035, + 2040, 2052, 2049, 2051, 2054, 2053, 2052, 2048, 2049, 2051, + 2053, 2055, 2057, 2044, 2056, 2050, 2058, 2056, 2059, 2060, + 2061, 2057, 2066, 0, 2055, 2058, 2062, 2059, 2060, 2054, + 2063, 2064, 2062, 2072, 2061, 2064, 2063, 2068, 2069, 2069, - 2073, 2071, 2075, 2075, 2079, 2072, 2077, 2077, 2078, 2079, - 2080, 2078, 2073, 2081, 2082, 2082, 2080, 2083, 2085, 2081, - 2084, 2084, 2086, 2087, 2088, 2088, 2091, 2095, 2090, 2091, - 2085, 2083, 2090, 2092, 2092, 2093, 2086, 2094, 2098, 2096, - 2093, 2101, 2087, 2096, 2097, 2097, 2094, 2095, 2100, 2102, - 2103, 2098, 2104, 2100, 2105, 2106, 2104, 2107, 2109, 2108, - 2106, 2101, 2111, 2107, 2103, 2108, 2112, 2113, 2115, 2102, - 2115, 2112, 2114, 2113, 2105, 2118, 2109, 2121, 2111, 13, - 2114, 2119, 2119, 2120, 2122, 2122, 2120, 2124, 2125, 2118, - 2126, 2124, 2127, 2127, 2125, 2128, 2131, 2131, 2133, 2135, + 2074, 2070, 2066, 2071, 2071, 2075, 2068, 2070, 2076, 2076, + 2077, 2078, 2071, 2072, 2080, 2072, 2074, 2081, 2083, 2082, + 2078, 2075, 2087, 2086, 2085, 2077, 2080, 2085, 2086, 2088, + 2083, 2089, 2089, 2081, 2082, 2090, 2090, 2092, 2092, 2094, + 2093, 2088, 2087, 2093, 2094, 2095, 2096, 2097, 2097, 2098, + 2100, 2095, 2096, 2099, 2099, 2101, 2102, 2103, 2103, 2104, + 2105, 2106, 2100, 2098, 2108, 2104, 2106, 2109, 2108, 2101, + 2109, 2110, 2110, 2111, 2105, 2102, 2112, 2113, 2111, 2114, + 2115, 2115, 2116, 2114, 2118, 2112, 2119, 2120, 2121, 2118, + 2122, 2123, 2127, 2124, 2122, 2116, 2129, 2113, 2124, 2125, - 2139, 2136, 2126, 2121, 2128, 2139, 2140, 2141, 2149, 2142, - 2143, 2143, 2141, 2135, 2142, 2147, 2133, 2136, 2145, 2145, - 2150, 2147, 2148, 2148, 2149, 2151, 2153, 2154, 2155, 2155, - 2151, 2157, 2140, 2159, 2160, 2158, 2162, 2162, 2163, 2154, - 2157, 2158, 2150, 2164, 2169, 2153, 2166, 2166, 2177, 2160, - 2168, 2159, 2167, 2167, 2170, 2168, 2172, 2163, 2172, 2171, - 2173, 2164, 2169, 2170, 2171, 2174, 2175, 2176, 2177, 2184, - 2178, 2268, 2176, 2268, 2173, 2178, 2179, 2179, 2175, 2174, - 2180, 2180, 2181, 2181, 2182, 2182, 2183, 2184, 2185, 2186, - 2186, 2187, 2187, 2185, 2188, 2189, 2190, 2191, 2183, 2192, + 2137, 2137, 2121, 2126, 2139, 2125, 2119, 2120, 2130, 2126, + 2127, 2123, 2129, 2130, 2131, 2132, 2133, 2136, 2133, 2138, + 2131, 2143, 2138, 2132, 2140, 2140, 2144, 2143, 2142, 2151, + 2139, 2136, 2142, 2145, 2145, 2146, 2149, 2149, 2144, 2153, + 2154, 2157, 2158, 2159, 2146, 2160, 2157, 2151, 2159, 2167, + 2160, 2161, 2161, 2153, 2163, 2163, 2154, 2165, 2166, 2166, + 2168, 2169, 2171, 2165, 2172, 2167, 2169, 2176, 2158, 2173, + 2173, 2175, 2177, 2176, 2178, 2181, 2172, 2180, 2180, 2182, + 2175, 2171, 2168, 2184, 2184, 2185, 2185, 2186, 2187, 2178, + 2177, 2188, 2186, 2189, 2181, 2191, 2192, 2182, 2189, 2190, - 2192, 2193, 2194, 2194, 2195, 2195, 2188, 2189, 2196, 2197, - 2198, 2199, 2200, 2191, 2202, 2203, 2190, 2198, 2206, 2196, - 2193, 2197, 2201, 2199, 2204, 2204, 2207, 2201, 2205, 2208, - 2209, 2210, 2200, 2213, 2202, 2203, 2214, 2205, 2211, 2211, - 2212, 2216, 2208, 2217, 2206, 2210, 2207, 2218, 2213, 2212, - 2219, 2214, 2220, 2219, 2209, 2221, 2222, 2223, 2223, 2216, - 2221, 2222, 2224, 2224, 2230, 2217, 2220, 2225, 2225, 2231, - 2218, 2227, 2227, 2229, 2229, 2232, 2234, 2235, 2236, 2237, - 2231, 2238, 2230, 2239, 2240, 2241, 2241, 2243, 2243, 2244, - 2238, 2250, 2245, 0, 2232, 2235, 2234, 2246, 2246, 2237, + 2188, 2190, 2193, 2194, 2195, 0, 2187, 2196, 2194, 2191, + 2192, 2201, 2196, 2202, 2193, 2197, 2197, 2198, 2198, 2199, + 2199, 2200, 2200, 2201, 2195, 2203, 2204, 2204, 2205, 2205, + 2203, 2202, 2206, 2207, 2208, 2209, 2210, 2210, 2211, 2212, + 2212, 2213, 2213, 2215, 2206, 2207, 2216, 2214, 2217, 2218, + 2220, 2209, 2221, 2216, 2208, 2215, 2219, 2211, 2214, 2223, + 2217, 2219, 2222, 2222, 2224, 2225, 2226, 2227, 2223, 2218, + 2220, 2230, 2221, 2228, 2229, 2229, 2234, 2231, 2232, 2226, + 2230, 2235, 2236, 2237, 2238, 2225, 2237, 2228, 2241, 2241, + 2224, 2227, 2231, 2232, 2234, 2239, 2240, 2248, 2238, 2250, - 2236, 2245, 2240, 2239, 2248, 2249, 2249, 2251, 2252, 2250, - 2254, 2244, 2253, 2248, 2255, 2252, 2257, 2256, 2258, 2258, - 2259, 2259, 2261, 2260, 2262, 2251, 2263, 2253, 2254, 2260, - 2265, 2264, 2255, 2256, 2266, 2257, 2264, 2267, 2273, 2262, - 2261, 2276, 2267, 2269, 2269, 2263, 2270, 2275, 2270, 2277, - 2265, 2271, 2271, 2278, 2266, 2280, 2275, 2273, 2279, 2281, - 2276, 2277, 2284, 2279, 2285, 2286, 2286, 2285, 2287, 2288, - 2289, 2289, 2290, 2278, 2292, 2280, 2290, 2293, 2281, 2294, - 2294, 2293, 2284, 2287, 2295, 2297, 2298, 2288, 2301, 2292, - 2299, 2299, 2302, 2305, 2303, 2304, 2304, 2295, 2303, 2307, + 2239, 2240, 2252, 2235, 2254, 2236, 2242, 2242, 2243, 2243, + 2245, 2245, 2247, 2247, 2249, 2248, 2253, 2255, 2250, 2256, + 2257, 2258, 2252, 2258, 2259, 2249, 2254, 2260, 2256, 2261, + 2262, 2262, 2264, 2264, 2253, 2265, 2271, 2255, 2272, 2266, + 2257, 2267, 2267, 2269, 2259, 2260, 2273, 2261, 2266, 2270, + 2270, 2274, 2269, 2273, 2271, 2275, 2272, 2265, 2276, 2277, + 2278, 2279, 2279, 2280, 2280, 2281, 2274, 2282, 2283, 2284, + 2286, 2281, 2285, 2275, 2287, 2277, 2276, 2285, 2289, 2278, + 2289, 2288, 2291, 2283, 2291, 2282, 2288, 2294, 2284, 2296, + 2286, 2290, 2290, 2297, 2287, 2292, 2292, 2298, 2296, 2299, - 2301, 2302, 2306, 2306, 2307, 2297, 2298, 2308, 2309, 2310, - 2311, 2311, 2305, 2316, 2316, 2317, 2308, 2318, 2318, 2319, - 2320, 2310, 2321, 2324, 2309, 2322, 2323, 2323, 2326, 2326, - 2329, 2321, 2319, 2320, 2322, 2329, 2330, 2317, 2324, 2331, - 2332, 2330, 2333, 2334, 2336, 2332, 2335, 2614, 2338, 2339, - 2333, 2340, 2336, 2331, 2339, 2335, 2340, 2341, 2342, 2342, - 2343, 2343, 2334, 2338, 2344, 2345, 2346, 2347, 2348, 2614, - 2345, 2344, 2341, 2349, 2348, 2350, 2350, 2351, 2349, 2353, - 2353, 2352, 2354, 2354, 2346, 2347, 2352, 2357, 2358, 2358, - 2359, 2360, 2351, 2359, 2361, 2363, 2360, 2360, 2362, 2361, + 2300, 2301, 2308, 2302, 2305, 2300, 2294, 2306, 2309, 2298, + 2306, 0, 2297, 2307, 2307, 2310, 2310, 2308, 2313, 2299, + 2318, 2301, 2302, 2311, 2305, 2314, 2309, 2311, 2316, 2314, + 2315, 2315, 2319, 2313, 2320, 2320, 2322, 2323, 2324, 2326, + 2318, 2316, 2324, 2325, 2325, 2329, 2323, 2330, 2322, 2327, + 2327, 2328, 2319, 2331, 2329, 2338, 2328, 2340, 2326, 2332, + 2332, 2337, 2337, 2330, 2342, 2331, 2339, 2339, 2341, 2343, + 2340, 2344, 2344, 2342, 2345, 2347, 2347, 2338, 2343, 2350, + 2351, 2341, 2352, 2353, 2350, 2351, 2354, 2355, 2353, 2345, + 2356, 2367, 2357, 2359, 2354, 2362, 2352, 2360, 2361, 2356, - 2357, 2363, 2364, 2362, 2365, 2366, 2364, 2367, 2368, 2365, - 2369, 2370, 2372, 2375, 2366, 2369, 2368, 2372, 2373, 2377, - 2379, 2373, 2367, 2370, 2377, 2375, 2378, 2380, 2381, 2387, - 2382, 2378, 2383, 2383, 2384, 2388, 2393, 2381, 2379, 2382, - 2380, 2389, 2391, 2384, 2390, 2390, 2395, 2392, 2387, 2394, - 2394, 2393, 2397, 2399, 2400, 2388, 2392, 2402, 2400, 0, - 2389, 2391, 2401, 2401, 2403, 2395, 2404, 2397, 2405, 2407, - 2403, 2410, 2404, 2399, 2405, 2406, 2406, 2407, 2408, 2411, - 2410, 2413, 2402, 2408, 2414, 2413, 2415, 2417, 2417, 2418, - 2418, 2427, 2411, 2419, 2419, 2421, 2421, 2423, 2414, 2422, + 2357, 2368, 2360, 2361, 2363, 2363, 2355, 2365, 2359, 2367, + 2362, 2364, 2364, 2366, 2365, 2369, 2372, 2370, 2366, 2368, + 2373, 2369, 2370, 2371, 2371, 2373, 2374, 2374, 2375, 2375, + 2378, 2372, 2379, 2379, 2380, 2381, 2390, 2380, 2403, 2382, + 2381, 2381, 2383, 2378, 2382, 2384, 2385, 2383, 2386, 2387, + 2385, 2384, 2388, 2386, 2389, 2391, 2403, 2390, 2387, 2392, + 2394, 2391, 2389, 2393, 2396, 2392, 2399, 2388, 2393, 2396, + 2397, 2401, 2394, 2397, 2402, 2404, 2401, 2405, 2399, 2402, + 2406, 2407, 2407, 2408, 2411, 2412, 2405, 2413, 2404, 2406, + 2414, 2414, 2408, 2415, 2417, 2416, 2418, 2418, 2419, 2421, - 2432, 2415, 2423, 2422, 2425, 2425, 2429, 2428, 2430, 2433, - 2433, 2427, 2428, 2430, 2430, 2435, 2435, 2438, 2429, 2440, - 2432, 2436, 2436, 2437, 2442, 2446, 2437, 2443, 2443, 2448, - 2438, 2444, 2444, 2445, 2445, 2447, 2447, 2440, 2449, 2450, - 2446, 2451, 2448, 2457, 2442, 2452, 2452, 2451, 2453, 2456, - 2458, 2459, 2453, 2450, 2456, 2456, 2449, 2460, 2461, 2462, - 2472, 2463, 2477, 2460, 2461, 2463, 2457, 2464, 2464, 2467, - 2458, 2459, 2469, 2470, 2467, 2473, 2470, 2474, 2473, 2476, - 2469, 2475, 2477, 2480, 2462, 2472, 2475, 2478, 2479, 2479, - 2481, 2483, 2484, 2484, 2474, 2474, 2492, 2476, 2481, 2482, + 2423, 2425, 2425, 2411, 2416, 2412, 2413, 2424, 2426, 2417, + 2427, 2424, 2415, 2428, 2421, 2429, 2427, 2419, 2431, 2428, + 2423, 2429, 2430, 2430, 2432, 2434, 2431, 2435, 2437, 2432, + 2438, 2439, 2437, 2426, 2434, 2441, 2441, 2442, 2442, 2446, + 2435, 2443, 2443, 2446, 2438, 2447, 2439, 2445, 2445, 2451, + 2447, 2449, 2449, 2452, 2453, 2454, 2456, 2464, 2452, 2462, + 2454, 2454, 2457, 2457, 2459, 2459, 2453, 2460, 2460, 2451, + 2461, 2466, 2462, 2461, 2470, 2464, 2456, 2467, 2467, 2468, + 2468, 2469, 2469, 2471, 2471, 2472, 2473, 2474, 2475, 2470, + 2481, 2466, 2476, 2476, 2475, 2477, 2482, 2480, 2472, 2477, - 2489, 2478, 2480, 2491, 2482, 2482, 2485, 2485, 2486, 2486, - 2483, 2487, 2487, 2488, 2488, 2490, 2489, 2493, 2494, 2495, - 2490, 0, 2492, 2491, 2497, 2497, 2493, 2498, 2499, 2502, - 2498, 2501, 2501, 2503, 2503, 2504, 2502, 2511, 2494, 2495, - 2504, 2506, 2506, 2507, 2508, 2509, 2499, 2512, 2512, 2514, - 2515, 2517, 2507, 2508, 2509, 2511, 2513, 2516, 2514, 2518, - 2513, 2522, 2516, 2516, 2517, 2515, 2522, 2526, 2518, 2523, - 2523, 2525, 2525, 2527, 2528, 2530, 2531, 2534, 2535, 2536, - 2537, 2526, 2539, 2541, 2530, 2543, 2537, 2535, 2531, 2559, - 2543, 2544, 2528, 0, 2539, 2559, 2544, 2546, 2527, 2536, + 2483, 2474, 2480, 2480, 2473, 2484, 2485, 2486, 2488, 2488, + 2487, 2484, 2485, 2481, 2487, 2493, 2482, 2491, 2494, 2496, + 2483, 2494, 2491, 2493, 2497, 2498, 2499, 2497, 2500, 2501, + 0, 2499, 2486, 2502, 2503, 2503, 2504, 2505, 2506, 2507, + 2505, 2510, 2498, 2498, 2496, 2508, 2500, 2502, 2505, 2501, + 2504, 2509, 2506, 2508, 2511, 2511, 2509, 2509, 2507, 2516, + 2510, 2512, 2512, 2513, 2513, 2514, 2514, 2515, 2515, 2517, + 2518, 2519, 2520, 2521, 2517, 2516, 2522, 2524, 2524, 2525, + 2526, 2520, 2525, 2528, 2528, 2529, 2530, 2530, 2538, 2531, + 2518, 0, 2529, 2521, 2531, 2534, 2522, 2519, 2526, 2533, - 2545, 2545, 2534, 2548, 2541, 2555, 2546, 2556, 2548, 2549, - 2549, 2551, 2551, 2549, 2552, 2552, 2553, 2553, 2554, 2557, - 2562, 2562, 2563, 2560, 2557, 2555, 2556, 2554, 2560, 2561, - 2564, 2565, 2566, 2567, 2561, 2568, 2565, 2569, 2569, 2567, - 2563, 2572, 2571, 2573, 2575, 2575, 2577, 2582, 2579, 2578, - 2566, 2564, 2579, 2581, 2585, 2580, 2572, 2583, 2587, 2577, - 2568, 2571, 2578, 2573, 2580, 2583, 2582, 2584, 2592, 2581, - 2586, 2586, 2584, 2589, 2589, 2590, 2590, 2587, 2594, 2594, - 2585, 2596, 2597, 2598, 2602, 2599, 2601, 2601, 2603, 2592, - 2599, 2604, 2606, 2606, 2607, 2608, 2608, 2596, 2597, 2598, + 2533, 2535, 2536, 2541, 2534, 2540, 2538, 2539, 2539, 2540, + 2535, 2536, 2541, 2542, 2543, 2545, 2544, 2549, 2553, 2543, + 2543, 2554, 2549, 2555, 2545, 2550, 2550, 2557, 2542, 2544, + 2552, 2552, 2553, 2558, 2561, 2562, 2557, 2563, 2566, 2568, + 0, 2555, 2564, 2614, 2562, 2558, 2554, 2570, 2564, 2571, + 2566, 2614, 2570, 2573, 2571, 2572, 2572, 2563, 2575, 2561, + 2568, 2582, 2573, 2575, 2576, 2576, 2578, 2578, 2576, 2579, + 2579, 2580, 2580, 2581, 2583, 2584, 2590, 2586, 2591, 2587, + 2584, 2582, 2581, 2586, 2587, 2588, 2589, 2589, 2593, 2594, + 2588, 2592, 2595, 2583, 2590, 2594, 2592, 2596, 2596, 2591, - 2611, 2612, 2615, 2615, 2602, 2616, 2616, 2612, 2607, 2613, - 2604, 2603, 2617, 2619, 2613, 2618, 2618, 2620, 2621, 2622, - 2611, 2623, 2624, 2625, 2619, 2622, 2620, 2626, 2626, 2632, - 2627, 2633, 2617, 2627, 2624, 2618, 2628, 2628, 2621, 2634, - 2623, 2632, 2637, 2625, 2638, 2634, 2635, 2635, 2637, 2636, - 2640, 2633, 2636, 2641, 2642, 2640, 2648, 2643, 2641, 2644, - 2645, 2645, 2638, 2643, 2647, 2647, 2651, 2651, 2654, 2649, - 2652, 2652, 2666, 2642, 2653, 2648, 2644, 2644, 2649, 2653, - 2655, 2664, 2654, 2656, 2656, 2655, 2657, 2657, 2658, 2658, - 2659, 2661, 2661, 2667, 2666, 2659, 2668, 2669, 2669, 2672, + 2598, 2602, 2599, 2600, 2598, 2604, 2593, 2599, 2600, 2601, + 2601, 2603, 2606, 2606, 2608, 2609, 2612, 2595, 2610, 2613, + 2602, 2611, 2610, 2616, 2615, 2604, 2603, 2608, 2609, 2615, + 2611, 2618, 2612, 2617, 2617, 2620, 2620, 2623, 2613, 2621, + 2621, 2625, 2625, 2627, 2628, 2629, 2630, 2632, 2632, 2616, + 2618, 2630, 2633, 2634, 2635, 2637, 2637, 2638, 2623, 2627, + 2628, 2629, 2639, 2639, 2642, 2644, 2645, 2648, 2643, 2652, + 2644, 2638, 2633, 2635, 2643, 2650, 2634, 2646, 2646, 2647, + 2647, 2649, 2649, 2651, 2642, 2653, 2650, 2648, 2645, 2652, + 2654, 2653, 2651, 2655, 2656, 2657, 2657, 2658, 2659, 2659, - 2664, 2671, 2671, 2673, 2677, 2674, 2675, 2675, 2678, 2740, - 2677, 2679, 2680, 2672, 2674, 2667, 2740, 2680, 2668, 2683, - 2683, 2685, 2685, 2673, 2686, 2687, 2688, 2690, 2678, 2686, - 2679, 2689, 2688, 2691, 2691, 2690, 2692, 2694, 2695, 2687, - 2696, 2692, 2697, 2689, 2698, 2696, 2701, 2700, 2702, 2703, - 2698, 2705, 2704, 0, 2697, 2700, 2706, 2694, 2695, 2707, - 2717, 2708, 2711, 2712, 2717, 2701, 2708, 2705, 2702, 2703, - 2704, 2715, 2715, 2706, 2706, 2727, 2712, 2716, 2716, 2727, - 2707, 2733, 2711, 2721, 2721, 2723, 2723, 2724, 2724, 2730, - 2724, 2725, 2725, 2734, 2725, 2726, 2726, 2731, 2726, 2729, + 2658, 2649, 2664, 2663, 2665, 2655, 2666, 2666, 2667, 2654, + 2665, 2667, 2668, 2669, 2656, 2663, 2671, 2673, 2668, 2672, + 2674, 2671, 2664, 2675, 2672, 2678, 2674, 2676, 2676, 2679, + 2680, 2669, 2681, 2682, 2682, 2683, 2673, 2678, 2689, 2684, + 2675, 2675, 2686, 2686, 0, 2681, 2688, 2679, 2684, 2687, + 2687, 2688, 2689, 2690, 2683, 2680, 2691, 2691, 2690, 2692, + 2692, 2693, 2693, 2694, 2696, 2696, 2699, 2701, 2694, 2702, + 2703, 2704, 2704, 2706, 2706, 2708, 2707, 2709, 2710, 2710, + 2713, 2712, 2714, 2715, 0, 2699, 2709, 2712, 2715, 2701, + 2707, 2702, 2703, 2718, 2718, 2708, 2720, 2720, 2721, 2722, - 2729, 2733, 2739, 2735, 2736, 2736, 2741, 2730, 2735, 2742, - 2741, 2731, 2745, 2734, 2743, 2746, 2747, 2747, 2742, 2748, - 2748, 2749, 2749, 2750, 2746, 2752, 2751, 2739, 2755, 2743, - 2745, 2751, 2756, 2754, 2752, 2753, 2757, 2752, 2750, 2754, - 2753, 2753, 2760, 2758, 2759, 2761, 2761, 2756, 2758, 2759, - 2762, 2765, 2765, 2755, 2831, 2762, 2831, 2757, 2768, 2768, - 2780, 2760, 2769, 2769, 2770, 2770, 2771, 2771, 2772, 2772, - 2773, 2773, 2774, 2774, 2776, 2777, 2777, 2778, 2779, 2782, - 2780, 2783, 2783, 2776, 2784, 2786, 2778, 2785, 2787, 2787, - 2779, 2788, 2789, 2789, 2792, 2794, 2796, 2786, 2782, 2784, + 2713, 2714, 2723, 2721, 2724, 2729, 2725, 2727, 2723, 2726, + 2726, 2730, 2727, 2722, 2725, 2731, 2724, 2732, 2733, 2735, + 2731, 2736, 2737, 2738, 2733, 2729, 2739, 2735, 2746, 2732, + 2740, 2730, 2741, 2742, 2743, 2750, 2745, 2754, 2754, 2743, + 2736, 2745, 2737, 2738, 2739, 2747, 2740, 2748, 2746, 2741, + 2741, 2747, 2748, 2751, 2742, 2750, 2755, 2755, 2756, 2760, + 2760, 2766, 2756, 2762, 2762, 2766, 2751, 2763, 2763, 2769, + 2763, 2764, 2764, 2772, 2764, 2765, 2765, 2770, 2765, 2768, + 2768, 2773, 2778, 2774, 2775, 2775, 2780, 2769, 2774, 2779, + 2780, 2770, 2793, 2772, 2781, 2782, 2779, 2784, 2793, 2785, - 2785, 2793, 2795, 2795, 2793, 2798, 2788, 2799, 2798, 2800, - 2801, 2802, 2792, 2799, 2796, 2801, 2803, 2804, 2817, 2815, - 2806, 2794, 2815, 2800, 2818, 2818, 2819, 2819, 2820, 2820, - 2802, 2817, 2822, 2804, 2803, 2806, 2823, 2824, 2825, 2826, - 2828, 2824, 2830, 2829, 2832, 2823, 2835, 2830, 2833, 2833, - 2836, 2834, 2838, 2826, 2829, 2822, 2837, 2840, 2825, 2832, - 2839, 2841, 2842, 2828, 2834, 2835, 2846, 2842, 2836, 2847, - 2848, 2848, 2837, 2849, 2854, 2839, 2855, 2838, 2840, 2859, - 2846, 2841, 2849, 2850, 2850, 2851, 2851, 2852, 2852, 2847, - 2853, 2853, 2856, 2854, 2857, 2856, 2855, 2858, 2860, 2857, + 2819, 2773, 2789, 2781, 2786, 2786, 2794, 2778, 2785, 2819, + 2782, 2787, 2787, 2788, 2788, 2784, 2790, 2789, 2791, 2792, + 2795, 2790, 2796, 2797, 2792, 2792, 2799, 2791, 2797, 2798, + 2791, 2794, 2800, 2800, 2798, 2795, 2801, 2871, 2802, 2803, + 2803, 2871, 2801, 2796, 2802, 2799, 2804, 2804, 2805, 2808, + 2808, 2811, 2811, 2805, 2812, 2812, 2813, 2813, 2814, 2814, + 2815, 2815, 2816, 2816, 2817, 2817, 2820, 2820, 2821, 2822, + 2823, 2827, 2825, 2826, 2826, 2828, 2835, 2821, 2830, 2830, + 2829, 2822, 2831, 2832, 2832, 2837, 2827, 2839, 2828, 2842, + 2823, 2825, 2829, 2836, 2835, 2842, 2836, 2831, 2838, 2838, - 2861, 2862, 2858, 2863, 2859, 2865, 2861, 2864, 2864, 2866, - 2867, 2867, 2869, 2860, 2871, 2862, 2874, 2874, 2875, 2875, - 2865, 2876, 2877, 2863, 2878, 2879, 2880, 2869, 2866, 2876, - 2878, 2879, 2871, 2881, 2882, 2883, 2883, 2885, 2888, 2886, - 2880, 2877, 2891, 2889, 2892, 2893, 2881, 2889, 2894, 2892, - 2895, 2896, 2888, 2882, 2900, 2897, 0, 2901, 2885, 2886, - 2897, 2894, 2891, 2895, 2893, 2902, 2898, 2903, 2903, 2910, - 2896, 2898, 2904, 2905, 2900, 2901, 0, 2904, 2907, 2905, - 2906, 2906, 2908, 2907, 2902, 2909, 2911, 2908, 2910, 2917, - 2909, 2913, 2911, 2912, 2912, 2916, 2913, 2914, 2914, 2916, + 2841, 2843, 2844, 2841, 2845, 2839, 2846, 2844, 2849, 2847, + 2850, 2837, 2853, 2862, 2849, 2843, 2862, 2864, 2869, 2850, + 2865, 2865, 2872, 2845, 2846, 2847, 2870, 2853, 2866, 2866, + 2864, 2867, 2867, 2873, 2875, 2870, 2879, 2876, 2877, 2880, + 2880, 2869, 2872, 2877, 2878, 2881, 2878, 2873, 2876, 2882, + 2884, 2879, 2883, 2885, 2886, 2887, 2889, 2875, 2881, 2888, + 2890, 2895, 2891, 2896, 2887, 2898, 2884, 2891, 2882, 2886, + 2883, 2888, 2897, 2897, 2898, 2895, 2903, 2889, 2885, 2904, + 2890, 2899, 2899, 2896, 2900, 2900, 2901, 2901, 2902, 2902, + 2905, 2906, 2907, 2905, 2908, 2903, 2906, 2907, 2909, 2904, - 2918, 2919, 2920, 2921, 2922, 2923, 2930, 2918, 2917, 2921, - 2925, 2925, 2927, 2927, 2929, 2928, 2931, 2932, 2923, 2929, - 2919, 2920, 2937, 2922, 2928, 2930, 2934, 2928, 2933, 2933, - 2932, 2934, 2935, 2938, 2938, 2931, 2939, 2940, 2940, 2941, - 2941, 2942, 2943, 2944, 2951, 2935, 2942, 2946, 2937, 2943, - 2945, 2945, 2946, 2949, 2947, 2939, 2947, 2948, 2948, 2950, - 2949, 2953, 2944, 2951, 2952, 2956, 2950, 2955, 2955, 2952, - 2958, 2959, 2960, 2961, 2965, 2958, 2959, 2962, 2962, 2966, - 2953, 2964, 2964, 2969, 2956, 2967, 2967, 2968, 2968, 2979, - 2969, 2960, 2961, 2965, 2971, 2971, 2972, 2972, 2966, 2973, + 2910, 2911, 2912, 2913, 2914, 2916, 2910, 2917, 2913, 2915, + 2915, 2918, 2918, 2909, 2912, 2911, 2920, 2922, 2928, 2908, + 2916, 2925, 2925, 2929, 2914, 2927, 2917, 2926, 2926, 2929, + 2930, 2920, 2931, 2927, 2932, 2922, 2930, 2928, 2933, 2934, + 2935, 2935, 2936, 2936, 2934, 2938, 2931, 2932, 2939, 2941, + 2942, 2944, 2947, 2945, 2942, 2946, 2948, 2933, 2945, 2949, + 2952, 2952, 2950, 2941, 2955, 2947, 2938, 2950, 2939, 2948, + 2951, 2944, 2956, 2957, 2946, 2951, 2958, 2958, 2949, 2965, + 2959, 2960, 2961, 2961, 2955, 2959, 2962, 2960, 2963, 2964, + 2956, 2962, 2957, 2963, 2964, 2966, 2968, 2968, 2965, 2969, - 2975, 2980, 2978, 2981, 2981, 2975, 2973, 2978, 2979, 2982, - 2982, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2980, 2986, 2986, 2986, 2986, 2986, 2986, 2986, 2987, 2987, - 2987, 2987, 2987, 2987, 2987, 2988, 2988, 2988, 2988, 2988, - 2988, 2988, 2989, 2989, 2989, 2989, 2989, 2989, 2989, 2990, - 2990, 2990, 2990, 2990, 2990, 2990, 2992, 2992, 0, 2992, - 2992, 2992, 2992, 2993, 2993, 0, 0, 0, 2993, 2993, - 2994, 2994, 0, 0, 2994, 0, 2994, 2995, 0, 0, - 0, 0, 0, 2995, 2996, 2996, 0, 0, 0, 2996, - 2996, 2997, 0, 0, 0, 0, 0, 2997, 2998, 2998, + 2973, 2966, 2970, 2970, 2969, 2972, 2974, 2975, 2976, 2972, + 2977, 2978, 2979, 2974, 2981, 2981, 2977, 2983, 2983, 2973, + 2984, 2986, 2987, 2985, 2988, 2979, 2975, 2976, 2985, 2984, + 2978, 2990, 2984, 2989, 2989, 2991, 2990, 2988, 2993, 2995, + 2986, 2987, 2994, 2994, 2996, 2996, 2997, 2997, 2991, 2998, + 2999, 3000, 3001, 3001, 2998, 3002, 3007, 2999, 2995, 3003, + 3002, 3003, 3004, 3004, 2993, 3005, 3006, 3009, 3012, 3008, + 3000, 3016, 3005, 3006, 3008, 3007, 3011, 3011, 3014, 3015, + 3017, 3018, 3018, 3014, 3015, 3021, 3009, 3012, 3020, 3020, + 3016, 3022, 3023, 3023, 3024, 3024, 3025, 3027, 3027, 3017, - 0, 2998, 2998, 2998, 2998, 2999, 2999, 0, 2999, 2999, - 2999, 2999, 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, - 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, - 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, - 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, 2985, - 2985, 2985, 2985 + 3028, 3028, 3029, 3025, 3021, 3035, 3031, 3034, 3036, 3029, + 3022, 3031, 3034, 3037, 3037, 3038, 3038, 0, 0, 0, + 0, 0, 0, 0, 3035, 0, 0, 3036, 3042, 3042, + 3042, 3042, 3042, 3042, 3042, 3043, 3043, 3043, 3043, 3043, + 3043, 3043, 3044, 3044, 3044, 3044, 3044, 3044, 3044, 3045, + 3045, 3045, 3045, 3045, 3045, 3045, 3046, 3046, 3046, 3046, + 3046, 3046, 3046, 3048, 3048, 0, 3048, 3048, 3048, 3048, + 3049, 3049, 0, 0, 0, 3049, 3049, 3050, 3050, 0, + 0, 3050, 0, 3050, 3051, 0, 0, 0, 0, 0, + 3051, 3052, 3052, 0, 0, 0, 3052, 3052, 3053, 0, + + 0, 0, 0, 0, 3053, 3054, 3054, 0, 3054, 3054, + 3054, 3054, 3055, 3055, 0, 3055, 3055, 3055, 3055, 3041, + 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, + 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, + 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, + 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041, 3041 } ; static yy_state_type yy_last_accepting_state; @@ -2895,7 +2936,7 @@ static void config_end_include(void) } #endif -#line 2896 "" +#line 2937 "" #define YY_NO_INPUT 1 #line 184 "./util/configlexer.lex" #ifndef YY_NO_UNPUT @@ -2904,9 +2945,9 @@ static void config_end_include(void) #ifndef YY_NO_INPUT #define YY_NO_INPUT 1 #endif -#line 2905 "" +#line 2946 "" -#line 2907 "" +#line 2948 "" #define INITIAL 0 #define quotedstring 1 @@ -3128,7 +3169,7 @@ YY_DECL { #line 204 "./util/configlexer.lex" -#line 3129 "" +#line 3170 "" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@ -3161,13 +3202,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 2986 ) + if ( yy_current_state >= 3042 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 5813 ); + while ( yy_base[yy_current_state] != 5920 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -4318,331 +4359,363 @@ YY_RULE_SETUP case 225: YY_RULE_SETUP #line 433 "./util/configlexer.lex" -{ YDVAR(1, VAR_DNSTAP_SEND_IDENTITY) } +{ YDVAR(1, VAR_DNSTAP_IP) } YY_BREAK case 226: YY_RULE_SETUP #line 434 "./util/configlexer.lex" -{ YDVAR(1, VAR_DNSTAP_SEND_VERSION) } +{ YDVAR(1, VAR_DNSTAP_TLS) } YY_BREAK case 227: YY_RULE_SETUP #line 435 "./util/configlexer.lex" -{ YDVAR(1, VAR_DNSTAP_IDENTITY) } +{ YDVAR(1, VAR_DNSTAP_TLS_SERVER_NAME) } YY_BREAK case 228: YY_RULE_SETUP #line 436 "./util/configlexer.lex" -{ YDVAR(1, VAR_DNSTAP_VERSION) } +{ YDVAR(1, VAR_DNSTAP_TLS_CERT_BUNDLE) } YY_BREAK case 229: YY_RULE_SETUP #line 437 "./util/configlexer.lex" { - YDVAR(1, VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES) } + YDVAR(1, VAR_DNSTAP_TLS_CLIENT_KEY_FILE) } YY_BREAK case 230: YY_RULE_SETUP #line 439 "./util/configlexer.lex" { - YDVAR(1, VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES) } + YDVAR(1, VAR_DNSTAP_TLS_CLIENT_CERT_FILE) } YY_BREAK case 231: YY_RULE_SETUP #line 441 "./util/configlexer.lex" -{ - YDVAR(1, VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES) } +{ YDVAR(1, VAR_DNSTAP_SEND_IDENTITY) } YY_BREAK case 232: YY_RULE_SETUP -#line 443 "./util/configlexer.lex" -{ - YDVAR(1, VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES) } +#line 442 "./util/configlexer.lex" +{ YDVAR(1, VAR_DNSTAP_SEND_VERSION) } YY_BREAK case 233: YY_RULE_SETUP -#line 445 "./util/configlexer.lex" -{ - YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) } +#line 443 "./util/configlexer.lex" +{ YDVAR(1, VAR_DNSTAP_IDENTITY) } YY_BREAK case 234: YY_RULE_SETUP -#line 447 "./util/configlexer.lex" -{ - YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) } +#line 444 "./util/configlexer.lex" +{ YDVAR(1, VAR_DNSTAP_VERSION) } YY_BREAK case 235: YY_RULE_SETUP -#line 449 "./util/configlexer.lex" -{ YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) } +#line 445 "./util/configlexer.lex" +{ + YDVAR(1, VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES) } YY_BREAK case 236: YY_RULE_SETUP -#line 450 "./util/configlexer.lex" -{ YDVAR(1, VAR_IP_RATELIMIT) } +#line 447 "./util/configlexer.lex" +{ + YDVAR(1, VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES) } YY_BREAK case 237: YY_RULE_SETUP -#line 451 "./util/configlexer.lex" -{ YDVAR(1, VAR_RATELIMIT) } +#line 449 "./util/configlexer.lex" +{ + YDVAR(1, VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES) } YY_BREAK case 238: YY_RULE_SETUP -#line 452 "./util/configlexer.lex" -{ YDVAR(1, VAR_IP_RATELIMIT_SLABS) } +#line 451 "./util/configlexer.lex" +{ + YDVAR(1, VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES) } YY_BREAK case 239: YY_RULE_SETUP #line 453 "./util/configlexer.lex" -{ YDVAR(1, VAR_RATELIMIT_SLABS) } +{ + YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) } YY_BREAK case 240: YY_RULE_SETUP -#line 454 "./util/configlexer.lex" -{ YDVAR(1, VAR_IP_RATELIMIT_SIZE) } +#line 455 "./util/configlexer.lex" +{ + YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) } YY_BREAK case 241: YY_RULE_SETUP -#line 455 "./util/configlexer.lex" -{ YDVAR(1, VAR_RATELIMIT_SIZE) } +#line 457 "./util/configlexer.lex" +{ YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) } YY_BREAK case 242: YY_RULE_SETUP -#line 456 "./util/configlexer.lex" -{ YDVAR(2, VAR_RATELIMIT_FOR_DOMAIN) } +#line 458 "./util/configlexer.lex" +{ YDVAR(1, VAR_IP_RATELIMIT) } YY_BREAK case 243: YY_RULE_SETUP -#line 457 "./util/configlexer.lex" -{ YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) } +#line 459 "./util/configlexer.lex" +{ YDVAR(1, VAR_RATELIMIT) } YY_BREAK case 244: YY_RULE_SETUP -#line 458 "./util/configlexer.lex" -{ YDVAR(1, VAR_IP_RATELIMIT_FACTOR) } +#line 460 "./util/configlexer.lex" +{ YDVAR(1, VAR_IP_RATELIMIT_SLABS) } YY_BREAK case 245: YY_RULE_SETUP -#line 459 "./util/configlexer.lex" -{ YDVAR(1, VAR_RATELIMIT_FACTOR) } +#line 461 "./util/configlexer.lex" +{ YDVAR(1, VAR_RATELIMIT_SLABS) } YY_BREAK case 246: YY_RULE_SETUP -#line 460 "./util/configlexer.lex" -{ YDVAR(1, VAR_LOW_RTT) } +#line 462 "./util/configlexer.lex" +{ YDVAR(1, VAR_IP_RATELIMIT_SIZE) } YY_BREAK case 247: YY_RULE_SETUP -#line 461 "./util/configlexer.lex" -{ YDVAR(1, VAR_FAST_SERVER_NUM) } +#line 463 "./util/configlexer.lex" +{ YDVAR(1, VAR_RATELIMIT_SIZE) } YY_BREAK case 248: YY_RULE_SETUP -#line 462 "./util/configlexer.lex" -{ YDVAR(1, VAR_FAST_SERVER_PERMIL) } +#line 464 "./util/configlexer.lex" +{ YDVAR(2, VAR_RATELIMIT_FOR_DOMAIN) } YY_BREAK case 249: YY_RULE_SETUP -#line 463 "./util/configlexer.lex" -{ YDVAR(1, VAR_FAST_SERVER_PERMIL) } +#line 465 "./util/configlexer.lex" +{ YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) } YY_BREAK case 250: YY_RULE_SETUP -#line 464 "./util/configlexer.lex" -{ YDVAR(1, VAR_FAST_SERVER_PERMIL) } +#line 466 "./util/configlexer.lex" +{ YDVAR(1, VAR_IP_RATELIMIT_FACTOR) } YY_BREAK case 251: YY_RULE_SETUP -#line 465 "./util/configlexer.lex" -{ YDVAR(2, VAR_RESPONSE_IP_TAG) } +#line 467 "./util/configlexer.lex" +{ YDVAR(1, VAR_RATELIMIT_FACTOR) } YY_BREAK case 252: YY_RULE_SETUP -#line 466 "./util/configlexer.lex" -{ YDVAR(2, VAR_RESPONSE_IP) } +#line 468 "./util/configlexer.lex" +{ YDVAR(1, VAR_LOW_RTT) } YY_BREAK case 253: YY_RULE_SETUP -#line 467 "./util/configlexer.lex" -{ YDVAR(2, VAR_RESPONSE_IP_DATA) } +#line 469 "./util/configlexer.lex" +{ YDVAR(1, VAR_FAST_SERVER_NUM) } YY_BREAK case 254: YY_RULE_SETUP -#line 468 "./util/configlexer.lex" -{ YDVAR(0, VAR_DNSCRYPT) } +#line 470 "./util/configlexer.lex" +{ YDVAR(1, VAR_FAST_SERVER_PERMIL) } YY_BREAK case 255: YY_RULE_SETUP -#line 469 "./util/configlexer.lex" -{ YDVAR(1, VAR_DNSCRYPT_ENABLE) } +#line 471 "./util/configlexer.lex" +{ YDVAR(1, VAR_FAST_SERVER_PERMIL) } YY_BREAK case 256: YY_RULE_SETUP -#line 470 "./util/configlexer.lex" -{ YDVAR(1, VAR_DNSCRYPT_PORT) } +#line 472 "./util/configlexer.lex" +{ YDVAR(1, VAR_FAST_SERVER_PERMIL) } YY_BREAK case 257: YY_RULE_SETUP -#line 471 "./util/configlexer.lex" -{ YDVAR(1, VAR_DNSCRYPT_PROVIDER) } +#line 473 "./util/configlexer.lex" +{ YDVAR(2, VAR_RESPONSE_IP_TAG) } YY_BREAK case 258: YY_RULE_SETUP -#line 472 "./util/configlexer.lex" -{ YDVAR(1, VAR_DNSCRYPT_SECRET_KEY) } +#line 474 "./util/configlexer.lex" +{ YDVAR(2, VAR_RESPONSE_IP) } YY_BREAK case 259: YY_RULE_SETUP -#line 473 "./util/configlexer.lex" -{ YDVAR(1, VAR_DNSCRYPT_PROVIDER_CERT) } +#line 475 "./util/configlexer.lex" +{ YDVAR(2, VAR_RESPONSE_IP_DATA) } YY_BREAK case 260: YY_RULE_SETUP -#line 474 "./util/configlexer.lex" -{ YDVAR(1, VAR_DNSCRYPT_PROVIDER_CERT_ROTATED) } +#line 476 "./util/configlexer.lex" +{ YDVAR(0, VAR_DNSCRYPT) } YY_BREAK case 261: YY_RULE_SETUP -#line 475 "./util/configlexer.lex" -{ - YDVAR(1, VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE) } +#line 477 "./util/configlexer.lex" +{ YDVAR(1, VAR_DNSCRYPT_ENABLE) } YY_BREAK case 262: YY_RULE_SETUP -#line 477 "./util/configlexer.lex" -{ - YDVAR(1, VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS) } +#line 478 "./util/configlexer.lex" +{ YDVAR(1, VAR_DNSCRYPT_PORT) } YY_BREAK case 263: YY_RULE_SETUP #line 479 "./util/configlexer.lex" -{ YDVAR(1, VAR_DNSCRYPT_NONCE_CACHE_SIZE) } +{ YDVAR(1, VAR_DNSCRYPT_PROVIDER) } YY_BREAK case 264: YY_RULE_SETUP #line 480 "./util/configlexer.lex" -{ YDVAR(1, VAR_DNSCRYPT_NONCE_CACHE_SLABS) } +{ YDVAR(1, VAR_DNSCRYPT_SECRET_KEY) } YY_BREAK case 265: YY_RULE_SETUP #line 481 "./util/configlexer.lex" -{ YDVAR(1, VAR_IPSECMOD_ENABLED) } +{ YDVAR(1, VAR_DNSCRYPT_PROVIDER_CERT) } YY_BREAK case 266: YY_RULE_SETUP #line 482 "./util/configlexer.lex" -{ YDVAR(1, VAR_IPSECMOD_IGNORE_BOGUS) } +{ YDVAR(1, VAR_DNSCRYPT_PROVIDER_CERT_ROTATED) } YY_BREAK case 267: YY_RULE_SETUP #line 483 "./util/configlexer.lex" -{ YDVAR(1, VAR_IPSECMOD_HOOK) } +{ + YDVAR(1, VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE) } YY_BREAK case 268: YY_RULE_SETUP -#line 484 "./util/configlexer.lex" -{ YDVAR(1, VAR_IPSECMOD_MAX_TTL) } +#line 485 "./util/configlexer.lex" +{ + YDVAR(1, VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS) } YY_BREAK case 269: YY_RULE_SETUP -#line 485 "./util/configlexer.lex" -{ YDVAR(1, VAR_IPSECMOD_WHITELIST) } +#line 487 "./util/configlexer.lex" +{ YDVAR(1, VAR_DNSCRYPT_NONCE_CACHE_SIZE) } YY_BREAK case 270: YY_RULE_SETUP -#line 486 "./util/configlexer.lex" -{ YDVAR(1, VAR_IPSECMOD_STRICT) } +#line 488 "./util/configlexer.lex" +{ YDVAR(1, VAR_DNSCRYPT_NONCE_CACHE_SLABS) } YY_BREAK case 271: YY_RULE_SETUP -#line 487 "./util/configlexer.lex" -{ YDVAR(0, VAR_CACHEDB) } +#line 489 "./util/configlexer.lex" +{ YDVAR(1, VAR_IPSECMOD_ENABLED) } YY_BREAK case 272: YY_RULE_SETUP -#line 488 "./util/configlexer.lex" -{ YDVAR(1, VAR_CACHEDB_BACKEND) } +#line 490 "./util/configlexer.lex" +{ YDVAR(1, VAR_IPSECMOD_IGNORE_BOGUS) } YY_BREAK case 273: YY_RULE_SETUP -#line 489 "./util/configlexer.lex" -{ YDVAR(1, VAR_CACHEDB_SECRETSEED) } +#line 491 "./util/configlexer.lex" +{ YDVAR(1, VAR_IPSECMOD_HOOK) } YY_BREAK case 274: YY_RULE_SETUP -#line 490 "./util/configlexer.lex" -{ YDVAR(1, VAR_CACHEDB_REDISHOST) } +#line 492 "./util/configlexer.lex" +{ YDVAR(1, VAR_IPSECMOD_MAX_TTL) } YY_BREAK case 275: YY_RULE_SETUP -#line 491 "./util/configlexer.lex" -{ YDVAR(1, VAR_CACHEDB_REDISPORT) } +#line 493 "./util/configlexer.lex" +{ YDVAR(1, VAR_IPSECMOD_WHITELIST) } YY_BREAK case 276: YY_RULE_SETUP -#line 492 "./util/configlexer.lex" -{ YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) } +#line 494 "./util/configlexer.lex" +{ YDVAR(1, VAR_IPSECMOD_STRICT) } YY_BREAK case 277: YY_RULE_SETUP -#line 493 "./util/configlexer.lex" -{ YDVAR(0, VAR_IPSET) } +#line 495 "./util/configlexer.lex" +{ YDVAR(0, VAR_CACHEDB) } YY_BREAK case 278: YY_RULE_SETUP -#line 494 "./util/configlexer.lex" -{ YDVAR(1, VAR_IPSET_NAME_V4) } +#line 496 "./util/configlexer.lex" +{ YDVAR(1, VAR_CACHEDB_BACKEND) } YY_BREAK case 279: YY_RULE_SETUP -#line 495 "./util/configlexer.lex" -{ YDVAR(1, VAR_IPSET_NAME_V6) } +#line 497 "./util/configlexer.lex" +{ YDVAR(1, VAR_CACHEDB_SECRETSEED) } YY_BREAK case 280: YY_RULE_SETUP -#line 496 "./util/configlexer.lex" -{ YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM) } +#line 498 "./util/configlexer.lex" +{ YDVAR(1, VAR_CACHEDB_REDISHOST) } YY_BREAK case 281: YY_RULE_SETUP -#line 497 "./util/configlexer.lex" -{ YDVAR(2, VAR_TCP_CONNECTION_LIMIT) } +#line 499 "./util/configlexer.lex" +{ YDVAR(1, VAR_CACHEDB_REDISPORT) } YY_BREAK case 282: -/* rule 282 can match eol */ YY_RULE_SETUP -#line 498 "./util/configlexer.lex" -{ LEXOUT(("NL\n")); cfg_parser->line++; } +#line 500 "./util/configlexer.lex" +{ YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) } YY_BREAK -/* Quoted strings. Strip leading and ending quotes */ case 283: YY_RULE_SETUP #line 501 "./util/configlexer.lex" +{ YDVAR(0, VAR_IPSET) } + YY_BREAK +case 284: +YY_RULE_SETUP +#line 502 "./util/configlexer.lex" +{ YDVAR(1, VAR_IPSET_NAME_V4) } + YY_BREAK +case 285: +YY_RULE_SETUP +#line 503 "./util/configlexer.lex" +{ YDVAR(1, VAR_IPSET_NAME_V6) } + YY_BREAK +case 286: +YY_RULE_SETUP +#line 504 "./util/configlexer.lex" +{ YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM) } + YY_BREAK +case 287: +YY_RULE_SETUP +#line 505 "./util/configlexer.lex" +{ YDVAR(2, VAR_TCP_CONNECTION_LIMIT) } + YY_BREAK +case 288: +/* rule 288 can match eol */ +YY_RULE_SETUP +#line 506 "./util/configlexer.lex" +{ LEXOUT(("NL\n")); cfg_parser->line++; } + YY_BREAK +/* Quoted strings. Strip leading and ending quotes */ +case 289: +YY_RULE_SETUP +#line 509 "./util/configlexer.lex" { BEGIN(quotedstring); LEXOUT(("QS ")); } YY_BREAK case YY_STATE_EOF(quotedstring): -#line 502 "./util/configlexer.lex" +#line 510 "./util/configlexer.lex" { yyerror("EOF inside quoted string"); if(--num_args == 0) { BEGIN(INITIAL); } else { BEGIN(val); } } YY_BREAK -case 284: +case 290: YY_RULE_SETUP -#line 507 "./util/configlexer.lex" +#line 515 "./util/configlexer.lex" { LEXOUT(("STR(%s) ", yytext)); yymore(); } YY_BREAK -case 285: -/* rule 285 can match eol */ +case 291: +/* rule 291 can match eol */ YY_RULE_SETUP -#line 508 "./util/configlexer.lex" +#line 516 "./util/configlexer.lex" { yyerror("newline inside quoted string, no end \""); cfg_parser->line++; BEGIN(INITIAL); } YY_BREAK -case 286: +case 292: YY_RULE_SETUP -#line 510 "./util/configlexer.lex" +#line 518 "./util/configlexer.lex" { LEXOUT(("QE ")); if(--num_args == 0) { BEGIN(INITIAL); } @@ -4655,34 +4728,34 @@ YY_RULE_SETUP } YY_BREAK /* Single Quoted strings. Strip leading and ending quotes */ -case 287: +case 293: YY_RULE_SETUP -#line 522 "./util/configlexer.lex" +#line 530 "./util/configlexer.lex" { BEGIN(singlequotedstr); LEXOUT(("SQS ")); } YY_BREAK case YY_STATE_EOF(singlequotedstr): -#line 523 "./util/configlexer.lex" +#line 531 "./util/configlexer.lex" { yyerror("EOF inside quoted string"); if(--num_args == 0) { BEGIN(INITIAL); } else { BEGIN(val); } } YY_BREAK -case 288: +case 294: YY_RULE_SETUP -#line 528 "./util/configlexer.lex" +#line 536 "./util/configlexer.lex" { LEXOUT(("STR(%s) ", yytext)); yymore(); } YY_BREAK -case 289: -/* rule 289 can match eol */ +case 295: +/* rule 295 can match eol */ YY_RULE_SETUP -#line 529 "./util/configlexer.lex" +#line 537 "./util/configlexer.lex" { yyerror("newline inside quoted string, no end '"); cfg_parser->line++; BEGIN(INITIAL); } YY_BREAK -case 290: +case 296: YY_RULE_SETUP -#line 531 "./util/configlexer.lex" +#line 539 "./util/configlexer.lex" { LEXOUT(("SQE ")); if(--num_args == 0) { BEGIN(INITIAL); } @@ -4695,38 +4768,38 @@ YY_RULE_SETUP } YY_BREAK /* include: directive */ -case 291: +case 297: YY_RULE_SETUP -#line 543 "./util/configlexer.lex" +#line 551 "./util/configlexer.lex" { LEXOUT(("v(%s) ", yytext)); inc_prev = YYSTATE; BEGIN(include); } YY_BREAK case YY_STATE_EOF(include): -#line 545 "./util/configlexer.lex" +#line 553 "./util/configlexer.lex" { yyerror("EOF inside include directive"); BEGIN(inc_prev); } YY_BREAK -case 292: +case 298: YY_RULE_SETUP -#line 549 "./util/configlexer.lex" +#line 557 "./util/configlexer.lex" { LEXOUT(("ISP ")); /* ignore */ } YY_BREAK -case 293: -/* rule 293 can match eol */ +case 299: +/* rule 299 can match eol */ YY_RULE_SETUP -#line 550 "./util/configlexer.lex" +#line 558 "./util/configlexer.lex" { LEXOUT(("NL\n")); cfg_parser->line++;} YY_BREAK -case 294: +case 300: YY_RULE_SETUP -#line 551 "./util/configlexer.lex" +#line 559 "./util/configlexer.lex" { LEXOUT(("IQS ")); BEGIN(include_quoted); } YY_BREAK -case 295: +case 301: YY_RULE_SETUP -#line 552 "./util/configlexer.lex" +#line 560 "./util/configlexer.lex" { LEXOUT(("Iunquotedstr(%s) ", yytext)); config_start_include_glob(yytext); @@ -4734,27 +4807,27 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(include_quoted): -#line 557 "./util/configlexer.lex" +#line 565 "./util/configlexer.lex" { yyerror("EOF inside quoted string"); BEGIN(inc_prev); } YY_BREAK -case 296: +case 302: YY_RULE_SETUP -#line 561 "./util/configlexer.lex" +#line 569 "./util/configlexer.lex" { LEXOUT(("ISTR(%s) ", yytext)); yymore(); } YY_BREAK -case 297: -/* rule 297 can match eol */ +case 303: +/* rule 303 can match eol */ YY_RULE_SETUP -#line 562 "./util/configlexer.lex" +#line 570 "./util/configlexer.lex" { yyerror("newline before \" in include name"); cfg_parser->line++; BEGIN(inc_prev); } YY_BREAK -case 298: +case 304: YY_RULE_SETUP -#line 564 "./util/configlexer.lex" +#line 572 "./util/configlexer.lex" { LEXOUT(("IQE ")); yytext[yyleng - 1] = '\0'; @@ -4764,7 +4837,7 @@ YY_RULE_SETUP YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(val): -#line 570 "./util/configlexer.lex" +#line 578 "./util/configlexer.lex" { LEXOUT(("LEXEOF ")); yy_set_bol(1); /* Set beginning of line, so "^" rules match. */ @@ -4776,33 +4849,33 @@ case YY_STATE_EOF(val): } } YY_BREAK -case 299: +case 305: YY_RULE_SETUP -#line 581 "./util/configlexer.lex" +#line 589 "./util/configlexer.lex" { LEXOUT(("unquotedstr(%s) ", yytext)); if(--num_args == 0) { BEGIN(INITIAL); } yylval.str = strdup(yytext); return STRING_ARG; } YY_BREAK -case 300: +case 306: YY_RULE_SETUP -#line 585 "./util/configlexer.lex" +#line 593 "./util/configlexer.lex" { ub_c_error_msg("unknown keyword '%s'", yytext); } YY_BREAK -case 301: +case 307: YY_RULE_SETUP -#line 589 "./util/configlexer.lex" +#line 597 "./util/configlexer.lex" { ub_c_error_msg("stray '%s'", yytext); } YY_BREAK -case 302: +case 308: YY_RULE_SETUP -#line 593 "./util/configlexer.lex" +#line 601 "./util/configlexer.lex" ECHO; YY_BREAK -#line 4803 "" +#line 4876 "" case YY_END_OF_BUFFER: { @@ -5097,7 +5170,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 2986 ) + if ( yy_current_state >= 3042 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; @@ -5125,11 +5198,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 2986 ) + if ( yy_current_state >= 3042 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - yy_is_jam = (yy_current_state == 2985); + yy_is_jam = (yy_current_state == 3041); return yy_is_jam ? 0 : yy_current_state; } @@ -5768,6 +5841,6 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 593 "./util/configlexer.lex" +#line 601 "./util/configlexer.lex" diff --git a/util/configlexer.lex b/util/configlexer.lex index deedffa58..8832ab7a0 100644 --- a/util/configlexer.lex +++ b/util/configlexer.lex @@ -430,6 +430,14 @@ local-zone-override{COLON} { YDVAR(3, VAR_LOCAL_ZONE_OVERRIDE) } dnstap{COLON} { YDVAR(0, VAR_DNSTAP) } dnstap-enable{COLON} { YDVAR(1, VAR_DNSTAP_ENABLE) } dnstap-socket-path{COLON} { YDVAR(1, VAR_DNSTAP_SOCKET_PATH) } +dnstap-ip{COLON} { YDVAR(1, VAR_DNSTAP_IP) } +dnstap-tls{COLON} { YDVAR(1, VAR_DNSTAP_TLS) } +dnstap-tls-server-name{COLON} { YDVAR(1, VAR_DNSTAP_TLS_SERVER_NAME) } +dnstap-tls-cert-bundle{COLON} { YDVAR(1, VAR_DNSTAP_TLS_CERT_BUNDLE) } +dnstap-tls-client-key-file{COLON} { + YDVAR(1, VAR_DNSTAP_TLS_CLIENT_KEY_FILE) } +dnstap-tls-client-cert-file{COLON} { + YDVAR(1, VAR_DNSTAP_TLS_CLIENT_CERT_FILE) } dnstap-send-identity{COLON} { YDVAR(1, VAR_DNSTAP_SEND_IDENTITY) } dnstap-send-version{COLON} { YDVAR(1, VAR_DNSTAP_SEND_VERSION) } dnstap-identity{COLON} { YDVAR(1, VAR_DNSTAP_IDENTITY) } diff --git a/util/configparser.c b/util/configparser.c index 69ee1cc1c..d02cc6dfc 100644 --- a/util/configparser.c +++ b/util/configparser.c @@ -285,130 +285,136 @@ extern int yydebug; VAR_DNSTAP = 406, VAR_DNSTAP_ENABLE = 407, VAR_DNSTAP_SOCKET_PATH = 408, - VAR_DNSTAP_SEND_IDENTITY = 409, - VAR_DNSTAP_SEND_VERSION = 410, - VAR_DNSTAP_IDENTITY = 411, - VAR_DNSTAP_VERSION = 412, - VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES = 413, - VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES = 414, - VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES = 415, - VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES = 416, - VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES = 417, - VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES = 418, - VAR_RESPONSE_IP_TAG = 419, - VAR_RESPONSE_IP = 420, - VAR_RESPONSE_IP_DATA = 421, - VAR_HARDEN_ALGO_DOWNGRADE = 422, - VAR_IP_TRANSPARENT = 423, - VAR_DISABLE_DNSSEC_LAME_CHECK = 424, - VAR_IP_RATELIMIT = 425, - VAR_IP_RATELIMIT_SLABS = 426, - VAR_IP_RATELIMIT_SIZE = 427, - VAR_RATELIMIT = 428, - VAR_RATELIMIT_SLABS = 429, - VAR_RATELIMIT_SIZE = 430, - VAR_RATELIMIT_FOR_DOMAIN = 431, - VAR_RATELIMIT_BELOW_DOMAIN = 432, - VAR_IP_RATELIMIT_FACTOR = 433, - VAR_RATELIMIT_FACTOR = 434, - VAR_SEND_CLIENT_SUBNET = 435, - VAR_CLIENT_SUBNET_ZONE = 436, - VAR_CLIENT_SUBNET_ALWAYS_FORWARD = 437, - VAR_CLIENT_SUBNET_OPCODE = 438, - VAR_MAX_CLIENT_SUBNET_IPV4 = 439, - VAR_MAX_CLIENT_SUBNET_IPV6 = 440, - VAR_MIN_CLIENT_SUBNET_IPV4 = 441, - VAR_MIN_CLIENT_SUBNET_IPV6 = 442, - VAR_MAX_ECS_TREE_SIZE_IPV4 = 443, - VAR_MAX_ECS_TREE_SIZE_IPV6 = 444, - VAR_CAPS_WHITELIST = 445, - VAR_CACHE_MAX_NEGATIVE_TTL = 446, - VAR_PERMIT_SMALL_HOLDDOWN = 447, - VAR_QNAME_MINIMISATION = 448, - VAR_QNAME_MINIMISATION_STRICT = 449, - VAR_IP_FREEBIND = 450, - VAR_DEFINE_TAG = 451, - VAR_LOCAL_ZONE_TAG = 452, - VAR_ACCESS_CONTROL_TAG = 453, - VAR_LOCAL_ZONE_OVERRIDE = 454, - VAR_ACCESS_CONTROL_TAG_ACTION = 455, - VAR_ACCESS_CONTROL_TAG_DATA = 456, - VAR_VIEW = 457, - VAR_ACCESS_CONTROL_VIEW = 458, - VAR_VIEW_FIRST = 459, - VAR_SERVE_EXPIRED = 460, - VAR_SERVE_EXPIRED_TTL = 461, - VAR_SERVE_EXPIRED_TTL_RESET = 462, - VAR_SERVE_EXPIRED_REPLY_TTL = 463, - VAR_SERVE_EXPIRED_CLIENT_TIMEOUT = 464, - VAR_FAKE_DSA = 465, - VAR_FAKE_SHA1 = 466, - VAR_LOG_IDENTITY = 467, - VAR_HIDE_TRUSTANCHOR = 468, - VAR_TRUST_ANCHOR_SIGNALING = 469, - VAR_AGGRESSIVE_NSEC = 470, - VAR_USE_SYSTEMD = 471, - VAR_SHM_ENABLE = 472, - VAR_SHM_KEY = 473, - VAR_ROOT_KEY_SENTINEL = 474, - VAR_DNSCRYPT = 475, - VAR_DNSCRYPT_ENABLE = 476, - VAR_DNSCRYPT_PORT = 477, - VAR_DNSCRYPT_PROVIDER = 478, - VAR_DNSCRYPT_SECRET_KEY = 479, - VAR_DNSCRYPT_PROVIDER_CERT = 480, - VAR_DNSCRYPT_PROVIDER_CERT_ROTATED = 481, - VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE = 482, - VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS = 483, - VAR_DNSCRYPT_NONCE_CACHE_SIZE = 484, - VAR_DNSCRYPT_NONCE_CACHE_SLABS = 485, - VAR_IPSECMOD_ENABLED = 486, - VAR_IPSECMOD_HOOK = 487, - VAR_IPSECMOD_IGNORE_BOGUS = 488, - VAR_IPSECMOD_MAX_TTL = 489, - VAR_IPSECMOD_WHITELIST = 490, - VAR_IPSECMOD_STRICT = 491, - VAR_CACHEDB = 492, - VAR_CACHEDB_BACKEND = 493, - VAR_CACHEDB_SECRETSEED = 494, - VAR_CACHEDB_REDISHOST = 495, - VAR_CACHEDB_REDISPORT = 496, - VAR_CACHEDB_REDISTIMEOUT = 497, - VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 498, - VAR_FOR_UPSTREAM = 499, - VAR_AUTH_ZONE = 500, - VAR_ZONEFILE = 501, - VAR_MASTER = 502, - VAR_URL = 503, - VAR_FOR_DOWNSTREAM = 504, - VAR_FALLBACK_ENABLED = 505, - VAR_TLS_ADDITIONAL_PORT = 506, - VAR_LOW_RTT = 507, - VAR_LOW_RTT_PERMIL = 508, - VAR_FAST_SERVER_PERMIL = 509, - VAR_FAST_SERVER_NUM = 510, - VAR_ALLOW_NOTIFY = 511, - VAR_TLS_WIN_CERT = 512, - VAR_TCP_CONNECTION_LIMIT = 513, - VAR_FORWARD_NO_CACHE = 514, - VAR_STUB_NO_CACHE = 515, - VAR_LOG_SERVFAIL = 516, - VAR_DENY_ANY = 517, - VAR_UNKNOWN_SERVER_TIME_LIMIT = 518, - VAR_LOG_TAG_QUERYREPLY = 519, - VAR_STREAM_WAIT_SIZE = 520, - VAR_TLS_CIPHERS = 521, - VAR_TLS_CIPHERSUITES = 522, - VAR_IPSET = 523, - VAR_IPSET_NAME_V4 = 524, - VAR_IPSET_NAME_V6 = 525, - VAR_TLS_SESSION_TICKET_KEYS = 526, - VAR_RPZ = 527, - VAR_TAGS = 528, - VAR_RPZ_ACTION_OVERRIDE = 529, - VAR_RPZ_CNAME_OVERRIDE = 530, - VAR_RPZ_LOG = 531, - VAR_RPZ_LOG_NAME = 532 + VAR_DNSTAP_IP = 409, + VAR_DNSTAP_TLS = 410, + VAR_DNSTAP_TLS_SERVER_NAME = 411, + VAR_DNSTAP_TLS_CERT_BUNDLE = 412, + VAR_DNSTAP_TLS_CLIENT_KEY_FILE = 413, + VAR_DNSTAP_TLS_CLIENT_CERT_FILE = 414, + VAR_DNSTAP_SEND_IDENTITY = 415, + VAR_DNSTAP_SEND_VERSION = 416, + VAR_DNSTAP_IDENTITY = 417, + VAR_DNSTAP_VERSION = 418, + VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES = 419, + VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES = 420, + VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES = 421, + VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES = 422, + VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES = 423, + VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES = 424, + VAR_RESPONSE_IP_TAG = 425, + VAR_RESPONSE_IP = 426, + VAR_RESPONSE_IP_DATA = 427, + VAR_HARDEN_ALGO_DOWNGRADE = 428, + VAR_IP_TRANSPARENT = 429, + VAR_DISABLE_DNSSEC_LAME_CHECK = 430, + VAR_IP_RATELIMIT = 431, + VAR_IP_RATELIMIT_SLABS = 432, + VAR_IP_RATELIMIT_SIZE = 433, + VAR_RATELIMIT = 434, + VAR_RATELIMIT_SLABS = 435, + VAR_RATELIMIT_SIZE = 436, + VAR_RATELIMIT_FOR_DOMAIN = 437, + VAR_RATELIMIT_BELOW_DOMAIN = 438, + VAR_IP_RATELIMIT_FACTOR = 439, + VAR_RATELIMIT_FACTOR = 440, + VAR_SEND_CLIENT_SUBNET = 441, + VAR_CLIENT_SUBNET_ZONE = 442, + VAR_CLIENT_SUBNET_ALWAYS_FORWARD = 443, + VAR_CLIENT_SUBNET_OPCODE = 444, + VAR_MAX_CLIENT_SUBNET_IPV4 = 445, + VAR_MAX_CLIENT_SUBNET_IPV6 = 446, + VAR_MIN_CLIENT_SUBNET_IPV4 = 447, + VAR_MIN_CLIENT_SUBNET_IPV6 = 448, + VAR_MAX_ECS_TREE_SIZE_IPV4 = 449, + VAR_MAX_ECS_TREE_SIZE_IPV6 = 450, + VAR_CAPS_WHITELIST = 451, + VAR_CACHE_MAX_NEGATIVE_TTL = 452, + VAR_PERMIT_SMALL_HOLDDOWN = 453, + VAR_QNAME_MINIMISATION = 454, + VAR_QNAME_MINIMISATION_STRICT = 455, + VAR_IP_FREEBIND = 456, + VAR_DEFINE_TAG = 457, + VAR_LOCAL_ZONE_TAG = 458, + VAR_ACCESS_CONTROL_TAG = 459, + VAR_LOCAL_ZONE_OVERRIDE = 460, + VAR_ACCESS_CONTROL_TAG_ACTION = 461, + VAR_ACCESS_CONTROL_TAG_DATA = 462, + VAR_VIEW = 463, + VAR_ACCESS_CONTROL_VIEW = 464, + VAR_VIEW_FIRST = 465, + VAR_SERVE_EXPIRED = 466, + VAR_SERVE_EXPIRED_TTL = 467, + VAR_SERVE_EXPIRED_TTL_RESET = 468, + VAR_SERVE_EXPIRED_REPLY_TTL = 469, + VAR_SERVE_EXPIRED_CLIENT_TIMEOUT = 470, + VAR_FAKE_DSA = 471, + VAR_FAKE_SHA1 = 472, + VAR_LOG_IDENTITY = 473, + VAR_HIDE_TRUSTANCHOR = 474, + VAR_TRUST_ANCHOR_SIGNALING = 475, + VAR_AGGRESSIVE_NSEC = 476, + VAR_USE_SYSTEMD = 477, + VAR_SHM_ENABLE = 478, + VAR_SHM_KEY = 479, + VAR_ROOT_KEY_SENTINEL = 480, + VAR_DNSCRYPT = 481, + VAR_DNSCRYPT_ENABLE = 482, + VAR_DNSCRYPT_PORT = 483, + VAR_DNSCRYPT_PROVIDER = 484, + VAR_DNSCRYPT_SECRET_KEY = 485, + VAR_DNSCRYPT_PROVIDER_CERT = 486, + VAR_DNSCRYPT_PROVIDER_CERT_ROTATED = 487, + VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE = 488, + VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS = 489, + VAR_DNSCRYPT_NONCE_CACHE_SIZE = 490, + VAR_DNSCRYPT_NONCE_CACHE_SLABS = 491, + VAR_IPSECMOD_ENABLED = 492, + VAR_IPSECMOD_HOOK = 493, + VAR_IPSECMOD_IGNORE_BOGUS = 494, + VAR_IPSECMOD_MAX_TTL = 495, + VAR_IPSECMOD_WHITELIST = 496, + VAR_IPSECMOD_STRICT = 497, + VAR_CACHEDB = 498, + VAR_CACHEDB_BACKEND = 499, + VAR_CACHEDB_SECRETSEED = 500, + VAR_CACHEDB_REDISHOST = 501, + VAR_CACHEDB_REDISPORT = 502, + VAR_CACHEDB_REDISTIMEOUT = 503, + VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 504, + VAR_FOR_UPSTREAM = 505, + VAR_AUTH_ZONE = 506, + VAR_ZONEFILE = 507, + VAR_MASTER = 508, + VAR_URL = 509, + VAR_FOR_DOWNSTREAM = 510, + VAR_FALLBACK_ENABLED = 511, + VAR_TLS_ADDITIONAL_PORT = 512, + VAR_LOW_RTT = 513, + VAR_LOW_RTT_PERMIL = 514, + VAR_FAST_SERVER_PERMIL = 515, + VAR_FAST_SERVER_NUM = 516, + VAR_ALLOW_NOTIFY = 517, + VAR_TLS_WIN_CERT = 518, + VAR_TCP_CONNECTION_LIMIT = 519, + VAR_FORWARD_NO_CACHE = 520, + VAR_STUB_NO_CACHE = 521, + VAR_LOG_SERVFAIL = 522, + VAR_DENY_ANY = 523, + VAR_UNKNOWN_SERVER_TIME_LIMIT = 524, + VAR_LOG_TAG_QUERYREPLY = 525, + VAR_STREAM_WAIT_SIZE = 526, + VAR_TLS_CIPHERS = 527, + VAR_TLS_CIPHERSUITES = 528, + VAR_IPSET = 529, + VAR_IPSET_NAME_V4 = 530, + VAR_IPSET_NAME_V6 = 531, + VAR_TLS_SESSION_TICKET_KEYS = 532, + VAR_RPZ = 533, + VAR_TAGS = 534, + VAR_RPZ_ACTION_OVERRIDE = 535, + VAR_RPZ_CNAME_OVERRIDE = 536, + VAR_RPZ_LOG = 537, + VAR_RPZ_LOG_NAME = 538 }; #endif /* Tokens. */ @@ -563,130 +569,136 @@ extern int yydebug; #define VAR_DNSTAP 406 #define VAR_DNSTAP_ENABLE 407 #define VAR_DNSTAP_SOCKET_PATH 408 -#define VAR_DNSTAP_SEND_IDENTITY 409 -#define VAR_DNSTAP_SEND_VERSION 410 -#define VAR_DNSTAP_IDENTITY 411 -#define VAR_DNSTAP_VERSION 412 -#define VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES 413 -#define VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES 414 -#define VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES 415 -#define VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES 416 -#define VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES 417 -#define VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES 418 -#define VAR_RESPONSE_IP_TAG 419 -#define VAR_RESPONSE_IP 420 -#define VAR_RESPONSE_IP_DATA 421 -#define VAR_HARDEN_ALGO_DOWNGRADE 422 -#define VAR_IP_TRANSPARENT 423 -#define VAR_DISABLE_DNSSEC_LAME_CHECK 424 -#define VAR_IP_RATELIMIT 425 -#define VAR_IP_RATELIMIT_SLABS 426 -#define VAR_IP_RATELIMIT_SIZE 427 -#define VAR_RATELIMIT 428 -#define VAR_RATELIMIT_SLABS 429 -#define VAR_RATELIMIT_SIZE 430 -#define VAR_RATELIMIT_FOR_DOMAIN 431 -#define VAR_RATELIMIT_BELOW_DOMAIN 432 -#define VAR_IP_RATELIMIT_FACTOR 433 -#define VAR_RATELIMIT_FACTOR 434 -#define VAR_SEND_CLIENT_SUBNET 435 -#define VAR_CLIENT_SUBNET_ZONE 436 -#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 437 -#define VAR_CLIENT_SUBNET_OPCODE 438 -#define VAR_MAX_CLIENT_SUBNET_IPV4 439 -#define VAR_MAX_CLIENT_SUBNET_IPV6 440 -#define VAR_MIN_CLIENT_SUBNET_IPV4 441 -#define VAR_MIN_CLIENT_SUBNET_IPV6 442 -#define VAR_MAX_ECS_TREE_SIZE_IPV4 443 -#define VAR_MAX_ECS_TREE_SIZE_IPV6 444 -#define VAR_CAPS_WHITELIST 445 -#define VAR_CACHE_MAX_NEGATIVE_TTL 446 -#define VAR_PERMIT_SMALL_HOLDDOWN 447 -#define VAR_QNAME_MINIMISATION 448 -#define VAR_QNAME_MINIMISATION_STRICT 449 -#define VAR_IP_FREEBIND 450 -#define VAR_DEFINE_TAG 451 -#define VAR_LOCAL_ZONE_TAG 452 -#define VAR_ACCESS_CONTROL_TAG 453 -#define VAR_LOCAL_ZONE_OVERRIDE 454 -#define VAR_ACCESS_CONTROL_TAG_ACTION 455 -#define VAR_ACCESS_CONTROL_TAG_DATA 456 -#define VAR_VIEW 457 -#define VAR_ACCESS_CONTROL_VIEW 458 -#define VAR_VIEW_FIRST 459 -#define VAR_SERVE_EXPIRED 460 -#define VAR_SERVE_EXPIRED_TTL 461 -#define VAR_SERVE_EXPIRED_TTL_RESET 462 -#define VAR_SERVE_EXPIRED_REPLY_TTL 463 -#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 464 -#define VAR_FAKE_DSA 465 -#define VAR_FAKE_SHA1 466 -#define VAR_LOG_IDENTITY 467 -#define VAR_HIDE_TRUSTANCHOR 468 -#define VAR_TRUST_ANCHOR_SIGNALING 469 -#define VAR_AGGRESSIVE_NSEC 470 -#define VAR_USE_SYSTEMD 471 -#define VAR_SHM_ENABLE 472 -#define VAR_SHM_KEY 473 -#define VAR_ROOT_KEY_SENTINEL 474 -#define VAR_DNSCRYPT 475 -#define VAR_DNSCRYPT_ENABLE 476 -#define VAR_DNSCRYPT_PORT 477 -#define VAR_DNSCRYPT_PROVIDER 478 -#define VAR_DNSCRYPT_SECRET_KEY 479 -#define VAR_DNSCRYPT_PROVIDER_CERT 480 -#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 481 -#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 482 -#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 483 -#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 484 -#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 485 -#define VAR_IPSECMOD_ENABLED 486 -#define VAR_IPSECMOD_HOOK 487 -#define VAR_IPSECMOD_IGNORE_BOGUS 488 -#define VAR_IPSECMOD_MAX_TTL 489 -#define VAR_IPSECMOD_WHITELIST 490 -#define VAR_IPSECMOD_STRICT 491 -#define VAR_CACHEDB 492 -#define VAR_CACHEDB_BACKEND 493 -#define VAR_CACHEDB_SECRETSEED 494 -#define VAR_CACHEDB_REDISHOST 495 -#define VAR_CACHEDB_REDISPORT 496 -#define VAR_CACHEDB_REDISTIMEOUT 497 -#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 498 -#define VAR_FOR_UPSTREAM 499 -#define VAR_AUTH_ZONE 500 -#define VAR_ZONEFILE 501 -#define VAR_MASTER 502 -#define VAR_URL 503 -#define VAR_FOR_DOWNSTREAM 504 -#define VAR_FALLBACK_ENABLED 505 -#define VAR_TLS_ADDITIONAL_PORT 506 -#define VAR_LOW_RTT 507 -#define VAR_LOW_RTT_PERMIL 508 -#define VAR_FAST_SERVER_PERMIL 509 -#define VAR_FAST_SERVER_NUM 510 -#define VAR_ALLOW_NOTIFY 511 -#define VAR_TLS_WIN_CERT 512 -#define VAR_TCP_CONNECTION_LIMIT 513 -#define VAR_FORWARD_NO_CACHE 514 -#define VAR_STUB_NO_CACHE 515 -#define VAR_LOG_SERVFAIL 516 -#define VAR_DENY_ANY 517 -#define VAR_UNKNOWN_SERVER_TIME_LIMIT 518 -#define VAR_LOG_TAG_QUERYREPLY 519 -#define VAR_STREAM_WAIT_SIZE 520 -#define VAR_TLS_CIPHERS 521 -#define VAR_TLS_CIPHERSUITES 522 -#define VAR_IPSET 523 -#define VAR_IPSET_NAME_V4 524 -#define VAR_IPSET_NAME_V6 525 -#define VAR_TLS_SESSION_TICKET_KEYS 526 -#define VAR_RPZ 527 -#define VAR_TAGS 528 -#define VAR_RPZ_ACTION_OVERRIDE 529 -#define VAR_RPZ_CNAME_OVERRIDE 530 -#define VAR_RPZ_LOG 531 -#define VAR_RPZ_LOG_NAME 532 +#define VAR_DNSTAP_IP 409 +#define VAR_DNSTAP_TLS 410 +#define VAR_DNSTAP_TLS_SERVER_NAME 411 +#define VAR_DNSTAP_TLS_CERT_BUNDLE 412 +#define VAR_DNSTAP_TLS_CLIENT_KEY_FILE 413 +#define VAR_DNSTAP_TLS_CLIENT_CERT_FILE 414 +#define VAR_DNSTAP_SEND_IDENTITY 415 +#define VAR_DNSTAP_SEND_VERSION 416 +#define VAR_DNSTAP_IDENTITY 417 +#define VAR_DNSTAP_VERSION 418 +#define VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES 419 +#define VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES 420 +#define VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES 421 +#define VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES 422 +#define VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES 423 +#define VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES 424 +#define VAR_RESPONSE_IP_TAG 425 +#define VAR_RESPONSE_IP 426 +#define VAR_RESPONSE_IP_DATA 427 +#define VAR_HARDEN_ALGO_DOWNGRADE 428 +#define VAR_IP_TRANSPARENT 429 +#define VAR_DISABLE_DNSSEC_LAME_CHECK 430 +#define VAR_IP_RATELIMIT 431 +#define VAR_IP_RATELIMIT_SLABS 432 +#define VAR_IP_RATELIMIT_SIZE 433 +#define VAR_RATELIMIT 434 +#define VAR_RATELIMIT_SLABS 435 +#define VAR_RATELIMIT_SIZE 436 +#define VAR_RATELIMIT_FOR_DOMAIN 437 +#define VAR_RATELIMIT_BELOW_DOMAIN 438 +#define VAR_IP_RATELIMIT_FACTOR 439 +#define VAR_RATELIMIT_FACTOR 440 +#define VAR_SEND_CLIENT_SUBNET 441 +#define VAR_CLIENT_SUBNET_ZONE 442 +#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 443 +#define VAR_CLIENT_SUBNET_OPCODE 444 +#define VAR_MAX_CLIENT_SUBNET_IPV4 445 +#define VAR_MAX_CLIENT_SUBNET_IPV6 446 +#define VAR_MIN_CLIENT_SUBNET_IPV4 447 +#define VAR_MIN_CLIENT_SUBNET_IPV6 448 +#define VAR_MAX_ECS_TREE_SIZE_IPV4 449 +#define VAR_MAX_ECS_TREE_SIZE_IPV6 450 +#define VAR_CAPS_WHITELIST 451 +#define VAR_CACHE_MAX_NEGATIVE_TTL 452 +#define VAR_PERMIT_SMALL_HOLDDOWN 453 +#define VAR_QNAME_MINIMISATION 454 +#define VAR_QNAME_MINIMISATION_STRICT 455 +#define VAR_IP_FREEBIND 456 +#define VAR_DEFINE_TAG 457 +#define VAR_LOCAL_ZONE_TAG 458 +#define VAR_ACCESS_CONTROL_TAG 459 +#define VAR_LOCAL_ZONE_OVERRIDE 460 +#define VAR_ACCESS_CONTROL_TAG_ACTION 461 +#define VAR_ACCESS_CONTROL_TAG_DATA 462 +#define VAR_VIEW 463 +#define VAR_ACCESS_CONTROL_VIEW 464 +#define VAR_VIEW_FIRST 465 +#define VAR_SERVE_EXPIRED 466 +#define VAR_SERVE_EXPIRED_TTL 467 +#define VAR_SERVE_EXPIRED_TTL_RESET 468 +#define VAR_SERVE_EXPIRED_REPLY_TTL 469 +#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 470 +#define VAR_FAKE_DSA 471 +#define VAR_FAKE_SHA1 472 +#define VAR_LOG_IDENTITY 473 +#define VAR_HIDE_TRUSTANCHOR 474 +#define VAR_TRUST_ANCHOR_SIGNALING 475 +#define VAR_AGGRESSIVE_NSEC 476 +#define VAR_USE_SYSTEMD 477 +#define VAR_SHM_ENABLE 478 +#define VAR_SHM_KEY 479 +#define VAR_ROOT_KEY_SENTINEL 480 +#define VAR_DNSCRYPT 481 +#define VAR_DNSCRYPT_ENABLE 482 +#define VAR_DNSCRYPT_PORT 483 +#define VAR_DNSCRYPT_PROVIDER 484 +#define VAR_DNSCRYPT_SECRET_KEY 485 +#define VAR_DNSCRYPT_PROVIDER_CERT 486 +#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 487 +#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 488 +#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 489 +#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 490 +#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 491 +#define VAR_IPSECMOD_ENABLED 492 +#define VAR_IPSECMOD_HOOK 493 +#define VAR_IPSECMOD_IGNORE_BOGUS 494 +#define VAR_IPSECMOD_MAX_TTL 495 +#define VAR_IPSECMOD_WHITELIST 496 +#define VAR_IPSECMOD_STRICT 497 +#define VAR_CACHEDB 498 +#define VAR_CACHEDB_BACKEND 499 +#define VAR_CACHEDB_SECRETSEED 500 +#define VAR_CACHEDB_REDISHOST 501 +#define VAR_CACHEDB_REDISPORT 502 +#define VAR_CACHEDB_REDISTIMEOUT 503 +#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 504 +#define VAR_FOR_UPSTREAM 505 +#define VAR_AUTH_ZONE 506 +#define VAR_ZONEFILE 507 +#define VAR_MASTER 508 +#define VAR_URL 509 +#define VAR_FOR_DOWNSTREAM 510 +#define VAR_FALLBACK_ENABLED 511 +#define VAR_TLS_ADDITIONAL_PORT 512 +#define VAR_LOW_RTT 513 +#define VAR_LOW_RTT_PERMIL 514 +#define VAR_FAST_SERVER_PERMIL 515 +#define VAR_FAST_SERVER_NUM 516 +#define VAR_ALLOW_NOTIFY 517 +#define VAR_TLS_WIN_CERT 518 +#define VAR_TCP_CONNECTION_LIMIT 519 +#define VAR_FORWARD_NO_CACHE 520 +#define VAR_STUB_NO_CACHE 521 +#define VAR_LOG_SERVFAIL 522 +#define VAR_DENY_ANY 523 +#define VAR_UNKNOWN_SERVER_TIME_LIMIT 524 +#define VAR_LOG_TAG_QUERYREPLY 525 +#define VAR_STREAM_WAIT_SIZE 526 +#define VAR_TLS_CIPHERS 527 +#define VAR_TLS_CIPHERSUITES 528 +#define VAR_IPSET 529 +#define VAR_IPSET_NAME_V4 530 +#define VAR_IPSET_NAME_V6 531 +#define VAR_TLS_SESSION_TICKET_KEYS 532 +#define VAR_RPZ 533 +#define VAR_TAGS 534 +#define VAR_RPZ_ACTION_OVERRIDE 535 +#define VAR_RPZ_CNAME_OVERRIDE 536 +#define VAR_RPZ_LOG 537 +#define VAR_RPZ_LOG_NAME 538 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED @@ -696,7 +708,7 @@ union YYSTYPE char* str; -#line 700 "util/configparser.c" +#line 712 "util/configparser.c" }; typedef union YYSTYPE YYSTYPE; @@ -946,19 +958,19 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 2 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 590 +#define YYLAST 602 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 278 +#define YYNTOKENS 284 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 301 +#define YYNNTS 307 /* YYNRULES -- Number of rules. */ -#define YYNRULES 580 +#define YYNRULES 592 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 863 +#define YYNSTATES 881 #define YYUNDEFTOK 2 -#define YYMAXUTOK 532 +#define YYMAXUTOK 538 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM as returned by yylex, with out-of-bounds checking. */ @@ -1022,72 +1034,73 @@ static const yytype_uint16 yytranslate[] = 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277 + 275, 276, 277, 278, 279, 280, 281, 282, 283 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 175, 175, 175, 176, 176, 177, 177, 178, 178, - 178, 179, 179, 180, 180, 181, 185, 190, 191, 192, - 192, 192, 193, 193, 194, 194, 195, 195, 196, 196, - 196, 197, 197, 198, 198, 198, 199, 199, 199, 200, - 200, 201, 201, 202, 202, 203, 203, 204, 204, 205, - 205, 206, 206, 207, 207, 208, 208, 208, 209, 209, - 209, 210, 210, 210, 211, 211, 212, 212, 213, 213, - 214, 214, 215, 215, 215, 216, 216, 217, 217, 218, - 218, 218, 219, 219, 220, 220, 221, 221, 222, 222, - 222, 223, 223, 224, 224, 225, 225, 226, 226, 227, - 227, 228, 228, 228, 229, 229, 230, 230, 230, 231, - 231, 231, 232, 232, 232, 233, 233, 233, 233, 234, - 235, 235, 235, 236, 236, 236, 237, 237, 238, 238, - 239, 239, 239, 240, 240, 241, 241, 241, 242, 242, - 243, 243, 244, 245, 245, 246, 246, 247, 247, 248, - 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, - 254, 254, 254, 255, 255, 256, 256, 257, 257, 258, - 258, 259, 259, 260, 260, 261, 261, 261, 262, 262, - 262, 263, 263, 263, 264, 264, 265, 266, 266, 267, - 267, 268, 268, 269, 269, 270, 270, 270, 271, 271, - 271, 272, 272, 272, 273, 273, 274, 274, 275, 275, - 277, 289, 290, 291, 291, 291, 291, 291, 292, 292, - 294, 306, 307, 308, 308, 308, 308, 309, 309, 311, - 325, 326, 327, 327, 327, 327, 328, 328, 328, 330, - 347, 348, 349, 349, 349, 349, 350, 350, 350, 351, - 354, 373, 390, 398, 408, 416, 433, 434, 435, 435, - 435, 435, 435, 436, 436, 436, 437, 437, 439, 448, - 457, 468, 477, 486, 495, 506, 515, 527, 541, 556, - 567, 584, 601, 618, 635, 650, 665, 678, 693, 702, - 711, 720, 729, 738, 747, 756, 765, 774, 783, 792, - 801, 810, 823, 832, 845, 854, 863, 872, 879, 886, - 895, 902, 911, 919, 926, 933, 941, 950, 959, 973, - 982, 991, 1000, 1009, 1018, 1027, 1034, 1041, 1067, 1075, - 1082, 1089, 1096, 1103, 1111, 1119, 1127, 1134, 1145, 1156, - 1163, 1172, 1181, 1190, 1197, 1204, 1212, 1220, 1230, 1240, - 1250, 1258, 1271, 1282, 1290, 1303, 1312, 1321, 1330, 1340, - 1350, 1358, 1371, 1380, 1388, 1397, 1405, 1418, 1427, 1434, - 1444, 1454, 1464, 1474, 1484, 1494, 1504, 1514, 1521, 1528, - 1535, 1544, 1553, 1562, 1571, 1578, 1588, 1608, 1615, 1633, - 1646, 1659, 1668, 1677, 1686, 1695, 1705, 1715, 1726, 1735, - 1744, 1753, 1762, 1771, 1780, 1793, 1806, 1815, 1822, 1831, - 1840, 1849, 1858, 1866, 1879, 1887, 1928, 1935, 1950, 1960, - 1970, 1977, 1984, 1991, 2000, 2008, 2022, 2043, 2064, 2076, - 2088, 2100, 2109, 2130, 2140, 2149, 2157, 2165, 2178, 2191, - 2206, 2221, 2230, 2239, 2245, 2254, 2263, 2273, 2283, 2296, - 2309, 2321, 2335, 2347, 2361, 2371, 2378, 2385, 2394, 2403, - 2413, 2423, 2433, 2440, 2447, 2456, 2465, 2475, 2485, 2492, - 2499, 2506, 2514, 2524, 2534, 2544, 2554, 2593, 2603, 2611, - 2619, 2634, 2643, 2648, 2649, 2650, 2650, 2650, 2651, 2651, - 2651, 2652, 2652, 2654, 2664, 2673, 2680, 2687, 2694, 2701, - 2708, 2715, 2720, 2721, 2722, 2722, 2723, 2723, 2724, 2724, - 2725, 2726, 2727, 2728, 2729, 2730, 2732, 2741, 2748, 2757, - 2766, 2773, 2780, 2790, 2800, 2810, 2820, 2830, 2840, 2845, - 2846, 2847, 2849, 2855, 2865, 2872, 2881, 2889, 2894, 2895, - 2897, 2897, 2897, 2898, 2898, 2899, 2900, 2901, 2902, 2903, - 2905, 2915, 2924, 2931, 2940, 2947, 2956, 2964, 2977, 2985, - 2998, 3003, 3004, 3005, 3005, 3006, 3006, 3006, 3008, 3020, - 3032, 3044, 3059, 3072, 3083, 3088, 3089, 3090, 3090, 3092, - 3107 + 0, 177, 177, 177, 178, 178, 179, 179, 180, 180, + 180, 181, 181, 182, 182, 183, 187, 192, 193, 194, + 194, 194, 195, 195, 196, 196, 197, 197, 198, 198, + 198, 199, 199, 200, 200, 200, 201, 201, 201, 202, + 202, 203, 203, 204, 204, 205, 205, 206, 206, 207, + 207, 208, 208, 209, 209, 210, 210, 210, 211, 211, + 211, 212, 212, 212, 213, 213, 214, 214, 215, 215, + 216, 216, 217, 217, 217, 218, 218, 219, 219, 220, + 220, 220, 221, 221, 222, 222, 223, 223, 224, 224, + 224, 225, 225, 226, 226, 227, 227, 228, 228, 229, + 229, 230, 230, 230, 231, 231, 232, 232, 232, 233, + 233, 233, 234, 234, 234, 235, 235, 235, 235, 236, + 237, 237, 237, 238, 238, 238, 239, 239, 240, 240, + 241, 241, 241, 242, 242, 243, 243, 243, 244, 244, + 245, 245, 246, 247, 247, 248, 248, 249, 249, 250, + 251, 251, 252, 252, 253, 253, 254, 254, 255, 255, + 256, 256, 256, 257, 257, 258, 258, 259, 259, 260, + 260, 261, 261, 262, 262, 263, 263, 263, 264, 264, + 264, 265, 265, 265, 266, 266, 267, 268, 268, 269, + 269, 270, 270, 271, 271, 272, 272, 272, 273, 273, + 273, 274, 274, 274, 275, 275, 276, 276, 277, 277, + 279, 291, 292, 293, 293, 293, 293, 293, 294, 294, + 296, 308, 309, 310, 310, 310, 310, 311, 311, 313, + 327, 328, 329, 329, 329, 329, 330, 330, 330, 332, + 349, 350, 351, 351, 351, 351, 352, 352, 352, 353, + 356, 375, 392, 400, 410, 418, 435, 436, 437, 437, + 437, 437, 437, 438, 438, 438, 439, 439, 441, 450, + 459, 470, 479, 488, 497, 508, 517, 529, 543, 558, + 569, 586, 603, 620, 637, 652, 667, 680, 695, 704, + 713, 722, 731, 740, 749, 758, 767, 776, 785, 794, + 803, 812, 825, 834, 847, 856, 865, 874, 881, 888, + 897, 904, 913, 921, 928, 935, 943, 952, 961, 975, + 984, 993, 1002, 1011, 1020, 1029, 1036, 1043, 1069, 1077, + 1084, 1091, 1098, 1105, 1113, 1121, 1129, 1136, 1147, 1158, + 1165, 1174, 1183, 1192, 1199, 1206, 1214, 1222, 1232, 1242, + 1252, 1260, 1273, 1284, 1292, 1305, 1314, 1323, 1332, 1342, + 1352, 1360, 1373, 1382, 1390, 1399, 1407, 1420, 1429, 1436, + 1446, 1456, 1466, 1476, 1486, 1496, 1506, 1516, 1523, 1530, + 1537, 1546, 1555, 1564, 1573, 1580, 1590, 1610, 1617, 1635, + 1648, 1661, 1670, 1679, 1688, 1697, 1707, 1717, 1728, 1737, + 1746, 1755, 1764, 1773, 1782, 1795, 1808, 1817, 1824, 1833, + 1842, 1851, 1860, 1868, 1881, 1889, 1930, 1937, 1952, 1962, + 1972, 1979, 1986, 1993, 2002, 2010, 2024, 2045, 2066, 2078, + 2090, 2102, 2111, 2132, 2142, 2151, 2159, 2167, 2180, 2193, + 2208, 2223, 2232, 2241, 2247, 2256, 2265, 2275, 2285, 2298, + 2311, 2323, 2337, 2349, 2363, 2373, 2380, 2387, 2396, 2405, + 2415, 2425, 2435, 2442, 2449, 2458, 2467, 2477, 2487, 2494, + 2501, 2508, 2516, 2526, 2536, 2546, 2556, 2595, 2605, 2613, + 2621, 2636, 2645, 2650, 2651, 2652, 2652, 2652, 2653, 2653, + 2653, 2654, 2654, 2656, 2666, 2675, 2682, 2689, 2696, 2703, + 2710, 2717, 2722, 2723, 2724, 2724, 2725, 2725, 2725, 2726, + 2727, 2727, 2728, 2728, 2729, 2729, 2730, 2731, 2732, 2733, + 2734, 2735, 2737, 2746, 2753, 2760, 2769, 2776, 2783, 2790, + 2797, 2806, 2815, 2822, 2829, 2839, 2849, 2859, 2869, 2879, + 2889, 2894, 2895, 2896, 2898, 2904, 2914, 2921, 2930, 2938, + 2943, 2944, 2946, 2946, 2946, 2947, 2947, 2948, 2949, 2950, + 2951, 2952, 2954, 2964, 2973, 2980, 2989, 2996, 3005, 3013, + 3026, 3034, 3047, 3052, 3053, 3054, 3054, 3055, 3055, 3055, + 3057, 3069, 3081, 3093, 3108, 3121, 3132, 3137, 3138, 3139, + 3139, 3141, 3156 }; #endif @@ -1145,8 +1158,11 @@ static const char *const yytname[] = "VAR_DELAY_CLOSE", "VAR_UNBLOCK_LAN_ZONES", "VAR_INSECURE_LAN_ZONES", "VAR_INFRA_CACHE_MIN_RTT", "VAR_DNS64_PREFIX", "VAR_DNS64_SYNTHALL", "VAR_DNS64_IGNORE_AAAA", "VAR_DNSTAP", "VAR_DNSTAP_ENABLE", - "VAR_DNSTAP_SOCKET_PATH", "VAR_DNSTAP_SEND_IDENTITY", - "VAR_DNSTAP_SEND_VERSION", "VAR_DNSTAP_IDENTITY", "VAR_DNSTAP_VERSION", + "VAR_DNSTAP_SOCKET_PATH", "VAR_DNSTAP_IP", "VAR_DNSTAP_TLS", + "VAR_DNSTAP_TLS_SERVER_NAME", "VAR_DNSTAP_TLS_CERT_BUNDLE", + "VAR_DNSTAP_TLS_CLIENT_KEY_FILE", "VAR_DNSTAP_TLS_CLIENT_CERT_FILE", + "VAR_DNSTAP_SEND_IDENTITY", "VAR_DNSTAP_SEND_VERSION", + "VAR_DNSTAP_IDENTITY", "VAR_DNSTAP_VERSION", "VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES", "VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES", "VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES", @@ -1298,8 +1314,11 @@ static const char *const yytname[] = "rc_control_interface", "rc_control_use_cert", "rc_server_key_file", "rc_server_cert_file", "rc_control_key_file", "rc_control_cert_file", "dtstart", "contents_dt", "content_dt", "dt_dnstap_enable", - "dt_dnstap_socket_path", "dt_dnstap_send_identity", - "dt_dnstap_send_version", "dt_dnstap_identity", "dt_dnstap_version", + "dt_dnstap_socket_path", "dt_dnstap_ip", "dt_dnstap_tls", + "dt_dnstap_tls_server_name", "dt_dnstap_tls_cert_bundle", + "dt_dnstap_tls_client_key_file", "dt_dnstap_tls_client_cert_file", + "dt_dnstap_send_identity", "dt_dnstap_send_version", + "dt_dnstap_identity", "dt_dnstap_version", "dt_dnstap_log_resolver_query_messages", "dt_dnstap_log_resolver_response_messages", "dt_dnstap_log_client_query_messages", @@ -1355,14 +1374,15 @@ static const yytype_uint16 yytoknum[] = 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 529, 530, 531, 532 + 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, + 535, 536, 537, 538 }; # endif -#define YYPACT_NINF -262 +#define YYPACT_NINF -268 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-262))) + (!!((Yystate) == (-268))) #define YYTABLE_NINF -1 @@ -1373,93 +1393,95 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - -262, 0, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, 261, -41, - -36, -40, -20, -42, -29, -128, -105, -170, -221, -261, - 2, 3, 4, 12, 26, 27, 28, 31, 32, 33, - 35, 36, 37, 38, 39, 51, 52, 53, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 85, 87, - 88, 91, 93, 94, 95, 96, 97, 98, 99, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, 140, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 152, 153, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 193, 197, 198, 199, - 200, 201, 202, 203, 205, 206, 207, 208, 211, 212, - 215, 228, 229, 230, 231, 232, 233, 234, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 259, 260, 294, 295, 296, 297, 301, 302, 303, 345, - 346, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, 347, 348, 349, 350, 351, 352, 353, - -262, -262, -262, -262, -262, -262, -262, -262, 357, 361, - 362, 387, 388, 389, -262, -262, -262, -262, -262, -262, - -262, 391, 402, 403, 404, 405, 406, 407, -262, -262, - -262, -262, -262, -262, -262, -262, 408, 409, 410, 411, - 412, 413, 414, 453, -262, -262, -262, -262, -262, -262, - -262, -262, -262, 455, 471, 472, 473, 474, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, 475, - 476, 477, 478, 479, 480, 481, 488, -262, -262, -262, - -262, -262, -262, -262, -262, -262, 489, 490, 491, 492, - 493, 495, 496, 497, 498, 499, 500, 501, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, 504, -262, -262, 507, 510, 511, 519, 520, 521, - 523, 524, 525, 526, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, 527, 528, 529, 530, 531, - -262, -262, -262, -262, -262, -262, 532, 533, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - 534, 535, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, 536, 537, 538, - -262, -262, -262, -262, -262, -262, -262, -262, -262, 539, - 540, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - 541, 542, 543, 544, 545, 546, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, 547, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, 548, -262, -262, 549, - 550, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, 551, 552, 553, -262, -262, -262, -262, -262, - -262, -262, -262 + -268, 0, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, 267, -41, + -36, -40, -20, -42, -44, -86, -105, -203, -227, -267, + 2, 3, 4, 12, 24, 25, 26, 27, 28, 31, + 32, 33, 35, 36, 37, 38, 39, 49, 50, 51, + 52, 53, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 85, 87, 88, 91, 93, 94, 95, 96, + 97, 98, 99, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 199, 203, 204, 205, + 206, 207, 208, 209, 211, 212, 213, 214, 217, 218, + 221, 234, 235, 236, 237, 238, 239, 240, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 265, 266, 300, 301, 302, 303, 307, 308, 309, 351, + 352, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, 353, 354, 355, 356, 357, 358, 359, + -268, -268, -268, -268, -268, -268, -268, -268, 363, 367, + 368, 393, 394, 395, -268, -268, -268, -268, -268, -268, + -268, 397, 408, 409, 410, 411, 412, 413, -268, -268, + -268, -268, -268, -268, -268, -268, 414, 415, 416, 417, + 418, 419, 420, 421, -268, -268, -268, -268, -268, -268, + -268, -268, -268, 422, 423, 424, 425, 426, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, 465, + 467, 483, 484, 485, 486, 487, 488, -268, -268, -268, + -268, -268, -268, -268, -268, -268, 489, 490, 491, 492, + 493, 500, 501, 502, 503, 504, 505, 507, 508, 509, + 510, 511, 512, 513, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, 516, -268, -268, 519, 522, 523, 531, + 532, 533, 535, 536, 537, 538, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, 539, 540, 541, + 542, 543, -268, -268, -268, -268, -268, -268, 544, 545, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, 546, 547, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, 548, + 549, 550, -268, -268, -268, -268, -268, -268, -268, -268, + -268, 551, 552, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, 553, 554, 555, 556, 557, 558, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, 559, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, 560, -268, + -268, 561, 562, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + 563, 564, 565, -268, -268, -268, -268, -268, -268, -268, + -268 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -1467,9 +1489,9 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint16 yydefact[] = { - 2, 0, 1, 16, 210, 220, 482, 528, 501, 229, - 537, 560, 239, 574, 255, 3, 18, 212, 222, 231, - 241, 257, 484, 503, 530, 539, 562, 576, 4, 5, + 2, 0, 1, 16, 210, 220, 482, 540, 501, 229, + 549, 572, 239, 586, 255, 3, 18, 212, 222, 231, + 241, 257, 484, 503, 542, 551, 574, 588, 4, 5, 6, 10, 14, 15, 8, 9, 7, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1519,77 +1541,79 @@ static const yytype_uint16 yydefact[] = 265, 266, 267, 256, 258, 259, 261, 262, 263, 0, 0, 0, 0, 0, 0, 0, 0, 483, 485, 487, 486, 492, 488, 489, 490, 491, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 502, 504, - 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, - 515, 0, 529, 531, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 538, 540, 541, 542, 544, 545, - 543, 546, 547, 548, 549, 0, 0, 0, 0, 0, - 561, 563, 564, 565, 566, 567, 0, 0, 575, 577, - 578, 269, 268, 275, 288, 286, 294, 295, 298, 296, - 297, 299, 300, 301, 302, 303, 325, 326, 327, 328, - 329, 353, 354, 355, 360, 361, 291, 362, 363, 366, - 364, 365, 368, 369, 370, 384, 340, 341, 343, 344, - 371, 387, 334, 336, 388, 394, 395, 396, 292, 352, - 412, 413, 335, 407, 318, 287, 330, 385, 391, 372, - 0, 0, 416, 293, 270, 317, 376, 271, 289, 290, - 331, 332, 414, 374, 378, 379, 272, 417, 356, 383, - 319, 339, 389, 390, 393, 406, 333, 410, 408, 409, - 345, 351, 380, 381, 346, 347, 373, 398, 320, 321, - 324, 304, 306, 307, 308, 309, 310, 418, 419, 421, - 357, 358, 359, 367, 422, 423, 424, 0, 0, 0, - 375, 348, 533, 433, 437, 435, 434, 438, 436, 0, - 0, 441, 442, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 377, 392, 411, 446, 447, 349, 425, - 0, 0, 0, 0, 0, 0, 399, 400, 401, 402, - 403, 404, 405, 534, 342, 337, 397, 316, 273, 274, - 338, 448, 450, 449, 451, 452, 453, 305, 312, 443, - 445, 444, 311, 0, 323, 382, 420, 322, 350, 313, - 314, 315, 454, 455, 456, 460, 459, 457, 458, 461, - 462, 463, 464, 466, 465, 475, 0, 479, 480, 0, - 0, 481, 467, 473, 468, 469, 470, 472, 474, 471, - 250, 251, 252, 253, 254, 493, 495, 494, 497, 498, - 499, 500, 496, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 532, 550, 551, 552, 555, - 553, 554, 556, 557, 558, 559, 568, 569, 570, 571, - 572, 579, 580, 386, 415, 432, 535, 536, 439, 440, - 426, 427, 0, 0, 0, 431, 573, 476, 477, 478, - 430, 428, 429 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 502, 504, 505, 506, 507, 508, + 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, + 519, 520, 521, 0, 541, 543, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 550, 552, 553, 554, + 556, 557, 555, 558, 559, 560, 561, 0, 0, 0, + 0, 0, 573, 575, 576, 577, 578, 579, 0, 0, + 587, 589, 590, 269, 268, 275, 288, 286, 294, 295, + 298, 296, 297, 299, 300, 301, 302, 303, 325, 326, + 327, 328, 329, 353, 354, 355, 360, 361, 291, 362, + 363, 366, 364, 365, 368, 369, 370, 384, 340, 341, + 343, 344, 371, 387, 334, 336, 388, 394, 395, 396, + 292, 352, 412, 413, 335, 407, 318, 287, 330, 385, + 391, 372, 0, 0, 416, 293, 270, 317, 376, 271, + 289, 290, 331, 332, 414, 374, 378, 379, 272, 417, + 356, 383, 319, 339, 389, 390, 393, 406, 333, 410, + 408, 409, 345, 351, 380, 381, 346, 347, 373, 398, + 320, 321, 324, 304, 306, 307, 308, 309, 310, 418, + 419, 421, 357, 358, 359, 367, 422, 423, 424, 0, + 0, 0, 375, 348, 545, 433, 437, 435, 434, 438, + 436, 0, 0, 441, 442, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 377, 392, 411, 446, 447, + 349, 425, 0, 0, 0, 0, 0, 0, 399, 400, + 401, 402, 403, 404, 405, 546, 342, 337, 397, 316, + 273, 274, 338, 448, 450, 449, 451, 452, 453, 305, + 312, 443, 445, 444, 311, 0, 323, 382, 420, 322, + 350, 313, 314, 315, 454, 455, 456, 460, 459, 457, + 458, 461, 462, 463, 464, 466, 465, 475, 0, 479, + 480, 0, 0, 481, 467, 473, 468, 469, 470, 472, + 474, 471, 250, 251, 252, 253, 254, 493, 495, 494, + 497, 498, 499, 500, 496, 522, 523, 524, 525, 526, + 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, + 537, 538, 539, 544, 562, 563, 564, 567, 565, 566, + 568, 569, 570, 571, 580, 581, 582, 583, 584, 591, + 592, 386, 415, 432, 547, 548, 439, 440, 426, 427, + 0, 0, 0, 431, 585, 476, 477, 478, 430, 428, + 429 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -23, 554, 555, 556, 557, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262, -262, -262, -262, -262, -262, -262, -262, -262, -262, - -262 + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -23, 566, 567, 568, 569, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268, -268, -268, -268, + -268, -268, -268, -268, -268, -268, -268 }; /* YYDEFGOTO[NTERM-NUM]. */ @@ -1620,12 +1644,12 @@ static const yytype_int16 yydefgoto[] = 446, 447, 448, 449, 450, 475, 476, 477, 478, 479, 480, 481, 482, 459, 460, 461, 462, 463, 464, 465, 22, 34, 507, 508, 509, 510, 511, 512, 513, 514, - 515, 23, 35, 528, 529, 530, 531, 532, 533, 534, - 535, 536, 537, 538, 539, 540, 24, 36, 542, 543, - 418, 419, 420, 421, 25, 37, 554, 555, 556, 557, - 558, 559, 560, 561, 562, 563, 564, 26, 38, 570, - 571, 572, 573, 574, 575, 422, 27, 39, 578, 579, - 580 + 515, 23, 35, 534, 535, 536, 537, 538, 539, 540, + 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, + 551, 552, 24, 36, 554, 555, 418, 419, 420, 421, + 25, 37, 566, 567, 568, 569, 570, 571, 572, 573, + 574, 575, 576, 26, 38, 582, 583, 584, 585, 586, + 587, 422, 27, 39, 590, 591, 592 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -1633,140 +1657,142 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_uint16 yytable[] = { - 2, 466, 423, 451, 424, 425, 541, 438, 576, 577, - 494, 3, 581, 582, 583, 439, 440, 565, 566, 567, - 568, 569, 584, 466, 516, 517, 518, 519, 520, 521, - 522, 523, 524, 525, 526, 527, 585, 586, 587, 452, - 453, 588, 589, 590, 4, 591, 592, 593, 594, 595, - 5, 544, 545, 546, 547, 548, 549, 550, 551, 552, - 553, 596, 597, 598, 454, 426, 499, 500, 501, 502, - 503, 504, 505, 506, 599, 600, 601, 602, 603, 604, - 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, - 615, 616, 617, 618, 6, 619, 427, 620, 621, 428, - 441, 622, 442, 623, 624, 625, 626, 627, 628, 629, - 7, 630, 631, 632, 633, 634, 635, 636, 637, 638, - 639, 640, 641, 642, 643, 455, 456, 644, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, - 667, 8, 668, 669, 670, 671, 672, 673, 674, 675, - 676, 677, 678, 679, 457, 680, 681, 682, 683, 684, - 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, - 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, - 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, - 715, 716, 9, 717, 468, 469, 470, 718, 719, 720, - 721, 722, 723, 724, 473, 725, 726, 727, 728, 429, - 10, 729, 730, 443, 467, 731, 468, 469, 470, 471, - 472, 483, 484, 485, 486, 487, 473, 11, 732, 733, - 734, 735, 736, 737, 738, 12, 739, 740, 741, 742, - 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, - 753, 754, 755, 756, 757, 758, 759, 760, 13, 761, - 762, 0, 14, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 763, 764, 765, 766, 71, 72, - 73, 767, 768, 769, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 770, 771, 772, 773, 774, - 775, 776, 777, 778, 115, 116, 117, 779, 118, 119, - 120, 780, 781, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 782, 783, 784, - 145, 785, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 786, 787, 788, 789, 790, 791, 792, 793, - 794, 795, 796, 797, 798, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 799, 194, 800, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 801, 802, 803, 804, 805, 806, 807, 808, 809, - 810, 811, 210, 211, 212, 213, 214, 215, 812, 813, - 814, 815, 816, 817, 216, 818, 819, 820, 821, 822, - 823, 824, 217, 218, 825, 219, 220, 826, 221, 222, - 827, 828, 223, 224, 225, 226, 227, 228, 229, 829, - 830, 831, 230, 832, 833, 834, 835, 836, 837, 838, - 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, - 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, - 859, 860, 861, 862, 0, 0, 0, 0, 0, 0, + 2, 466, 423, 451, 424, 425, 553, 438, 588, 589, + 494, 3, 593, 594, 595, 439, 440, 577, 578, 579, + 580, 581, 596, 466, 556, 557, 558, 559, 560, 561, + 562, 563, 564, 565, 597, 598, 599, 600, 601, 452, + 453, 602, 603, 604, 4, 605, 606, 607, 608, 609, + 5, 499, 500, 501, 502, 503, 504, 505, 506, 610, + 611, 612, 613, 614, 454, 426, 516, 517, 518, 519, + 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, + 530, 531, 532, 533, 615, 616, 617, 618, 619, 620, + 621, 622, 623, 624, 6, 625, 427, 626, 627, 428, + 441, 628, 442, 629, 630, 631, 632, 633, 634, 635, + 7, 636, 637, 638, 639, 640, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 455, 456, 656, 657, 658, 659, 660, 661, 662, + 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, + 673, 8, 674, 675, 676, 677, 678, 679, 680, 681, + 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, + 457, 692, 693, 694, 695, 696, 697, 698, 699, 700, + 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, + 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, + 721, 722, 723, 724, 725, 726, 727, 728, 9, 729, + 468, 469, 470, 730, 731, 732, 733, 734, 735, 736, + 473, 737, 738, 739, 740, 429, 10, 741, 742, 443, + 467, 743, 468, 469, 470, 471, 472, 483, 484, 485, + 486, 487, 473, 11, 744, 745, 746, 747, 748, 749, + 750, 12, 751, 752, 753, 754, 755, 756, 757, 758, + 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, + 769, 770, 771, 772, 13, 773, 774, 0, 14, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 775, 776, 777, 778, 71, 72, 73, 779, 780, 781, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 782, 783, 784, 785, 786, 787, 788, 789, 790, + 115, 116, 117, 791, 118, 119, 120, 792, 793, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 794, 795, 796, 145, 797, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 798, 799, + 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, + 810, 811, 812, 813, 814, 815, 816, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 817, 194, 818, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 819, 820, 821, 822, 823, 824, 825, + 826, 827, 828, 829, 210, 211, 212, 213, 214, 215, + 830, 831, 832, 833, 834, 835, 216, 836, 837, 838, + 839, 840, 841, 842, 217, 218, 843, 219, 220, 844, + 221, 222, 845, 846, 223, 224, 225, 226, 227, 228, + 229, 847, 848, 849, 230, 850, 851, 852, 853, 854, + 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, + 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, + 875, 876, 877, 878, 879, 880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 495, 496, 497, - 498 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 495, + 496, 497, 498 }; static const yytype_int16 yycheck[] = { - 0, 43, 43, 43, 45, 46, 111, 43, 269, 270, - 33, 11, 10, 10, 10, 51, 52, 238, 239, 240, - 241, 242, 10, 43, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 10, 10, 10, 79, + 0, 43, 43, 43, 45, 46, 111, 43, 275, 276, + 33, 11, 10, 10, 10, 51, 52, 244, 245, 246, + 247, 248, 10, 43, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 10, 10, 10, 10, 10, 79, 80, 10, 10, 10, 44, 10, 10, 10, 10, 10, - 50, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 10, 10, 10, 104, 106, 95, 96, 97, 98, - 99, 100, 101, 102, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 50, 95, 96, 97, 98, 99, 100, 101, 102, 10, + 10, 10, 10, 10, 104, 106, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 94, 10, 137, 10, 10, 140, 136, 10, 138, 10, 10, 10, 10, 10, 10, 10, 110, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 165, 166, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 171, 172, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 151, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 204, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 210, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 208, 10, + 252, 253, 254, 10, 10, 10, 10, 10, 10, 10, + 262, 10, 10, 10, 10, 266, 226, 10, 10, 265, + 250, 10, 252, 253, 254, 255, 256, 279, 280, 281, + 282, 283, 262, 243, 10, 10, 10, 10, 10, 10, + 10, 251, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 202, 10, 246, 247, 248, 10, 10, 10, - 10, 10, 10, 10, 256, 10, 10, 10, 10, 260, - 220, 10, 10, 259, 244, 10, 246, 247, 248, 249, - 250, 273, 274, 275, 276, 277, 256, 237, 10, 10, - 10, 10, 10, 10, 10, 245, 10, 10, 10, 10, + 10, 10, 10, 10, 274, 10, 10, -1, 278, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 10, 10, 10, 10, 47, 48, 49, 10, 10, 10, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 103, 104, 105, 10, 107, 108, 109, 10, 10, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 10, 10, 10, 139, 10, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 268, 10, - 10, -1, 272, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 10, 10, 10, 10, 47, 48, - 49, 10, 10, 10, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 103, 104, 105, 10, 107, 108, - 109, 10, 10, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 10, 10, 10, - 139, 10, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 10, 203, 10, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 231, 232, 233, 234, 235, 236, 10, 10, - 10, 10, 10, 10, 243, 10, 10, 10, 10, 10, - 10, 10, 251, 252, 10, 254, 255, 10, 257, 258, - 10, 10, 261, 262, 263, 264, 265, 266, 267, 10, - 10, 10, 271, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 10, 209, 10, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 237, 238, 239, 240, 241, 242, + 10, 10, 10, 10, 10, 10, 249, 10, 10, 10, + 10, 10, 10, 10, 257, 258, 10, 260, 261, 10, + 263, 264, 10, 10, 267, 268, 269, 270, 271, 272, + 273, 10, 10, 10, 277, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, -1, -1, -1, -1, -1, -1, + 10, 10, 10, 10, 10, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 33, 33, 33, - 33 + -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, + 33, 33, 33 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint16 yystos[] = { - 0, 279, 0, 11, 44, 50, 94, 110, 151, 202, - 220, 237, 245, 268, 272, 280, 281, 284, 287, 290, - 293, 301, 518, 529, 544, 552, 565, 574, 282, 285, - 288, 291, 294, 302, 519, 530, 545, 553, 566, 575, + 0, 285, 0, 11, 44, 50, 94, 110, 151, 208, + 226, 243, 251, 274, 278, 286, 287, 290, 293, 296, + 299, 307, 524, 535, 556, 564, 577, 586, 288, 291, + 294, 297, 300, 308, 525, 536, 557, 565, 578, 587, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, @@ -1778,15 +1804,112 @@ static const yytype_uint16 yystos[] = 109, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 139, 141, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 203, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 231, 232, 233, 234, 235, 236, 243, 251, 252, 254, - 255, 257, 258, 261, 262, 263, 264, 265, 266, 267, - 271, 283, 304, 305, 306, 307, 308, 309, 310, 311, + 145, 146, 147, 148, 149, 150, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 209, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, + 237, 238, 239, 240, 241, 242, 249, 257, 258, 260, + 261, 263, 264, 267, 268, 269, 270, 271, 272, 273, + 277, 289, 310, 311, 312, 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, + 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, + 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, + 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, + 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, + 488, 489, 490, 491, 492, 493, 494, 495, 560, 561, + 562, 563, 585, 43, 45, 46, 106, 137, 140, 266, + 292, 496, 497, 498, 499, 500, 501, 502, 43, 51, + 52, 136, 138, 265, 295, 503, 504, 505, 506, 507, + 508, 43, 79, 80, 104, 171, 172, 210, 298, 517, + 518, 519, 520, 521, 522, 523, 43, 250, 252, 253, + 254, 255, 256, 262, 301, 509, 510, 511, 512, 513, + 514, 515, 516, 279, 280, 281, 282, 283, 302, 303, + 304, 305, 306, 309, 509, 510, 511, 512, 513, 95, + 96, 97, 98, 99, 100, 101, 102, 526, 527, 528, + 529, 530, 531, 532, 533, 534, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 537, 538, 539, 540, 541, 542, + 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, + 553, 554, 555, 111, 558, 559, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 566, 567, 568, 569, + 570, 571, 572, 573, 574, 575, 576, 244, 245, 246, + 247, 248, 579, 580, 581, 582, 583, 584, 275, 276, + 588, 589, 590, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10 +}; + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint16 yyr1[] = +{ + 0, 284, 285, 285, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 287, 288, 288, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 290, 291, 291, 292, 292, 292, 292, 292, 292, 292, + 293, 294, 294, 295, 295, 295, 295, 295, 295, 296, + 297, 297, 298, 298, 298, 298, 298, 298, 298, 299, + 300, 300, 301, 301, 301, 301, 301, 301, 301, 301, + 302, 303, 304, 305, 306, 307, 308, 308, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, @@ -1804,116 +1927,22 @@ static const yytype_uint16 yystos[] = 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, - 482, 483, 484, 485, 486, 487, 488, 489, 548, 549, - 550, 551, 573, 43, 45, 46, 106, 137, 140, 260, - 286, 490, 491, 492, 493, 494, 495, 496, 43, 51, - 52, 136, 138, 259, 289, 497, 498, 499, 500, 501, - 502, 43, 79, 80, 104, 165, 166, 204, 292, 511, - 512, 513, 514, 515, 516, 517, 43, 244, 246, 247, - 248, 249, 250, 256, 295, 503, 504, 505, 506, 507, - 508, 509, 510, 273, 274, 275, 276, 277, 296, 297, - 298, 299, 300, 303, 503, 504, 505, 506, 507, 95, - 96, 97, 98, 99, 100, 101, 102, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 531, 532, - 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, - 543, 111, 546, 547, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 554, 555, 556, 557, 558, 559, - 560, 561, 562, 563, 564, 238, 239, 240, 241, 242, - 567, 568, 569, 570, 571, 572, 269, 270, 576, 577, - 578, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10 -}; - - /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint16 yyr1[] = -{ - 0, 278, 279, 279, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 281, 282, 282, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, - 284, 285, 285, 286, 286, 286, 286, 286, 286, 286, - 287, 288, 288, 289, 289, 289, 289, 289, 289, 290, - 291, 291, 292, 292, 292, 292, 292, 292, 292, 293, - 294, 294, 295, 295, 295, 295, 295, 295, 295, 295, - 296, 297, 298, 299, 300, 301, 302, 302, 303, 303, - 303, 303, 303, 303, 303, 303, 303, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, - 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, - 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, - 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, - 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, - 516, 517, 518, 519, 519, 520, 520, 520, 520, 520, - 520, 520, 520, 521, 522, 523, 524, 525, 526, 527, - 528, 529, 530, 530, 531, 531, 531, 531, 531, 531, - 531, 531, 531, 531, 531, 531, 532, 533, 534, 535, - 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, - 545, 546, 547, 548, 549, 550, 551, 552, 553, 553, - 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, - 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, - 565, 566, 566, 567, 567, 567, 567, 567, 568, 569, - 570, 571, 572, 573, 574, 575, 575, 576, 576, 577, - 578 + 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, + 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, + 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, + 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, + 522, 523, 524, 525, 525, 526, 526, 526, 526, 526, + 526, 526, 526, 527, 528, 529, 530, 531, 532, 533, + 534, 535, 536, 536, 537, 537, 537, 537, 537, 537, + 537, 537, 537, 537, 537, 537, 537, 537, 537, 537, + 537, 537, 538, 539, 540, 541, 542, 543, 544, 545, + 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, + 556, 557, 557, 558, 559, 560, 561, 562, 563, 564, + 565, 565, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 567, 568, 569, 570, 571, 572, 573, 574, + 575, 576, 577, 578, 578, 579, 579, 579, 579, 579, + 580, 581, 582, 583, 584, 585, 586, 587, 587, 588, + 588, 589, 590 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -1970,14 +1999,15 @@ static const yytype_uint8 yyr2[] = 2, 2, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 0, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, - 0, 1, 2, 2, 2, 3, 3, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 2, 0, 1, 1, 1, 1, 1, 2, 2, - 2, 2, 2, 3, 1, 2, 0, 1, 1, 2, - 2 + 1, 2, 0, 1, 2, 2, 2, 3, 3, 1, + 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 1, 2, 0, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 3, 1, 2, 0, 1, + 1, 2, 2 }; @@ -2662,15 +2692,15 @@ yyreduce: switch (yyn) { case 16: -#line 186 "./util/configparser.y" +#line 188 "./util/configparser.y" { OUTYY(("\nP(server:)\n")); } -#line 2670 "util/configparser.c" +#line 2700 "util/configparser.c" break; case 210: -#line 278 "./util/configparser.y" +#line 280 "./util/configparser.y" { struct config_stub* s; OUTYY(("\nP(stub_zone:)\n")); @@ -2681,11 +2711,11 @@ yyreduce: } else yyerror("out of memory"); } -#line 2685 "util/configparser.c" +#line 2715 "util/configparser.c" break; case 220: -#line 295 "./util/configparser.y" +#line 297 "./util/configparser.y" { struct config_stub* s; OUTYY(("\nP(forward_zone:)\n")); @@ -2696,11 +2726,11 @@ yyreduce: } else yyerror("out of memory"); } -#line 2700 "util/configparser.c" +#line 2730 "util/configparser.c" break; case 229: -#line 312 "./util/configparser.y" +#line 314 "./util/configparser.y" { struct config_view* s; OUTYY(("\nP(view:)\n")); @@ -2713,11 +2743,11 @@ yyreduce: } else yyerror("out of memory"); } -#line 2717 "util/configparser.c" +#line 2747 "util/configparser.c" break; case 239: -#line 331 "./util/configparser.y" +#line 333 "./util/configparser.y" { struct config_auth* s; OUTYY(("\nP(auth_zone:)\n")); @@ -2733,11 +2763,11 @@ yyreduce: } else yyerror("out of memory"); } -#line 2737 "util/configparser.c" +#line 2767 "util/configparser.c" break; case 250: -#line 355 "./util/configparser.y" +#line 357 "./util/configparser.y" { uint8_t* bitlist; size_t len = 0; @@ -2754,11 +2784,11 @@ yyreduce: } } -#line 2758 "util/configparser.c" +#line 2788 "util/configparser.c" break; case 251: -#line 374 "./util/configparser.y" +#line 376 "./util/configparser.y" { OUTYY(("P(rpz_action_override:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "nxdomain")!=0 && strcmp((yyvsp[0].str), "nodata")!=0 && @@ -2773,21 +2803,21 @@ yyreduce: cfg_parser->cfg->auths->rpz_action_override = (yyvsp[0].str); } } -#line 2777 "util/configparser.c" +#line 2807 "util/configparser.c" break; case 252: -#line 391 "./util/configparser.y" +#line 393 "./util/configparser.y" { OUTYY(("P(rpz_cname_override:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->auths->rpz_cname); cfg_parser->cfg->auths->rpz_cname = (yyvsp[0].str); } -#line 2787 "util/configparser.c" +#line 2817 "util/configparser.c" break; case 253: -#line 399 "./util/configparser.y" +#line 401 "./util/configparser.y" { OUTYY(("P(rpz_log:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -2795,21 +2825,21 @@ yyreduce: else cfg_parser->cfg->auths->rpz_log = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 2799 "util/configparser.c" +#line 2829 "util/configparser.c" break; case 254: -#line 409 "./util/configparser.y" +#line 411 "./util/configparser.y" { OUTYY(("P(rpz_log_name:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->auths->rpz_log_name); cfg_parser->cfg->auths->rpz_log_name = (yyvsp[0].str); } -#line 2809 "util/configparser.c" +#line 2839 "util/configparser.c" break; case 255: -#line 417 "./util/configparser.y" +#line 419 "./util/configparser.y" { struct config_auth* s; OUTYY(("\nP(rpz:)\n")); @@ -2825,11 +2855,11 @@ yyreduce: } else yyerror("out of memory"); } -#line 2829 "util/configparser.c" +#line 2859 "util/configparser.c" break; case 268: -#line 440 "./util/configparser.y" +#line 442 "./util/configparser.y" { OUTYY(("P(server_num_threads:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -2837,11 +2867,11 @@ yyreduce: else cfg_parser->cfg->num_threads = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 2841 "util/configparser.c" +#line 2871 "util/configparser.c" break; case 269: -#line 449 "./util/configparser.y" +#line 451 "./util/configparser.y" { OUTYY(("P(server_verbosity:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -2849,11 +2879,11 @@ yyreduce: else cfg_parser->cfg->verbosity = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 2853 "util/configparser.c" +#line 2883 "util/configparser.c" break; case 270: -#line 458 "./util/configparser.y" +#line 460 "./util/configparser.y" { OUTYY(("P(server_statistics_interval:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "") == 0 || strcmp((yyvsp[0].str), "0") == 0) @@ -2863,11 +2893,11 @@ yyreduce: else cfg_parser->cfg->stat_interval = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 2867 "util/configparser.c" +#line 2897 "util/configparser.c" break; case 271: -#line 469 "./util/configparser.y" +#line 471 "./util/configparser.y" { OUTYY(("P(server_statistics_cumulative:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -2875,11 +2905,11 @@ yyreduce: else cfg_parser->cfg->stat_cumulative = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 2879 "util/configparser.c" +#line 2909 "util/configparser.c" break; case 272: -#line 478 "./util/configparser.y" +#line 480 "./util/configparser.y" { OUTYY(("P(server_extended_statistics:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -2887,11 +2917,11 @@ yyreduce: else cfg_parser->cfg->stat_extended = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 2891 "util/configparser.c" +#line 2921 "util/configparser.c" break; case 273: -#line 487 "./util/configparser.y" +#line 489 "./util/configparser.y" { OUTYY(("P(server_shm_enable:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -2899,11 +2929,11 @@ yyreduce: else cfg_parser->cfg->shm_enable = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 2903 "util/configparser.c" +#line 2933 "util/configparser.c" break; case 274: -#line 496 "./util/configparser.y" +#line 498 "./util/configparser.y" { OUTYY(("P(server_shm_key:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "") == 0 || strcmp((yyvsp[0].str), "0") == 0) @@ -2913,11 +2943,11 @@ yyreduce: else cfg_parser->cfg->shm_key = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 2917 "util/configparser.c" +#line 2947 "util/configparser.c" break; case 275: -#line 507 "./util/configparser.y" +#line 509 "./util/configparser.y" { OUTYY(("P(server_port:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -2925,11 +2955,11 @@ yyreduce: else cfg_parser->cfg->port = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 2929 "util/configparser.c" +#line 2959 "util/configparser.c" break; case 276: -#line 516 "./util/configparser.y" +#line 518 "./util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(server_send_client_subnet:%s)\n", (yyvsp[0].str))); @@ -2940,11 +2970,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 2944 "util/configparser.c" +#line 2974 "util/configparser.c" break; case 277: -#line 528 "./util/configparser.y" +#line 530 "./util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(server_client_subnet_zone:%s)\n", (yyvsp[0].str))); @@ -2956,11 +2986,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 2960 "util/configparser.c" +#line 2990 "util/configparser.c" break; case 278: -#line 542 "./util/configparser.y" +#line 544 "./util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(server_client_subnet_always_forward:%s)\n", (yyvsp[0].str))); @@ -2974,11 +3004,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 2978 "util/configparser.c" +#line 3008 "util/configparser.c" break; case 279: -#line 557 "./util/configparser.y" +#line 559 "./util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(client_subnet_opcode:%s)\n", (yyvsp[0].str))); @@ -2988,11 +3018,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 2992 "util/configparser.c" +#line 3022 "util/configparser.c" break; case 280: -#line 568 "./util/configparser.y" +#line 570 "./util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(max_client_subnet_ipv4:%s)\n", (yyvsp[0].str))); @@ -3008,11 +3038,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 3012 "util/configparser.c" +#line 3042 "util/configparser.c" break; case 281: -#line 585 "./util/configparser.y" +#line 587 "./util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(max_client_subnet_ipv6:%s)\n", (yyvsp[0].str))); @@ -3028,11 +3058,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 3032 "util/configparser.c" +#line 3062 "util/configparser.c" break; case 282: -#line 602 "./util/configparser.y" +#line 604 "./util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(min_client_subnet_ipv4:%s)\n", (yyvsp[0].str))); @@ -3048,11 +3078,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 3052 "util/configparser.c" +#line 3082 "util/configparser.c" break; case 283: -#line 619 "./util/configparser.y" +#line 621 "./util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(min_client_subnet_ipv6:%s)\n", (yyvsp[0].str))); @@ -3068,11 +3098,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 3072 "util/configparser.c" +#line 3102 "util/configparser.c" break; case 284: -#line 636 "./util/configparser.y" +#line 638 "./util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(max_ecs_tree_size_ipv4:%s)\n", (yyvsp[0].str))); @@ -3086,11 +3116,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 3090 "util/configparser.c" +#line 3120 "util/configparser.c" break; case 285: -#line 651 "./util/configparser.y" +#line 653 "./util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(max_ecs_tree_size_ipv6:%s)\n", (yyvsp[0].str))); @@ -3104,11 +3134,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 3108 "util/configparser.c" +#line 3138 "util/configparser.c" break; case 286: -#line 666 "./util/configparser.y" +#line 668 "./util/configparser.y" { OUTYY(("P(server_interface:%s)\n", (yyvsp[0].str))); if(cfg_parser->cfg->num_ifs == 0) @@ -3120,11 +3150,11 @@ yyreduce: else cfg_parser->cfg->ifs[cfg_parser->cfg->num_ifs++] = (yyvsp[0].str); } -#line 3124 "util/configparser.c" +#line 3154 "util/configparser.c" break; case 287: -#line 679 "./util/configparser.y" +#line 681 "./util/configparser.y" { OUTYY(("P(server_outgoing_interface:%s)\n", (yyvsp[0].str))); if(cfg_parser->cfg->num_out_ifs == 0) @@ -3138,11 +3168,11 @@ yyreduce: cfg_parser->cfg->out_ifs[ cfg_parser->cfg->num_out_ifs++] = (yyvsp[0].str); } -#line 3142 "util/configparser.c" +#line 3172 "util/configparser.c" break; case 288: -#line 694 "./util/configparser.y" +#line 696 "./util/configparser.y" { OUTYY(("P(server_outgoing_range:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -3150,11 +3180,11 @@ yyreduce: else cfg_parser->cfg->outgoing_num_ports = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3154 "util/configparser.c" +#line 3184 "util/configparser.c" break; case 289: -#line 703 "./util/configparser.y" +#line 705 "./util/configparser.y" { OUTYY(("P(server_outgoing_port_permit:%s)\n", (yyvsp[0].str))); if(!cfg_mark_ports((yyvsp[0].str), 1, @@ -3162,11 +3192,11 @@ yyreduce: yyerror("port number or range (\"low-high\") expected"); free((yyvsp[0].str)); } -#line 3166 "util/configparser.c" +#line 3196 "util/configparser.c" break; case 290: -#line 712 "./util/configparser.y" +#line 714 "./util/configparser.y" { OUTYY(("P(server_outgoing_port_avoid:%s)\n", (yyvsp[0].str))); if(!cfg_mark_ports((yyvsp[0].str), 0, @@ -3174,11 +3204,11 @@ yyreduce: yyerror("port number or range (\"low-high\") expected"); free((yyvsp[0].str)); } -#line 3178 "util/configparser.c" +#line 3208 "util/configparser.c" break; case 291: -#line 721 "./util/configparser.y" +#line 723 "./util/configparser.y" { OUTYY(("P(server_outgoing_num_tcp:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3186,11 +3216,11 @@ yyreduce: else cfg_parser->cfg->outgoing_num_tcp = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3190 "util/configparser.c" +#line 3220 "util/configparser.c" break; case 292: -#line 730 "./util/configparser.y" +#line 732 "./util/configparser.y" { OUTYY(("P(server_incoming_num_tcp:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3198,11 +3228,11 @@ yyreduce: else cfg_parser->cfg->incoming_num_tcp = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3202 "util/configparser.c" +#line 3232 "util/configparser.c" break; case 293: -#line 739 "./util/configparser.y" +#line 741 "./util/configparser.y" { OUTYY(("P(server_interface_automatic:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3210,11 +3240,11 @@ yyreduce: else cfg_parser->cfg->if_automatic = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3214 "util/configparser.c" +#line 3244 "util/configparser.c" break; case 294: -#line 748 "./util/configparser.y" +#line 750 "./util/configparser.y" { OUTYY(("P(server_do_ip4:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3222,11 +3252,11 @@ yyreduce: else cfg_parser->cfg->do_ip4 = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3226 "util/configparser.c" +#line 3256 "util/configparser.c" break; case 295: -#line 757 "./util/configparser.y" +#line 759 "./util/configparser.y" { OUTYY(("P(server_do_ip6:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3234,11 +3264,11 @@ yyreduce: else cfg_parser->cfg->do_ip6 = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3238 "util/configparser.c" +#line 3268 "util/configparser.c" break; case 296: -#line 766 "./util/configparser.y" +#line 768 "./util/configparser.y" { OUTYY(("P(server_do_udp:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3246,11 +3276,11 @@ yyreduce: else cfg_parser->cfg->do_udp = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3250 "util/configparser.c" +#line 3280 "util/configparser.c" break; case 297: -#line 775 "./util/configparser.y" +#line 777 "./util/configparser.y" { OUTYY(("P(server_do_tcp:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3258,11 +3288,11 @@ yyreduce: else cfg_parser->cfg->do_tcp = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3262 "util/configparser.c" +#line 3292 "util/configparser.c" break; case 298: -#line 784 "./util/configparser.y" +#line 786 "./util/configparser.y" { OUTYY(("P(server_prefer_ip6:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3270,11 +3300,11 @@ yyreduce: else cfg_parser->cfg->prefer_ip6 = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3274 "util/configparser.c" +#line 3304 "util/configparser.c" break; case 299: -#line 793 "./util/configparser.y" +#line 795 "./util/configparser.y" { OUTYY(("P(server_tcp_mss:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3282,11 +3312,11 @@ yyreduce: else cfg_parser->cfg->tcp_mss = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3286 "util/configparser.c" +#line 3316 "util/configparser.c" break; case 300: -#line 802 "./util/configparser.y" +#line 804 "./util/configparser.y" { OUTYY(("P(server_outgoing_tcp_mss:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3294,11 +3324,11 @@ yyreduce: else cfg_parser->cfg->outgoing_tcp_mss = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3298 "util/configparser.c" +#line 3328 "util/configparser.c" break; case 301: -#line 811 "./util/configparser.y" +#line 813 "./util/configparser.y" { OUTYY(("P(server_tcp_idle_timeout:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3310,11 +3340,11 @@ yyreduce: else cfg_parser->cfg->tcp_idle_timeout = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3314 "util/configparser.c" +#line 3344 "util/configparser.c" break; case 302: -#line 824 "./util/configparser.y" +#line 826 "./util/configparser.y" { OUTYY(("P(server_tcp_keepalive:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3322,11 +3352,11 @@ yyreduce: else cfg_parser->cfg->do_tcp_keepalive = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3326 "util/configparser.c" +#line 3356 "util/configparser.c" break; case 303: -#line 833 "./util/configparser.y" +#line 835 "./util/configparser.y" { OUTYY(("P(server_tcp_keepalive_timeout:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3338,11 +3368,11 @@ yyreduce: else cfg_parser->cfg->tcp_keepalive_timeout = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3342 "util/configparser.c" +#line 3372 "util/configparser.c" break; case 304: -#line 846 "./util/configparser.y" +#line 848 "./util/configparser.y" { OUTYY(("P(server_tcp_upstream:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3350,11 +3380,11 @@ yyreduce: else cfg_parser->cfg->tcp_upstream = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3354 "util/configparser.c" +#line 3384 "util/configparser.c" break; case 305: -#line 855 "./util/configparser.y" +#line 857 "./util/configparser.y" { OUTYY(("P(server_udp_upstream_without_downstream:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3362,11 +3392,11 @@ yyreduce: else cfg_parser->cfg->udp_upstream_without_downstream = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3366 "util/configparser.c" +#line 3396 "util/configparser.c" break; case 306: -#line 864 "./util/configparser.y" +#line 866 "./util/configparser.y" { OUTYY(("P(server_ssl_upstream:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3374,31 +3404,31 @@ yyreduce: else cfg_parser->cfg->ssl_upstream = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3378 "util/configparser.c" +#line 3408 "util/configparser.c" break; case 307: -#line 873 "./util/configparser.y" +#line 875 "./util/configparser.y" { OUTYY(("P(server_ssl_service_key:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->ssl_service_key); cfg_parser->cfg->ssl_service_key = (yyvsp[0].str); } -#line 3388 "util/configparser.c" +#line 3418 "util/configparser.c" break; case 308: -#line 880 "./util/configparser.y" +#line 882 "./util/configparser.y" { OUTYY(("P(server_ssl_service_pem:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->ssl_service_pem); cfg_parser->cfg->ssl_service_pem = (yyvsp[0].str); } -#line 3398 "util/configparser.c" +#line 3428 "util/configparser.c" break; case 309: -#line 887 "./util/configparser.y" +#line 889 "./util/configparser.y" { OUTYY(("P(server_ssl_port:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -3406,21 +3436,21 @@ yyreduce: else cfg_parser->cfg->ssl_port = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3410 "util/configparser.c" +#line 3440 "util/configparser.c" break; case 310: -#line 896 "./util/configparser.y" +#line 898 "./util/configparser.y" { OUTYY(("P(server_tls_cert_bundle:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->tls_cert_bundle); cfg_parser->cfg->tls_cert_bundle = (yyvsp[0].str); } -#line 3420 "util/configparser.c" +#line 3450 "util/configparser.c" break; case 311: -#line 903 "./util/configparser.y" +#line 905 "./util/configparser.y" { OUTYY(("P(server_tls_win_cert:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3428,53 +3458,53 @@ yyreduce: else cfg_parser->cfg->tls_win_cert = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3432 "util/configparser.c" +#line 3462 "util/configparser.c" break; case 312: -#line 912 "./util/configparser.y" +#line 914 "./util/configparser.y" { OUTYY(("P(server_tls_additional_port:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->tls_additional_port, (yyvsp[0].str))) yyerror("out of memory"); } -#line 3443 "util/configparser.c" +#line 3473 "util/configparser.c" break; case 313: -#line 920 "./util/configparser.y" +#line 922 "./util/configparser.y" { OUTYY(("P(server_tls_ciphers:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->tls_ciphers); cfg_parser->cfg->tls_ciphers = (yyvsp[0].str); } -#line 3453 "util/configparser.c" +#line 3483 "util/configparser.c" break; case 314: -#line 927 "./util/configparser.y" +#line 929 "./util/configparser.y" { OUTYY(("P(server_tls_ciphersuites:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->tls_ciphersuites); cfg_parser->cfg->tls_ciphersuites = (yyvsp[0].str); } -#line 3463 "util/configparser.c" +#line 3493 "util/configparser.c" break; case 315: -#line 934 "./util/configparser.y" +#line 936 "./util/configparser.y" { OUTYY(("P(server_tls_session_ticket_keys:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_append(&cfg_parser->cfg->tls_session_ticket_keys, (yyvsp[0].str))) yyerror("out of memory"); } -#line 3474 "util/configparser.c" +#line 3504 "util/configparser.c" break; case 316: -#line 942 "./util/configparser.y" +#line 944 "./util/configparser.y" { OUTYY(("P(server_use_systemd:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3482,11 +3512,11 @@ yyreduce: else cfg_parser->cfg->use_systemd = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3486 "util/configparser.c" +#line 3516 "util/configparser.c" break; case 317: -#line 951 "./util/configparser.y" +#line 953 "./util/configparser.y" { OUTYY(("P(server_do_daemonize:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3494,11 +3524,11 @@ yyreduce: else cfg_parser->cfg->do_daemonize = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3498 "util/configparser.c" +#line 3528 "util/configparser.c" break; case 318: -#line 960 "./util/configparser.y" +#line 962 "./util/configparser.y" { OUTYY(("P(server_use_syslog:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3511,11 +3541,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 3515 "util/configparser.c" +#line 3545 "util/configparser.c" break; case 319: -#line 974 "./util/configparser.y" +#line 976 "./util/configparser.y" { OUTYY(("P(server_log_time_ascii:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3523,11 +3553,11 @@ yyreduce: else cfg_parser->cfg->log_time_ascii = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3527 "util/configparser.c" +#line 3557 "util/configparser.c" break; case 320: -#line 983 "./util/configparser.y" +#line 985 "./util/configparser.y" { OUTYY(("P(server_log_queries:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3535,11 +3565,11 @@ yyreduce: else cfg_parser->cfg->log_queries = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3539 "util/configparser.c" +#line 3569 "util/configparser.c" break; case 321: -#line 992 "./util/configparser.y" +#line 994 "./util/configparser.y" { OUTYY(("P(server_log_replies:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3547,11 +3577,11 @@ yyreduce: else cfg_parser->cfg->log_replies = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3551 "util/configparser.c" +#line 3581 "util/configparser.c" break; case 322: -#line 1001 "./util/configparser.y" +#line 1003 "./util/configparser.y" { OUTYY(("P(server_log_tag_queryreply:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3559,11 +3589,11 @@ yyreduce: else cfg_parser->cfg->log_tag_queryreply = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3563 "util/configparser.c" +#line 3593 "util/configparser.c" break; case 323: -#line 1010 "./util/configparser.y" +#line 1012 "./util/configparser.y" { OUTYY(("P(server_log_servfail:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3571,11 +3601,11 @@ yyreduce: else cfg_parser->cfg->log_servfail = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3575 "util/configparser.c" +#line 3605 "util/configparser.c" break; case 324: -#line 1019 "./util/configparser.y" +#line 1021 "./util/configparser.y" { OUTYY(("P(server_log_local_actions:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3583,31 +3613,31 @@ yyreduce: else cfg_parser->cfg->log_local_actions = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3587 "util/configparser.c" +#line 3617 "util/configparser.c" break; case 325: -#line 1028 "./util/configparser.y" +#line 1030 "./util/configparser.y" { OUTYY(("P(server_chroot:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->chrootdir); cfg_parser->cfg->chrootdir = (yyvsp[0].str); } -#line 3597 "util/configparser.c" +#line 3627 "util/configparser.c" break; case 326: -#line 1035 "./util/configparser.y" +#line 1037 "./util/configparser.y" { OUTYY(("P(server_username:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->username); cfg_parser->cfg->username = (yyvsp[0].str); } -#line 3607 "util/configparser.c" +#line 3637 "util/configparser.c" break; case 327: -#line 1042 "./util/configparser.y" +#line 1044 "./util/configparser.y" { OUTYY(("P(server_directory:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->directory); @@ -3632,105 +3662,105 @@ yyreduce: } } } -#line 3636 "util/configparser.c" +#line 3666 "util/configparser.c" break; case 328: -#line 1068 "./util/configparser.y" +#line 1070 "./util/configparser.y" { OUTYY(("P(server_logfile:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->logfile); cfg_parser->cfg->logfile = (yyvsp[0].str); cfg_parser->cfg->use_syslog = 0; } -#line 3647 "util/configparser.c" +#line 3677 "util/configparser.c" break; case 329: -#line 1076 "./util/configparser.y" +#line 1078 "./util/configparser.y" { OUTYY(("P(server_pidfile:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->pidfile); cfg_parser->cfg->pidfile = (yyvsp[0].str); } -#line 3657 "util/configparser.c" +#line 3687 "util/configparser.c" break; case 330: -#line 1083 "./util/configparser.y" +#line 1085 "./util/configparser.y" { OUTYY(("P(server_root_hints:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->root_hints, (yyvsp[0].str))) yyerror("out of memory"); } -#line 3667 "util/configparser.c" +#line 3697 "util/configparser.c" break; case 331: -#line 1090 "./util/configparser.y" +#line 1092 "./util/configparser.y" { OUTYY(("P(server_dlv_anchor_file:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dlv_anchor_file); cfg_parser->cfg->dlv_anchor_file = (yyvsp[0].str); } -#line 3677 "util/configparser.c" +#line 3707 "util/configparser.c" break; case 332: -#line 1097 "./util/configparser.y" +#line 1099 "./util/configparser.y" { OUTYY(("P(server_dlv_anchor:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->dlv_anchor_list, (yyvsp[0].str))) yyerror("out of memory"); } -#line 3687 "util/configparser.c" +#line 3717 "util/configparser.c" break; case 333: -#line 1104 "./util/configparser.y" +#line 1106 "./util/configparser.y" { OUTYY(("P(server_auto_trust_anchor_file:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg-> auto_trust_anchor_file_list, (yyvsp[0].str))) yyerror("out of memory"); } -#line 3698 "util/configparser.c" +#line 3728 "util/configparser.c" break; case 334: -#line 1112 "./util/configparser.y" +#line 1114 "./util/configparser.y" { OUTYY(("P(server_trust_anchor_file:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg-> trust_anchor_file_list, (yyvsp[0].str))) yyerror("out of memory"); } -#line 3709 "util/configparser.c" +#line 3739 "util/configparser.c" break; case 335: -#line 1120 "./util/configparser.y" +#line 1122 "./util/configparser.y" { OUTYY(("P(server_trusted_keys_file:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg-> trusted_keys_file_list, (yyvsp[0].str))) yyerror("out of memory"); } -#line 3720 "util/configparser.c" +#line 3750 "util/configparser.c" break; case 336: -#line 1128 "./util/configparser.y" +#line 1130 "./util/configparser.y" { OUTYY(("P(server_trust_anchor:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->trust_anchor_list, (yyvsp[0].str))) yyerror("out of memory"); } -#line 3730 "util/configparser.c" +#line 3760 "util/configparser.c" break; case 337: -#line 1135 "./util/configparser.y" +#line 1137 "./util/configparser.y" { OUTYY(("P(server_trust_anchor_signaling:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3740,11 +3770,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3744 "util/configparser.c" +#line 3774 "util/configparser.c" break; case 338: -#line 1146 "./util/configparser.y" +#line 1148 "./util/configparser.y" { OUTYY(("P(server_root_key_sentinel:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3754,21 +3784,21 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3758 "util/configparser.c" +#line 3788 "util/configparser.c" break; case 339: -#line 1157 "./util/configparser.y" +#line 1159 "./util/configparser.y" { OUTYY(("P(server_domain_insecure:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->domain_insecure, (yyvsp[0].str))) yyerror("out of memory"); } -#line 3768 "util/configparser.c" +#line 3798 "util/configparser.c" break; case 340: -#line 1164 "./util/configparser.y" +#line 1166 "./util/configparser.y" { OUTYY(("P(server_hide_identity:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3776,11 +3806,11 @@ yyreduce: else cfg_parser->cfg->hide_identity = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3780 "util/configparser.c" +#line 3810 "util/configparser.c" break; case 341: -#line 1173 "./util/configparser.y" +#line 1175 "./util/configparser.y" { OUTYY(("P(server_hide_version:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3788,11 +3818,11 @@ yyreduce: else cfg_parser->cfg->hide_version = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3792 "util/configparser.c" +#line 3822 "util/configparser.c" break; case 342: -#line 1182 "./util/configparser.y" +#line 1184 "./util/configparser.y" { OUTYY(("P(server_hide_trustanchor:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3800,53 +3830,53 @@ yyreduce: else cfg_parser->cfg->hide_trustanchor = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3804 "util/configparser.c" +#line 3834 "util/configparser.c" break; case 343: -#line 1191 "./util/configparser.y" +#line 1193 "./util/configparser.y" { OUTYY(("P(server_identity:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->identity); cfg_parser->cfg->identity = (yyvsp[0].str); } -#line 3814 "util/configparser.c" +#line 3844 "util/configparser.c" break; case 344: -#line 1198 "./util/configparser.y" +#line 1200 "./util/configparser.y" { OUTYY(("P(server_version:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->version); cfg_parser->cfg->version = (yyvsp[0].str); } -#line 3824 "util/configparser.c" +#line 3854 "util/configparser.c" break; case 345: -#line 1205 "./util/configparser.y" +#line 1207 "./util/configparser.y" { OUTYY(("P(server_so_rcvbuf:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->so_rcvbuf)) yyerror("buffer size expected"); free((yyvsp[0].str)); } -#line 3835 "util/configparser.c" +#line 3865 "util/configparser.c" break; case 346: -#line 1213 "./util/configparser.y" +#line 1215 "./util/configparser.y" { OUTYY(("P(server_so_sndbuf:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->so_sndbuf)) yyerror("buffer size expected"); free((yyvsp[0].str)); } -#line 3846 "util/configparser.c" +#line 3876 "util/configparser.c" break; case 347: -#line 1221 "./util/configparser.y" +#line 1223 "./util/configparser.y" { OUTYY(("P(server_so_reuseport:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3855,11 +3885,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3859 "util/configparser.c" +#line 3889 "util/configparser.c" break; case 348: -#line 1231 "./util/configparser.y" +#line 1233 "./util/configparser.y" { OUTYY(("P(server_ip_transparent:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3868,11 +3898,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3872 "util/configparser.c" +#line 3902 "util/configparser.c" break; case 349: -#line 1241 "./util/configparser.y" +#line 1243 "./util/configparser.y" { OUTYY(("P(server_ip_freebind:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3881,22 +3911,22 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3885 "util/configparser.c" +#line 3915 "util/configparser.c" break; case 350: -#line 1251 "./util/configparser.y" +#line 1253 "./util/configparser.y" { OUTYY(("P(server_stream_wait_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->stream_wait_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 3896 "util/configparser.c" +#line 3926 "util/configparser.c" break; case 351: -#line 1259 "./util/configparser.y" +#line 1261 "./util/configparser.y" { OUTYY(("P(server_edns_buffer_size:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -3908,11 +3938,11 @@ yyreduce: else cfg_parser->cfg->edns_buffer_size = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3912 "util/configparser.c" +#line 3942 "util/configparser.c" break; case 352: -#line 1272 "./util/configparser.y" +#line 1274 "./util/configparser.y" { OUTYY(("P(server_msg_buffer_size:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -3922,22 +3952,22 @@ yyreduce: else cfg_parser->cfg->msg_buffer_size = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3926 "util/configparser.c" +#line 3956 "util/configparser.c" break; case 353: -#line 1283 "./util/configparser.y" +#line 1285 "./util/configparser.y" { OUTYY(("P(server_msg_cache_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->msg_cache_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 3937 "util/configparser.c" +#line 3967 "util/configparser.c" break; case 354: -#line 1291 "./util/configparser.y" +#line 1293 "./util/configparser.y" { OUTYY(("P(server_msg_cache_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -3949,11 +3979,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 3953 "util/configparser.c" +#line 3983 "util/configparser.c" break; case 355: -#line 1304 "./util/configparser.y" +#line 1306 "./util/configparser.y" { OUTYY(("P(server_num_queries_per_thread:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -3961,11 +3991,11 @@ yyreduce: else cfg_parser->cfg->num_queries_per_thread = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3965 "util/configparser.c" +#line 3995 "util/configparser.c" break; case 356: -#line 1313 "./util/configparser.y" +#line 1315 "./util/configparser.y" { OUTYY(("P(server_jostle_timeout:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3973,11 +4003,11 @@ yyreduce: else cfg_parser->cfg->jostle_time = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3977 "util/configparser.c" +#line 4007 "util/configparser.c" break; case 357: -#line 1322 "./util/configparser.y" +#line 1324 "./util/configparser.y" { OUTYY(("P(server_delay_close:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3985,11 +4015,11 @@ yyreduce: else cfg_parser->cfg->delay_close = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3989 "util/configparser.c" +#line 4019 "util/configparser.c" break; case 358: -#line 1331 "./util/configparser.y" +#line 1333 "./util/configparser.y" { OUTYY(("P(server_unblock_lan_zones:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3998,11 +4028,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4002 "util/configparser.c" +#line 4032 "util/configparser.c" break; case 359: -#line 1341 "./util/configparser.y" +#line 1343 "./util/configparser.y" { OUTYY(("P(server_insecure_lan_zones:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4011,22 +4041,22 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4015 "util/configparser.c" +#line 4045 "util/configparser.c" break; case 360: -#line 1351 "./util/configparser.y" +#line 1353 "./util/configparser.y" { OUTYY(("P(server_rrset_cache_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->rrset_cache_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 4026 "util/configparser.c" +#line 4056 "util/configparser.c" break; case 361: -#line 1359 "./util/configparser.y" +#line 1361 "./util/configparser.y" { OUTYY(("P(server_rrset_cache_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -4038,11 +4068,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 4042 "util/configparser.c" +#line 4072 "util/configparser.c" break; case 362: -#line 1372 "./util/configparser.y" +#line 1374 "./util/configparser.y" { OUTYY(("P(server_infra_host_ttl:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4050,22 +4080,22 @@ yyreduce: else cfg_parser->cfg->host_ttl = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4054 "util/configparser.c" +#line 4084 "util/configparser.c" break; case 363: -#line 1381 "./util/configparser.y" +#line 1383 "./util/configparser.y" { OUTYY(("P(server_infra_lame_ttl:%s)\n", (yyvsp[0].str))); verbose(VERB_DETAIL, "ignored infra-lame-ttl: %s (option " "removed, use infra-host-ttl)", (yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4065 "util/configparser.c" +#line 4095 "util/configparser.c" break; case 364: -#line 1389 "./util/configparser.y" +#line 1391 "./util/configparser.y" { OUTYY(("P(server_infra_cache_numhosts:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -4073,22 +4103,22 @@ yyreduce: else cfg_parser->cfg->infra_cache_numhosts = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4077 "util/configparser.c" +#line 4107 "util/configparser.c" break; case 365: -#line 1398 "./util/configparser.y" +#line 1400 "./util/configparser.y" { OUTYY(("P(server_infra_cache_lame_size:%s)\n", (yyvsp[0].str))); verbose(VERB_DETAIL, "ignored infra-cache-lame-size: %s " "(option removed, use infra-cache-numhosts)", (yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4088 "util/configparser.c" +#line 4118 "util/configparser.c" break; case 366: -#line 1406 "./util/configparser.y" +#line 1408 "./util/configparser.y" { OUTYY(("P(server_infra_cache_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -4100,11 +4130,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 4104 "util/configparser.c" +#line 4134 "util/configparser.c" break; case 367: -#line 1419 "./util/configparser.y" +#line 1421 "./util/configparser.y" { OUTYY(("P(server_infra_cache_min_rtt:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4112,21 +4142,21 @@ yyreduce: else cfg_parser->cfg->infra_cache_min_rtt = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4116 "util/configparser.c" +#line 4146 "util/configparser.c" break; case 368: -#line 1428 "./util/configparser.y" +#line 1430 "./util/configparser.y" { OUTYY(("P(server_target_fetch_policy:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->target_fetch_policy); cfg_parser->cfg->target_fetch_policy = (yyvsp[0].str); } -#line 4126 "util/configparser.c" +#line 4156 "util/configparser.c" break; case 369: -#line 1435 "./util/configparser.y" +#line 1437 "./util/configparser.y" { OUTYY(("P(server_harden_short_bufsize:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4135,11 +4165,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4139 "util/configparser.c" +#line 4169 "util/configparser.c" break; case 370: -#line 1445 "./util/configparser.y" +#line 1447 "./util/configparser.y" { OUTYY(("P(server_harden_large_queries:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4148,11 +4178,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4152 "util/configparser.c" +#line 4182 "util/configparser.c" break; case 371: -#line 1455 "./util/configparser.y" +#line 1457 "./util/configparser.y" { OUTYY(("P(server_harden_glue:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4161,11 +4191,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4165 "util/configparser.c" +#line 4195 "util/configparser.c" break; case 372: -#line 1465 "./util/configparser.y" +#line 1467 "./util/configparser.y" { OUTYY(("P(server_harden_dnssec_stripped:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4174,11 +4204,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4178 "util/configparser.c" +#line 4208 "util/configparser.c" break; case 373: -#line 1475 "./util/configparser.y" +#line 1477 "./util/configparser.y" { OUTYY(("P(server_harden_below_nxdomain:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4187,11 +4217,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4191 "util/configparser.c" +#line 4221 "util/configparser.c" break; case 374: -#line 1485 "./util/configparser.y" +#line 1487 "./util/configparser.y" { OUTYY(("P(server_harden_referral_path:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4200,11 +4230,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4204 "util/configparser.c" +#line 4234 "util/configparser.c" break; case 375: -#line 1495 "./util/configparser.y" +#line 1497 "./util/configparser.y" { OUTYY(("P(server_harden_algo_downgrade:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4213,11 +4243,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4217 "util/configparser.c" +#line 4247 "util/configparser.c" break; case 376: -#line 1505 "./util/configparser.y" +#line 1507 "./util/configparser.y" { OUTYY(("P(server_use_caps_for_id:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4226,41 +4256,41 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4230 "util/configparser.c" +#line 4260 "util/configparser.c" break; case 377: -#line 1515 "./util/configparser.y" +#line 1517 "./util/configparser.y" { OUTYY(("P(server_caps_whitelist:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->caps_whitelist, (yyvsp[0].str))) yyerror("out of memory"); } -#line 4240 "util/configparser.c" +#line 4270 "util/configparser.c" break; case 378: -#line 1522 "./util/configparser.y" +#line 1524 "./util/configparser.y" { OUTYY(("P(server_private_address:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->private_address, (yyvsp[0].str))) yyerror("out of memory"); } -#line 4250 "util/configparser.c" +#line 4280 "util/configparser.c" break; case 379: -#line 1529 "./util/configparser.y" +#line 1531 "./util/configparser.y" { OUTYY(("P(server_private_domain:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->private_domain, (yyvsp[0].str))) yyerror("out of memory"); } -#line 4260 "util/configparser.c" +#line 4290 "util/configparser.c" break; case 380: -#line 1536 "./util/configparser.y" +#line 1538 "./util/configparser.y" { OUTYY(("P(server_prefetch:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4268,11 +4298,11 @@ yyreduce: else cfg_parser->cfg->prefetch = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4272 "util/configparser.c" +#line 4302 "util/configparser.c" break; case 381: -#line 1545 "./util/configparser.y" +#line 1547 "./util/configparser.y" { OUTYY(("P(server_prefetch_key:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4280,11 +4310,11 @@ yyreduce: else cfg_parser->cfg->prefetch_key = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4284 "util/configparser.c" +#line 4314 "util/configparser.c" break; case 382: -#line 1554 "./util/configparser.y" +#line 1556 "./util/configparser.y" { OUTYY(("P(server_deny_any:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4292,11 +4322,11 @@ yyreduce: else cfg_parser->cfg->deny_any = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4296 "util/configparser.c" +#line 4326 "util/configparser.c" break; case 383: -#line 1563 "./util/configparser.y" +#line 1565 "./util/configparser.y" { OUTYY(("P(server_unwanted_reply_threshold:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4304,21 +4334,21 @@ yyreduce: else cfg_parser->cfg->unwanted_threshold = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4308 "util/configparser.c" +#line 4338 "util/configparser.c" break; case 384: -#line 1572 "./util/configparser.y" +#line 1574 "./util/configparser.y" { OUTYY(("P(server_do_not_query_address:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->donotqueryaddrs, (yyvsp[0].str))) yyerror("out of memory"); } -#line 4318 "util/configparser.c" +#line 4348 "util/configparser.c" break; case 385: -#line 1579 "./util/configparser.y" +#line 1581 "./util/configparser.y" { OUTYY(("P(server_do_not_query_localhost:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4327,11 +4357,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4331 "util/configparser.c" +#line 4361 "util/configparser.c" break; case 386: -#line 1589 "./util/configparser.y" +#line 1591 "./util/configparser.y" { OUTYY(("P(server_access_control:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "deny")!=0 && strcmp((yyvsp[0].str), "refuse")!=0 && @@ -4350,21 +4380,21 @@ yyreduce: fatal_exit("out of memory adding acl"); } } -#line 4354 "util/configparser.c" +#line 4384 "util/configparser.c" break; case 387: -#line 1609 "./util/configparser.y" +#line 1611 "./util/configparser.y" { OUTYY(("P(server_module_conf:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->module_conf); cfg_parser->cfg->module_conf = (yyvsp[0].str); } -#line 4364 "util/configparser.c" +#line 4394 "util/configparser.c" break; case 388: -#line 1616 "./util/configparser.y" +#line 1618 "./util/configparser.y" { OUTYY(("P(server_val_override_date:%s)\n", (yyvsp[0].str))); if(*(yyvsp[0].str) == '\0' || strcmp((yyvsp[0].str), "0") == 0) { @@ -4381,11 +4411,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 4385 "util/configparser.c" +#line 4415 "util/configparser.c" break; case 389: -#line 1634 "./util/configparser.y" +#line 1636 "./util/configparser.y" { OUTYY(("P(server_val_sig_skew_min:%s)\n", (yyvsp[0].str))); if(*(yyvsp[0].str) == '\0' || strcmp((yyvsp[0].str), "0") == 0) { @@ -4397,11 +4427,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 4401 "util/configparser.c" +#line 4431 "util/configparser.c" break; case 390: -#line 1647 "./util/configparser.y" +#line 1649 "./util/configparser.y" { OUTYY(("P(server_val_sig_skew_max:%s)\n", (yyvsp[0].str))); if(*(yyvsp[0].str) == '\0' || strcmp((yyvsp[0].str), "0") == 0) { @@ -4413,11 +4443,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 4417 "util/configparser.c" +#line 4447 "util/configparser.c" break; case 391: -#line 1660 "./util/configparser.y" +#line 1662 "./util/configparser.y" { OUTYY(("P(server_cache_max_ttl:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4425,11 +4455,11 @@ yyreduce: else cfg_parser->cfg->max_ttl = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4429 "util/configparser.c" +#line 4459 "util/configparser.c" break; case 392: -#line 1669 "./util/configparser.y" +#line 1671 "./util/configparser.y" { OUTYY(("P(server_cache_max_negative_ttl:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4437,11 +4467,11 @@ yyreduce: else cfg_parser->cfg->max_negative_ttl = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4441 "util/configparser.c" +#line 4471 "util/configparser.c" break; case 393: -#line 1678 "./util/configparser.y" +#line 1680 "./util/configparser.y" { OUTYY(("P(server_cache_min_ttl:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4449,11 +4479,11 @@ yyreduce: else cfg_parser->cfg->min_ttl = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4453 "util/configparser.c" +#line 4483 "util/configparser.c" break; case 394: -#line 1687 "./util/configparser.y" +#line 1689 "./util/configparser.y" { OUTYY(("P(server_bogus_ttl:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4461,11 +4491,11 @@ yyreduce: else cfg_parser->cfg->bogus_ttl = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4465 "util/configparser.c" +#line 4495 "util/configparser.c" break; case 395: -#line 1696 "./util/configparser.y" +#line 1698 "./util/configparser.y" { OUTYY(("P(server_val_clean_additional:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4474,11 +4504,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4478 "util/configparser.c" +#line 4508 "util/configparser.c" break; case 396: -#line 1706 "./util/configparser.y" +#line 1708 "./util/configparser.y" { OUTYY(("P(server_val_permissive_mode:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4487,11 +4517,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4491 "util/configparser.c" +#line 4521 "util/configparser.c" break; case 397: -#line 1716 "./util/configparser.y" +#line 1718 "./util/configparser.y" { OUTYY(("P(server_aggressive_nsec:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4501,11 +4531,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4505 "util/configparser.c" +#line 4535 "util/configparser.c" break; case 398: -#line 1727 "./util/configparser.y" +#line 1729 "./util/configparser.y" { OUTYY(("P(server_ignore_cd_flag:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4513,11 +4543,11 @@ yyreduce: else cfg_parser->cfg->ignore_cd = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4517 "util/configparser.c" +#line 4547 "util/configparser.c" break; case 399: -#line 1736 "./util/configparser.y" +#line 1738 "./util/configparser.y" { OUTYY(("P(server_serve_expired:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4525,11 +4555,11 @@ yyreduce: else cfg_parser->cfg->serve_expired = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4529 "util/configparser.c" +#line 4559 "util/configparser.c" break; case 400: -#line 1745 "./util/configparser.y" +#line 1747 "./util/configparser.y" { OUTYY(("P(server_serve_expired_ttl:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4537,11 +4567,11 @@ yyreduce: else cfg_parser->cfg->serve_expired_ttl = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4541 "util/configparser.c" +#line 4571 "util/configparser.c" break; case 401: -#line 1754 "./util/configparser.y" +#line 1756 "./util/configparser.y" { OUTYY(("P(server_serve_expired_ttl_reset:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4549,11 +4579,11 @@ yyreduce: else cfg_parser->cfg->serve_expired_ttl_reset = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4553 "util/configparser.c" +#line 4583 "util/configparser.c" break; case 402: -#line 1763 "./util/configparser.y" +#line 1765 "./util/configparser.y" { OUTYY(("P(server_serve_expired_reply_ttl:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4561,11 +4591,11 @@ yyreduce: else cfg_parser->cfg->serve_expired_reply_ttl = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4565 "util/configparser.c" +#line 4595 "util/configparser.c" break; case 403: -#line 1772 "./util/configparser.y" +#line 1774 "./util/configparser.y" { OUTYY(("P(server_serve_expired_client_timeout:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4573,11 +4603,11 @@ yyreduce: else cfg_parser->cfg->serve_expired_client_timeout = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4577 "util/configparser.c" +#line 4607 "util/configparser.c" break; case 404: -#line 1781 "./util/configparser.y" +#line 1783 "./util/configparser.y" { OUTYY(("P(server_fake_dsa:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4589,11 +4619,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 4593 "util/configparser.c" +#line 4623 "util/configparser.c" break; case 405: -#line 1794 "./util/configparser.y" +#line 1796 "./util/configparser.y" { OUTYY(("P(server_fake_sha1:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4605,11 +4635,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 4609 "util/configparser.c" +#line 4639 "util/configparser.c" break; case 406: -#line 1807 "./util/configparser.y" +#line 1809 "./util/configparser.y" { OUTYY(("P(server_val_log_level:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4617,21 +4647,21 @@ yyreduce: else cfg_parser->cfg->val_log_level = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4621 "util/configparser.c" +#line 4651 "util/configparser.c" break; case 407: -#line 1816 "./util/configparser.y" +#line 1818 "./util/configparser.y" { OUTYY(("P(server_val_nsec3_keysize_iterations:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->val_nsec3_key_iterations); cfg_parser->cfg->val_nsec3_key_iterations = (yyvsp[0].str); } -#line 4631 "util/configparser.c" +#line 4661 "util/configparser.c" break; case 408: -#line 1823 "./util/configparser.y" +#line 1825 "./util/configparser.y" { OUTYY(("P(server_add_holddown:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4639,11 +4669,11 @@ yyreduce: else cfg_parser->cfg->add_holddown = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4643 "util/configparser.c" +#line 4673 "util/configparser.c" break; case 409: -#line 1832 "./util/configparser.y" +#line 1834 "./util/configparser.y" { OUTYY(("P(server_del_holddown:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4651,11 +4681,11 @@ yyreduce: else cfg_parser->cfg->del_holddown = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4655 "util/configparser.c" +#line 4685 "util/configparser.c" break; case 410: -#line 1841 "./util/configparser.y" +#line 1843 "./util/configparser.y" { OUTYY(("P(server_keep_missing:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4663,11 +4693,11 @@ yyreduce: else cfg_parser->cfg->keep_missing = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4667 "util/configparser.c" +#line 4697 "util/configparser.c" break; case 411: -#line 1850 "./util/configparser.y" +#line 1852 "./util/configparser.y" { OUTYY(("P(server_permit_small_holddown:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4676,22 +4706,22 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4680 "util/configparser.c" +#line 4710 "util/configparser.c" break; case 412: -#line 1859 "./util/configparser.y" +#line 1861 "./util/configparser.y" { OUTYY(("P(server_key_cache_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->key_cache_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 4691 "util/configparser.c" +#line 4721 "util/configparser.c" break; case 413: -#line 1867 "./util/configparser.y" +#line 1869 "./util/configparser.y" { OUTYY(("P(server_key_cache_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -4703,22 +4733,22 @@ yyreduce: } free((yyvsp[0].str)); } -#line 4707 "util/configparser.c" +#line 4737 "util/configparser.c" break; case 414: -#line 1880 "./util/configparser.y" +#line 1882 "./util/configparser.y" { OUTYY(("P(server_neg_cache_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->neg_cache_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 4718 "util/configparser.c" +#line 4748 "util/configparser.c" break; case 415: -#line 1888 "./util/configparser.y" +#line 1890 "./util/configparser.y" { OUTYY(("P(server_local_zone:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "static")!=0 && strcmp((yyvsp[0].str), "deny")!=0 && @@ -4758,21 +4788,21 @@ yyreduce: fatal_exit("out of memory adding local-zone"); } } -#line 4762 "util/configparser.c" +#line 4792 "util/configparser.c" break; case 416: -#line 1929 "./util/configparser.y" +#line 1931 "./util/configparser.y" { OUTYY(("P(server_local_data:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->local_data, (yyvsp[0].str))) fatal_exit("out of memory adding local-data"); } -#line 4772 "util/configparser.c" +#line 4802 "util/configparser.c" break; case 417: -#line 1936 "./util/configparser.y" +#line 1938 "./util/configparser.y" { char* ptr; OUTYY(("P(server_local_data_ptr:%s)\n", (yyvsp[0].str))); @@ -4786,11 +4816,11 @@ yyreduce: yyerror("local-data-ptr could not be reversed"); } } -#line 4790 "util/configparser.c" +#line 4820 "util/configparser.c" break; case 418: -#line 1951 "./util/configparser.y" +#line 1953 "./util/configparser.y" { OUTYY(("P(server_minimal_responses:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4799,11 +4829,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4803 "util/configparser.c" +#line 4833 "util/configparser.c" break; case 419: -#line 1961 "./util/configparser.y" +#line 1963 "./util/configparser.y" { OUTYY(("P(server_rrset_roundrobin:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4812,41 +4842,41 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4816 "util/configparser.c" +#line 4846 "util/configparser.c" break; case 420: -#line 1971 "./util/configparser.y" +#line 1973 "./util/configparser.y" { OUTYY(("P(server_unknown_server_time_limit:%s)\n", (yyvsp[0].str))); cfg_parser->cfg->unknown_server_time_limit = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4826 "util/configparser.c" +#line 4856 "util/configparser.c" break; case 421: -#line 1978 "./util/configparser.y" +#line 1980 "./util/configparser.y" { OUTYY(("P(server_max_udp_size:%s)\n", (yyvsp[0].str))); cfg_parser->cfg->max_udp_size = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4836 "util/configparser.c" +#line 4866 "util/configparser.c" break; case 422: -#line 1985 "./util/configparser.y" +#line 1987 "./util/configparser.y" { OUTYY(("P(dns64_prefix:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dns64_prefix); cfg_parser->cfg->dns64_prefix = (yyvsp[0].str); } -#line 4846 "util/configparser.c" +#line 4876 "util/configparser.c" break; case 423: -#line 1992 "./util/configparser.y" +#line 1994 "./util/configparser.y" { OUTYY(("P(server_dns64_synthall:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4854,22 +4884,22 @@ yyreduce: else cfg_parser->cfg->dns64_synthall = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4858 "util/configparser.c" +#line 4888 "util/configparser.c" break; case 424: -#line 2001 "./util/configparser.y" +#line 2003 "./util/configparser.y" { OUTYY(("P(dns64_ignore_aaaa:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->dns64_ignore_aaaa, (yyvsp[0].str))) fatal_exit("out of memory adding dns64-ignore-aaaa"); } -#line 4869 "util/configparser.c" +#line 4899 "util/configparser.c" break; case 425: -#line 2009 "./util/configparser.y" +#line 2011 "./util/configparser.y" { char* p, *s = (yyvsp[0].str); OUTYY(("P(server_define_tag:%s)\n", (yyvsp[0].str))); @@ -4882,11 +4912,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 4886 "util/configparser.c" +#line 4916 "util/configparser.c" break; case 426: -#line 2023 "./util/configparser.y" +#line 2025 "./util/configparser.y" { size_t len = 0; uint8_t* bitlist = config_parse_taglist(cfg_parser->cfg, (yyvsp[0].str), @@ -4906,11 +4936,11 @@ yyreduce: } } } -#line 4910 "util/configparser.c" +#line 4940 "util/configparser.c" break; case 427: -#line 2044 "./util/configparser.y" +#line 2046 "./util/configparser.y" { size_t len = 0; uint8_t* bitlist = config_parse_taglist(cfg_parser->cfg, (yyvsp[0].str), @@ -4930,11 +4960,11 @@ yyreduce: } } } -#line 4934 "util/configparser.c" +#line 4964 "util/configparser.c" break; case 428: -#line 2065 "./util/configparser.y" +#line 2067 "./util/configparser.y" { OUTYY(("P(server_access_control_tag_action:%s %s %s)\n", (yyvsp[-2].str), (yyvsp[-1].str), (yyvsp[0].str))); if(!cfg_str3list_insert(&cfg_parser->cfg->acl_tag_actions, @@ -4945,11 +4975,11 @@ yyreduce: free((yyvsp[0].str)); } } -#line 4949 "util/configparser.c" +#line 4979 "util/configparser.c" break; case 429: -#line 2077 "./util/configparser.y" +#line 2079 "./util/configparser.y" { OUTYY(("P(server_access_control_tag_data:%s %s %s)\n", (yyvsp[-2].str), (yyvsp[-1].str), (yyvsp[0].str))); if(!cfg_str3list_insert(&cfg_parser->cfg->acl_tag_datas, @@ -4960,11 +4990,11 @@ yyreduce: free((yyvsp[0].str)); } } -#line 4964 "util/configparser.c" +#line 4994 "util/configparser.c" break; case 430: -#line 2089 "./util/configparser.y" +#line 2091 "./util/configparser.y" { OUTYY(("P(server_local_zone_override:%s %s %s)\n", (yyvsp[-2].str), (yyvsp[-1].str), (yyvsp[0].str))); if(!cfg_str3list_insert(&cfg_parser->cfg->local_zone_overrides, @@ -4975,11 +5005,11 @@ yyreduce: free((yyvsp[0].str)); } } -#line 4979 "util/configparser.c" +#line 5009 "util/configparser.c" break; case 431: -#line 2101 "./util/configparser.y" +#line 2103 "./util/configparser.y" { OUTYY(("P(server_access_control_view:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); if(!cfg_str2list_insert(&cfg_parser->cfg->acl_view, @@ -4987,11 +5017,11 @@ yyreduce: yyerror("out of memory"); } } -#line 4991 "util/configparser.c" +#line 5021 "util/configparser.c" break; case 432: -#line 2110 "./util/configparser.y" +#line 2112 "./util/configparser.y" { size_t len = 0; uint8_t* bitlist = config_parse_taglist(cfg_parser->cfg, (yyvsp[0].str), @@ -5011,11 +5041,11 @@ yyreduce: } } } -#line 5015 "util/configparser.c" +#line 5045 "util/configparser.c" break; case 433: -#line 2131 "./util/configparser.y" +#line 2133 "./util/configparser.y" { OUTYY(("P(server_ip_ratelimit:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5023,11 +5053,11 @@ yyreduce: else cfg_parser->cfg->ip_ratelimit = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5027 "util/configparser.c" +#line 5057 "util/configparser.c" break; case 434: -#line 2141 "./util/configparser.y" +#line 2143 "./util/configparser.y" { OUTYY(("P(server_ratelimit:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5035,33 +5065,33 @@ yyreduce: else cfg_parser->cfg->ratelimit = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5039 "util/configparser.c" +#line 5069 "util/configparser.c" break; case 435: -#line 2150 "./util/configparser.y" +#line 2152 "./util/configparser.y" { OUTYY(("P(server_ip_ratelimit_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->ip_ratelimit_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 5050 "util/configparser.c" +#line 5080 "util/configparser.c" break; case 436: -#line 2158 "./util/configparser.y" +#line 2160 "./util/configparser.y" { OUTYY(("P(server_ratelimit_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->ratelimit_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 5061 "util/configparser.c" +#line 5091 "util/configparser.c" break; case 437: -#line 2166 "./util/configparser.y" +#line 2168 "./util/configparser.y" { OUTYY(("P(server_ip_ratelimit_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -5073,11 +5103,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 5077 "util/configparser.c" +#line 5107 "util/configparser.c" break; case 438: -#line 2179 "./util/configparser.y" +#line 2181 "./util/configparser.y" { OUTYY(("P(server_ratelimit_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -5089,11 +5119,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 5093 "util/configparser.c" +#line 5123 "util/configparser.c" break; case 439: -#line 2192 "./util/configparser.y" +#line 2194 "./util/configparser.y" { OUTYY(("P(server_ratelimit_for_domain:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) { @@ -5107,11 +5137,11 @@ yyreduce: "ratelimit-for-domain"); } } -#line 5111 "util/configparser.c" +#line 5141 "util/configparser.c" break; case 440: -#line 2207 "./util/configparser.y" +#line 2209 "./util/configparser.y" { OUTYY(("P(server_ratelimit_below_domain:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) { @@ -5125,11 +5155,11 @@ yyreduce: "ratelimit-below-domain"); } } -#line 5129 "util/configparser.c" +#line 5159 "util/configparser.c" break; case 441: -#line 2222 "./util/configparser.y" +#line 2224 "./util/configparser.y" { OUTYY(("P(server_ip_ratelimit_factor:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5137,11 +5167,11 @@ yyreduce: else cfg_parser->cfg->ip_ratelimit_factor = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5141 "util/configparser.c" +#line 5171 "util/configparser.c" break; case 442: -#line 2231 "./util/configparser.y" +#line 2233 "./util/configparser.y" { OUTYY(("P(server_ratelimit_factor:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5149,20 +5179,20 @@ yyreduce: else cfg_parser->cfg->ratelimit_factor = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5153 "util/configparser.c" +#line 5183 "util/configparser.c" break; case 443: -#line 2240 "./util/configparser.y" +#line 2242 "./util/configparser.y" { OUTYY(("P(low-rtt option is deprecated, use fast-server-num instead)\n")); free((yyvsp[0].str)); } -#line 5162 "util/configparser.c" +#line 5192 "util/configparser.c" break; case 444: -#line 2246 "./util/configparser.y" +#line 2248 "./util/configparser.y" { OUTYY(("P(server_fast_server_num:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) <= 0) @@ -5170,11 +5200,11 @@ yyreduce: else cfg_parser->cfg->fast_server_num = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5174 "util/configparser.c" +#line 5204 "util/configparser.c" break; case 445: -#line 2255 "./util/configparser.y" +#line 2257 "./util/configparser.y" { OUTYY(("P(server_fast_server_permil:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5182,11 +5212,11 @@ yyreduce: else cfg_parser->cfg->fast_server_permil = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5186 "util/configparser.c" +#line 5216 "util/configparser.c" break; case 446: -#line 2264 "./util/configparser.y" +#line 2266 "./util/configparser.y" { OUTYY(("P(server_qname_minimisation:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5195,11 +5225,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5199 "util/configparser.c" +#line 5229 "util/configparser.c" break; case 447: -#line 2274 "./util/configparser.y" +#line 2276 "./util/configparser.y" { OUTYY(("P(server_qname_minimisation_strict:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5208,11 +5238,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5212 "util/configparser.c" +#line 5242 "util/configparser.c" break; case 448: -#line 2284 "./util/configparser.y" +#line 2286 "./util/configparser.y" { #ifdef USE_IPSECMOD OUTYY(("P(server_ipsecmod_enabled:%s)\n", (yyvsp[0].str))); @@ -5224,11 +5254,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 5228 "util/configparser.c" +#line 5258 "util/configparser.c" break; case 449: -#line 2297 "./util/configparser.y" +#line 2299 "./util/configparser.y" { #ifdef USE_IPSECMOD OUTYY(("P(server_ipsecmod_ignore_bogus:%s)\n", (yyvsp[0].str))); @@ -5240,11 +5270,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 5244 "util/configparser.c" +#line 5274 "util/configparser.c" break; case 450: -#line 2310 "./util/configparser.y" +#line 2312 "./util/configparser.y" { #ifdef USE_IPSECMOD OUTYY(("P(server_ipsecmod_hook:%s)\n", (yyvsp[0].str))); @@ -5255,11 +5285,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 5259 "util/configparser.c" +#line 5289 "util/configparser.c" break; case 451: -#line 2322 "./util/configparser.y" +#line 2324 "./util/configparser.y" { #ifdef USE_IPSECMOD OUTYY(("P(server_ipsecmod_max_ttl:%s)\n", (yyvsp[0].str))); @@ -5272,11 +5302,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 5276 "util/configparser.c" +#line 5306 "util/configparser.c" break; case 452: -#line 2336 "./util/configparser.y" +#line 2338 "./util/configparser.y" { #ifdef USE_IPSECMOD OUTYY(("P(server_ipsecmod_whitelist:%s)\n", (yyvsp[0].str))); @@ -5287,11 +5317,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 5291 "util/configparser.c" +#line 5321 "util/configparser.c" break; case 453: -#line 2348 "./util/configparser.y" +#line 2350 "./util/configparser.y" { #ifdef USE_IPSECMOD OUTYY(("P(server_ipsecmod_strict:%s)\n", (yyvsp[0].str))); @@ -5304,11 +5334,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 5308 "util/configparser.c" +#line 5338 "util/configparser.c" break; case 454: -#line 2362 "./util/configparser.y" +#line 2364 "./util/configparser.y" { OUTYY(("P(name:%s)\n", (yyvsp[0].str))); if(cfg_parser->cfg->stubs->name) @@ -5317,31 +5347,31 @@ yyreduce: free(cfg_parser->cfg->stubs->name); cfg_parser->cfg->stubs->name = (yyvsp[0].str); } -#line 5321 "util/configparser.c" +#line 5351 "util/configparser.c" break; case 455: -#line 2372 "./util/configparser.y" +#line 2374 "./util/configparser.y" { OUTYY(("P(stub-host:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->hosts, (yyvsp[0].str))) yyerror("out of memory"); } -#line 5331 "util/configparser.c" +#line 5361 "util/configparser.c" break; case 456: -#line 2379 "./util/configparser.y" +#line 2381 "./util/configparser.y" { OUTYY(("P(stub-addr:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->addrs, (yyvsp[0].str))) yyerror("out of memory"); } -#line 5341 "util/configparser.c" +#line 5371 "util/configparser.c" break; case 457: -#line 2386 "./util/configparser.y" +#line 2388 "./util/configparser.y" { OUTYY(("P(stub-first:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5349,11 +5379,11 @@ yyreduce: else cfg_parser->cfg->stubs->isfirst=(strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5353 "util/configparser.c" +#line 5383 "util/configparser.c" break; case 458: -#line 2395 "./util/configparser.y" +#line 2397 "./util/configparser.y" { OUTYY(("P(stub-no-cache:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5361,11 +5391,11 @@ yyreduce: else cfg_parser->cfg->stubs->no_cache=(strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5365 "util/configparser.c" +#line 5395 "util/configparser.c" break; case 459: -#line 2404 "./util/configparser.y" +#line 2406 "./util/configparser.y" { OUTYY(("P(stub-ssl-upstream:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5374,11 +5404,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5378 "util/configparser.c" +#line 5408 "util/configparser.c" break; case 460: -#line 2414 "./util/configparser.y" +#line 2416 "./util/configparser.y" { OUTYY(("P(stub-prime:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5387,11 +5417,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5391 "util/configparser.c" +#line 5421 "util/configparser.c" break; case 461: -#line 2424 "./util/configparser.y" +#line 2426 "./util/configparser.y" { OUTYY(("P(name:%s)\n", (yyvsp[0].str))); if(cfg_parser->cfg->forwards->name) @@ -5400,31 +5430,31 @@ yyreduce: free(cfg_parser->cfg->forwards->name); cfg_parser->cfg->forwards->name = (yyvsp[0].str); } -#line 5404 "util/configparser.c" +#line 5434 "util/configparser.c" break; case 462: -#line 2434 "./util/configparser.y" +#line 2436 "./util/configparser.y" { OUTYY(("P(forward-host:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->hosts, (yyvsp[0].str))) yyerror("out of memory"); } -#line 5414 "util/configparser.c" +#line 5444 "util/configparser.c" break; case 463: -#line 2441 "./util/configparser.y" +#line 2443 "./util/configparser.y" { OUTYY(("P(forward-addr:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->addrs, (yyvsp[0].str))) yyerror("out of memory"); } -#line 5424 "util/configparser.c" +#line 5454 "util/configparser.c" break; case 464: -#line 2448 "./util/configparser.y" +#line 2450 "./util/configparser.y" { OUTYY(("P(forward-first:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5432,11 +5462,11 @@ yyreduce: else cfg_parser->cfg->forwards->isfirst=(strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5436 "util/configparser.c" +#line 5466 "util/configparser.c" break; case 465: -#line 2457 "./util/configparser.y" +#line 2459 "./util/configparser.y" { OUTYY(("P(forward-no-cache:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5444,11 +5474,11 @@ yyreduce: else cfg_parser->cfg->forwards->no_cache=(strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5448 "util/configparser.c" +#line 5478 "util/configparser.c" break; case 466: -#line 2466 "./util/configparser.y" +#line 2468 "./util/configparser.y" { OUTYY(("P(forward-ssl-upstream:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5457,11 +5487,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5461 "util/configparser.c" +#line 5491 "util/configparser.c" break; case 467: -#line 2476 "./util/configparser.y" +#line 2478 "./util/configparser.y" { OUTYY(("P(name:%s)\n", (yyvsp[0].str))); if(cfg_parser->cfg->auths->name) @@ -5470,52 +5500,52 @@ yyreduce: free(cfg_parser->cfg->auths->name); cfg_parser->cfg->auths->name = (yyvsp[0].str); } -#line 5474 "util/configparser.c" +#line 5504 "util/configparser.c" break; case 468: -#line 2486 "./util/configparser.y" +#line 2488 "./util/configparser.y" { OUTYY(("P(zonefile:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->auths->zonefile); cfg_parser->cfg->auths->zonefile = (yyvsp[0].str); } -#line 5484 "util/configparser.c" +#line 5514 "util/configparser.c" break; case 469: -#line 2493 "./util/configparser.y" +#line 2495 "./util/configparser.y" { OUTYY(("P(master:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->auths->masters, (yyvsp[0].str))) yyerror("out of memory"); } -#line 5494 "util/configparser.c" +#line 5524 "util/configparser.c" break; case 470: -#line 2500 "./util/configparser.y" +#line 2502 "./util/configparser.y" { OUTYY(("P(url:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->auths->urls, (yyvsp[0].str))) yyerror("out of memory"); } -#line 5504 "util/configparser.c" +#line 5534 "util/configparser.c" break; case 471: -#line 2507 "./util/configparser.y" +#line 2509 "./util/configparser.y" { OUTYY(("P(allow-notify:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->auths->allow_notify, (yyvsp[0].str))) yyerror("out of memory"); } -#line 5515 "util/configparser.c" +#line 5545 "util/configparser.c" break; case 472: -#line 2515 "./util/configparser.y" +#line 2517 "./util/configparser.y" { OUTYY(("P(for-downstream:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5524,11 +5554,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5528 "util/configparser.c" +#line 5558 "util/configparser.c" break; case 473: -#line 2525 "./util/configparser.y" +#line 2527 "./util/configparser.y" { OUTYY(("P(for-upstream:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5537,11 +5567,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5541 "util/configparser.c" +#line 5571 "util/configparser.c" break; case 474: -#line 2535 "./util/configparser.y" +#line 2537 "./util/configparser.y" { OUTYY(("P(fallback-enabled:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5550,11 +5580,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5554 "util/configparser.c" +#line 5584 "util/configparser.c" break; case 475: -#line 2545 "./util/configparser.y" +#line 2547 "./util/configparser.y" { OUTYY(("P(name:%s)\n", (yyvsp[0].str))); if(cfg_parser->cfg->views->name) @@ -5563,11 +5593,11 @@ yyreduce: free(cfg_parser->cfg->views->name); cfg_parser->cfg->views->name = (yyvsp[0].str); } -#line 5567 "util/configparser.c" +#line 5597 "util/configparser.c" break; case 476: -#line 2555 "./util/configparser.y" +#line 2557 "./util/configparser.y" { OUTYY(("P(view_local_zone:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "static")!=0 && strcmp((yyvsp[0].str), "deny")!=0 && @@ -5605,11 +5635,11 @@ yyreduce: fatal_exit("out of memory adding local-zone"); } } -#line 5609 "util/configparser.c" +#line 5639 "util/configparser.c" break; case 477: -#line 2594 "./util/configparser.y" +#line 2596 "./util/configparser.y" { OUTYY(("P(view_response_ip:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); validate_respip_action((yyvsp[0].str)); @@ -5618,33 +5648,33 @@ yyreduce: fatal_exit("out of memory adding per-view " "response-ip action"); } -#line 5622 "util/configparser.c" +#line 5652 "util/configparser.c" break; case 478: -#line 2604 "./util/configparser.y" +#line 2606 "./util/configparser.y" { OUTYY(("P(view_response_ip_data:%s)\n", (yyvsp[-1].str))); if(!cfg_str2list_insert( &cfg_parser->cfg->views->respip_data, (yyvsp[-1].str), (yyvsp[0].str))) fatal_exit("out of memory adding response-ip-data"); } -#line 5633 "util/configparser.c" +#line 5663 "util/configparser.c" break; case 479: -#line 2612 "./util/configparser.y" +#line 2614 "./util/configparser.y" { OUTYY(("P(view_local_data:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->views->local_data, (yyvsp[0].str))) { fatal_exit("out of memory adding local-data"); } } -#line 5644 "util/configparser.c" +#line 5674 "util/configparser.c" break; case 480: -#line 2620 "./util/configparser.y" +#line 2622 "./util/configparser.y" { char* ptr; OUTYY(("P(view_local_data_ptr:%s)\n", (yyvsp[0].str))); @@ -5658,11 +5688,11 @@ yyreduce: yyerror("local-data-ptr could not be reversed"); } } -#line 5662 "util/configparser.c" +#line 5692 "util/configparser.c" break; case 481: -#line 2635 "./util/configparser.y" +#line 2637 "./util/configparser.y" { OUTYY(("P(view-first:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5670,19 +5700,19 @@ yyreduce: else cfg_parser->cfg->views->isfirst=(strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5674 "util/configparser.c" +#line 5704 "util/configparser.c" break; case 482: -#line 2644 "./util/configparser.y" +#line 2646 "./util/configparser.y" { OUTYY(("\nP(remote-control:)\n")); } -#line 5682 "util/configparser.c" +#line 5712 "util/configparser.c" break; case 493: -#line 2655 "./util/configparser.y" +#line 2657 "./util/configparser.y" { OUTYY(("P(control_enable:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5691,11 +5721,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5695 "util/configparser.c" +#line 5725 "util/configparser.c" break; case 494: -#line 2665 "./util/configparser.y" +#line 2667 "./util/configparser.y" { OUTYY(("P(control_port:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -5703,79 +5733,79 @@ yyreduce: else cfg_parser->cfg->control_port = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5707 "util/configparser.c" +#line 5737 "util/configparser.c" break; case 495: -#line 2674 "./util/configparser.y" +#line 2676 "./util/configparser.y" { OUTYY(("P(control_interface:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_append(&cfg_parser->cfg->control_ifs, (yyvsp[0].str))) yyerror("out of memory"); } -#line 5717 "util/configparser.c" +#line 5747 "util/configparser.c" break; case 496: -#line 2681 "./util/configparser.y" +#line 2683 "./util/configparser.y" { OUTYY(("P(control_use_cert:%s)\n", (yyvsp[0].str))); cfg_parser->cfg->control_use_cert = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5727 "util/configparser.c" +#line 5757 "util/configparser.c" break; case 497: -#line 2688 "./util/configparser.y" +#line 2690 "./util/configparser.y" { OUTYY(("P(rc_server_key_file:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->server_key_file); cfg_parser->cfg->server_key_file = (yyvsp[0].str); } -#line 5737 "util/configparser.c" +#line 5767 "util/configparser.c" break; case 498: -#line 2695 "./util/configparser.y" +#line 2697 "./util/configparser.y" { OUTYY(("P(rc_server_cert_file:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->server_cert_file); cfg_parser->cfg->server_cert_file = (yyvsp[0].str); } -#line 5747 "util/configparser.c" +#line 5777 "util/configparser.c" break; case 499: -#line 2702 "./util/configparser.y" +#line 2704 "./util/configparser.y" { OUTYY(("P(rc_control_key_file:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->control_key_file); cfg_parser->cfg->control_key_file = (yyvsp[0].str); } -#line 5757 "util/configparser.c" +#line 5787 "util/configparser.c" break; case 500: -#line 2709 "./util/configparser.y" +#line 2711 "./util/configparser.y" { OUTYY(("P(rc_control_cert_file:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->control_cert_file); cfg_parser->cfg->control_cert_file = (yyvsp[0].str); } -#line 5767 "util/configparser.c" +#line 5797 "util/configparser.c" break; case 501: -#line 2716 "./util/configparser.y" +#line 2718 "./util/configparser.y" { OUTYY(("\nP(dnstap:)\n")); } -#line 5775 "util/configparser.c" +#line 5805 "util/configparser.c" break; - case 516: -#line 2733 "./util/configparser.y" + case 522: +#line 2738 "./util/configparser.y" { OUTYY(("P(dt_dnstap_enable:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5783,21 +5813,83 @@ yyreduce: else cfg_parser->cfg->dnstap = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5787 "util/configparser.c" +#line 5817 "util/configparser.c" break; - case 517: -#line 2742 "./util/configparser.y" + case 523: +#line 2747 "./util/configparser.y" { OUTYY(("P(dt_dnstap_socket_path:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dnstap_socket_path); cfg_parser->cfg->dnstap_socket_path = (yyvsp[0].str); } -#line 5797 "util/configparser.c" +#line 5827 "util/configparser.c" break; - case 518: -#line 2749 "./util/configparser.y" + case 524: +#line 2754 "./util/configparser.y" + { + OUTYY(("P(dt_dnstap_ip:%s)\n", (yyvsp[0].str))); + free(cfg_parser->cfg->dnstap_ip); + cfg_parser->cfg->dnstap_ip = (yyvsp[0].str); + } +#line 5837 "util/configparser.c" + break; + + case 525: +#line 2761 "./util/configparser.y" + { + OUTYY(("P(dt_dnstap_tls:%s)\n", (yyvsp[0].str))); + if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->dnstap_tls = (strcmp((yyvsp[0].str), "yes")==0); + free((yyvsp[0].str)); + } +#line 5849 "util/configparser.c" + break; + + case 526: +#line 2770 "./util/configparser.y" + { + OUTYY(("P(dt_dnstap_tls_server_name:%s)\n", (yyvsp[0].str))); + free(cfg_parser->cfg->dnstap_tls_server_name); + cfg_parser->cfg->dnstap_tls_server_name = (yyvsp[0].str); + } +#line 5859 "util/configparser.c" + break; + + case 527: +#line 2777 "./util/configparser.y" + { + OUTYY(("P(dt_dnstap_tls_cert_bundle:%s)\n", (yyvsp[0].str))); + free(cfg_parser->cfg->dnstap_tls_cert_bundle); + cfg_parser->cfg->dnstap_tls_cert_bundle = (yyvsp[0].str); + } +#line 5869 "util/configparser.c" + break; + + case 528: +#line 2784 "./util/configparser.y" + { + OUTYY(("P(dt_dnstap_tls_client_key_file:%s)\n", (yyvsp[0].str))); + free(cfg_parser->cfg->dnstap_tls_client_key_file); + cfg_parser->cfg->dnstap_tls_client_key_file = (yyvsp[0].str); + } +#line 5879 "util/configparser.c" + break; + + case 529: +#line 2791 "./util/configparser.y" + { + OUTYY(("P(dt_dnstap_tls_client_cert_file:%s)\n", (yyvsp[0].str))); + free(cfg_parser->cfg->dnstap_tls_client_cert_file); + cfg_parser->cfg->dnstap_tls_client_cert_file = (yyvsp[0].str); + } +#line 5889 "util/configparser.c" + break; + + case 530: +#line 2798 "./util/configparser.y" { OUTYY(("P(dt_dnstap_send_identity:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5805,11 +5897,11 @@ yyreduce: else cfg_parser->cfg->dnstap_send_identity = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5809 "util/configparser.c" +#line 5901 "util/configparser.c" break; - case 519: -#line 2758 "./util/configparser.y" + case 531: +#line 2807 "./util/configparser.y" { OUTYY(("P(dt_dnstap_send_version:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5817,31 +5909,31 @@ yyreduce: else cfg_parser->cfg->dnstap_send_version = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5821 "util/configparser.c" +#line 5913 "util/configparser.c" break; - case 520: -#line 2767 "./util/configparser.y" + case 532: +#line 2816 "./util/configparser.y" { OUTYY(("P(dt_dnstap_identity:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dnstap_identity); cfg_parser->cfg->dnstap_identity = (yyvsp[0].str); } -#line 5831 "util/configparser.c" +#line 5923 "util/configparser.c" break; - case 521: -#line 2774 "./util/configparser.y" + case 533: +#line 2823 "./util/configparser.y" { OUTYY(("P(dt_dnstap_version:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dnstap_version); cfg_parser->cfg->dnstap_version = (yyvsp[0].str); } -#line 5841 "util/configparser.c" +#line 5933 "util/configparser.c" break; - case 522: -#line 2781 "./util/configparser.y" + case 534: +#line 2830 "./util/configparser.y" { OUTYY(("P(dt_dnstap_log_resolver_query_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5850,11 +5942,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5854 "util/configparser.c" +#line 5946 "util/configparser.c" break; - case 523: -#line 2791 "./util/configparser.y" + case 535: +#line 2840 "./util/configparser.y" { OUTYY(("P(dt_dnstap_log_resolver_response_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5863,11 +5955,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5867 "util/configparser.c" +#line 5959 "util/configparser.c" break; - case 524: -#line 2801 "./util/configparser.y" + case 536: +#line 2850 "./util/configparser.y" { OUTYY(("P(dt_dnstap_log_client_query_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5876,11 +5968,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5880 "util/configparser.c" +#line 5972 "util/configparser.c" break; - case 525: -#line 2811 "./util/configparser.y" + case 537: +#line 2860 "./util/configparser.y" { OUTYY(("P(dt_dnstap_log_client_response_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5889,11 +5981,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5893 "util/configparser.c" +#line 5985 "util/configparser.c" break; - case 526: -#line 2821 "./util/configparser.y" + case 538: +#line 2870 "./util/configparser.y" { OUTYY(("P(dt_dnstap_log_forwarder_query_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5902,11 +5994,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5906 "util/configparser.c" +#line 5998 "util/configparser.c" break; - case 527: -#line 2831 "./util/configparser.y" + case 539: +#line 2880 "./util/configparser.y" { OUTYY(("P(dt_dnstap_log_forwarder_response_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5915,29 +6007,29 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5919 "util/configparser.c" +#line 6011 "util/configparser.c" break; - case 528: -#line 2841 "./util/configparser.y" + case 540: +#line 2890 "./util/configparser.y" { OUTYY(("\nP(python:)\n")); } -#line 5927 "util/configparser.c" +#line 6019 "util/configparser.c" break; - case 532: -#line 2850 "./util/configparser.y" + case 544: +#line 2899 "./util/configparser.y" { OUTYY(("P(python-script:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_append_ex(&cfg_parser->cfg->python_script, (yyvsp[0].str))) yyerror("out of memory"); } -#line 5937 "util/configparser.c" +#line 6029 "util/configparser.c" break; - case 533: -#line 2856 "./util/configparser.y" + case 545: +#line 2905 "./util/configparser.y" { OUTYY(("P(disable_dnssec_lame_check:%s)\n", (yyvsp[0].str))); if (strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5946,21 +6038,21 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5950 "util/configparser.c" +#line 6042 "util/configparser.c" break; - case 534: -#line 2866 "./util/configparser.y" + case 546: +#line 2915 "./util/configparser.y" { OUTYY(("P(server_log_identity:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->log_identity); cfg_parser->cfg->log_identity = (yyvsp[0].str); } -#line 5960 "util/configparser.c" +#line 6052 "util/configparser.c" break; - case 535: -#line 2873 "./util/configparser.y" + case 547: +#line 2922 "./util/configparser.y" { OUTYY(("P(server_response_ip:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); validate_respip_action((yyvsp[0].str)); @@ -5968,30 +6060,30 @@ yyreduce: (yyvsp[-1].str), (yyvsp[0].str))) fatal_exit("out of memory adding response-ip"); } -#line 5972 "util/configparser.c" +#line 6064 "util/configparser.c" break; - case 536: -#line 2882 "./util/configparser.y" + case 548: +#line 2931 "./util/configparser.y" { OUTYY(("P(server_response_ip_data:%s)\n", (yyvsp[-1].str))); if(!cfg_str2list_insert(&cfg_parser->cfg->respip_data, (yyvsp[-1].str), (yyvsp[0].str))) fatal_exit("out of memory adding response-ip-data"); } -#line 5983 "util/configparser.c" +#line 6075 "util/configparser.c" break; - case 537: -#line 2890 "./util/configparser.y" + case 549: +#line 2939 "./util/configparser.y" { OUTYY(("\nP(dnscrypt:)\n")); } -#line 5991 "util/configparser.c" +#line 6083 "util/configparser.c" break; - case 550: -#line 2906 "./util/configparser.y" + case 562: +#line 2955 "./util/configparser.y" { OUTYY(("P(dnsc_dnscrypt_enable:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5999,11 +6091,11 @@ yyreduce: else cfg_parser->cfg->dnscrypt = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6003 "util/configparser.c" +#line 6095 "util/configparser.c" break; - case 551: -#line 2916 "./util/configparser.y" + case 563: +#line 2965 "./util/configparser.y" { OUTYY(("P(dnsc_dnscrypt_port:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -6011,21 +6103,21 @@ yyreduce: else cfg_parser->cfg->dnscrypt_port = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 6015 "util/configparser.c" +#line 6107 "util/configparser.c" break; - case 552: -#line 2925 "./util/configparser.y" + case 564: +#line 2974 "./util/configparser.y" { OUTYY(("P(dnsc_dnscrypt_provider:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dnscrypt_provider); cfg_parser->cfg->dnscrypt_provider = (yyvsp[0].str); } -#line 6025 "util/configparser.c" +#line 6117 "util/configparser.c" break; - case 553: -#line 2932 "./util/configparser.y" + case 565: +#line 2981 "./util/configparser.y" { OUTYY(("P(dnsc_dnscrypt_provider_cert:%s)\n", (yyvsp[0].str))); if(cfg_strlist_find(cfg_parser->cfg->dnscrypt_provider_cert, (yyvsp[0].str))) @@ -6033,21 +6125,21 @@ yyreduce: if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_provider_cert, (yyvsp[0].str))) fatal_exit("out of memory adding dnscrypt-provider-cert"); } -#line 6037 "util/configparser.c" +#line 6129 "util/configparser.c" break; - case 554: -#line 2941 "./util/configparser.y" + case 566: +#line 2990 "./util/configparser.y" { OUTYY(("P(dnsc_dnscrypt_provider_cert_rotated:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_provider_cert_rotated, (yyvsp[0].str))) fatal_exit("out of memory adding dnscrypt-provider-cert-rotated"); } -#line 6047 "util/configparser.c" +#line 6139 "util/configparser.c" break; - case 555: -#line 2948 "./util/configparser.y" + case 567: +#line 2997 "./util/configparser.y" { OUTYY(("P(dnsc_dnscrypt_secret_key:%s)\n", (yyvsp[0].str))); if(cfg_strlist_find(cfg_parser->cfg->dnscrypt_secret_key, (yyvsp[0].str))) @@ -6055,22 +6147,22 @@ yyreduce: if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_secret_key, (yyvsp[0].str))) fatal_exit("out of memory adding dnscrypt-secret-key"); } -#line 6059 "util/configparser.c" +#line 6151 "util/configparser.c" break; - case 556: -#line 2957 "./util/configparser.y" + case 568: +#line 3006 "./util/configparser.y" { OUTYY(("P(dnscrypt_shared_secret_cache_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->dnscrypt_shared_secret_cache_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 6070 "util/configparser.c" +#line 6162 "util/configparser.c" break; - case 557: -#line 2965 "./util/configparser.y" + case 569: +#line 3014 "./util/configparser.y" { OUTYY(("P(dnscrypt_shared_secret_cache_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -6082,22 +6174,22 @@ yyreduce: } free((yyvsp[0].str)); } -#line 6086 "util/configparser.c" +#line 6178 "util/configparser.c" break; - case 558: -#line 2978 "./util/configparser.y" + case 570: +#line 3027 "./util/configparser.y" { OUTYY(("P(dnscrypt_nonce_cache_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->dnscrypt_nonce_cache_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 6097 "util/configparser.c" +#line 6189 "util/configparser.c" break; - case 559: -#line 2986 "./util/configparser.y" + case 571: +#line 3035 "./util/configparser.y" { OUTYY(("P(dnscrypt_nonce_cache_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -6109,19 +6201,19 @@ yyreduce: } free((yyvsp[0].str)); } -#line 6113 "util/configparser.c" +#line 6205 "util/configparser.c" break; - case 560: -#line 2999 "./util/configparser.y" + case 572: +#line 3048 "./util/configparser.y" { OUTYY(("\nP(cachedb:)\n")); } -#line 6121 "util/configparser.c" +#line 6213 "util/configparser.c" break; - case 568: -#line 3009 "./util/configparser.y" + case 580: +#line 3058 "./util/configparser.y" { #ifdef USE_CACHEDB OUTYY(("P(backend:%s)\n", (yyvsp[0].str))); @@ -6132,11 +6224,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 6136 "util/configparser.c" +#line 6228 "util/configparser.c" break; - case 569: -#line 3021 "./util/configparser.y" + case 581: +#line 3070 "./util/configparser.y" { #ifdef USE_CACHEDB OUTYY(("P(secret-seed:%s)\n", (yyvsp[0].str))); @@ -6147,11 +6239,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 6151 "util/configparser.c" +#line 6243 "util/configparser.c" break; - case 570: -#line 3033 "./util/configparser.y" + case 582: +#line 3082 "./util/configparser.y" { #if defined(USE_CACHEDB) && defined(USE_REDIS) OUTYY(("P(redis_server_host:%s)\n", (yyvsp[0].str))); @@ -6162,11 +6254,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 6166 "util/configparser.c" +#line 6258 "util/configparser.c" break; - case 571: -#line 3045 "./util/configparser.y" + case 583: +#line 3094 "./util/configparser.y" { #if defined(USE_CACHEDB) && defined(USE_REDIS) int port; @@ -6180,11 +6272,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 6184 "util/configparser.c" +#line 6276 "util/configparser.c" break; - case 572: -#line 3060 "./util/configparser.y" + case 584: +#line 3109 "./util/configparser.y" { #if defined(USE_CACHEDB) && defined(USE_REDIS) OUTYY(("P(redis_timeout:%s)\n", (yyvsp[0].str))); @@ -6196,11 +6288,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 6200 "util/configparser.c" +#line 6292 "util/configparser.c" break; - case 573: -#line 3073 "./util/configparser.y" + case 585: +#line 3122 "./util/configparser.y" { OUTYY(("P(server_tcp_connection_limit:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); if (atoi((yyvsp[0].str)) < 0) @@ -6210,19 +6302,19 @@ yyreduce: fatal_exit("out of memory adding tcp connection limit"); } } -#line 6214 "util/configparser.c" +#line 6306 "util/configparser.c" break; - case 574: -#line 3084 "./util/configparser.y" + case 586: +#line 3133 "./util/configparser.y" { OUTYY(("\nP(ipset:)\n")); } -#line 6222 "util/configparser.c" +#line 6314 "util/configparser.c" break; - case 579: -#line 3093 "./util/configparser.y" + case 591: +#line 3142 "./util/configparser.y" { #ifdef USE_IPSET OUTYY(("P(name-v4:%s)\n", (yyvsp[0].str))); @@ -6236,11 +6328,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 6240 "util/configparser.c" +#line 6332 "util/configparser.c" break; - case 580: -#line 3108 "./util/configparser.y" + case 592: +#line 3157 "./util/configparser.y" { #ifdef USE_IPSET OUTYY(("P(name-v6:%s)\n", (yyvsp[0].str))); @@ -6254,11 +6346,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 6258 "util/configparser.c" +#line 6350 "util/configparser.c" break; -#line 6262 "util/configparser.c" +#line 6354 "util/configparser.c" default: break; } @@ -6490,7 +6582,7 @@ yyreturn: #endif return yyresult; } -#line 3122 "./util/configparser.y" +#line 3171 "./util/configparser.y" /* parse helper routines could be here */ diff --git a/util/configparser.h b/util/configparser.h index 4d7e6b12f..42a66bac8 100644 --- a/util/configparser.h +++ b/util/configparser.h @@ -200,130 +200,136 @@ extern int yydebug; VAR_DNSTAP = 406, VAR_DNSTAP_ENABLE = 407, VAR_DNSTAP_SOCKET_PATH = 408, - VAR_DNSTAP_SEND_IDENTITY = 409, - VAR_DNSTAP_SEND_VERSION = 410, - VAR_DNSTAP_IDENTITY = 411, - VAR_DNSTAP_VERSION = 412, - VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES = 413, - VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES = 414, - VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES = 415, - VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES = 416, - VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES = 417, - VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES = 418, - VAR_RESPONSE_IP_TAG = 419, - VAR_RESPONSE_IP = 420, - VAR_RESPONSE_IP_DATA = 421, - VAR_HARDEN_ALGO_DOWNGRADE = 422, - VAR_IP_TRANSPARENT = 423, - VAR_DISABLE_DNSSEC_LAME_CHECK = 424, - VAR_IP_RATELIMIT = 425, - VAR_IP_RATELIMIT_SLABS = 426, - VAR_IP_RATELIMIT_SIZE = 427, - VAR_RATELIMIT = 428, - VAR_RATELIMIT_SLABS = 429, - VAR_RATELIMIT_SIZE = 430, - VAR_RATELIMIT_FOR_DOMAIN = 431, - VAR_RATELIMIT_BELOW_DOMAIN = 432, - VAR_IP_RATELIMIT_FACTOR = 433, - VAR_RATELIMIT_FACTOR = 434, - VAR_SEND_CLIENT_SUBNET = 435, - VAR_CLIENT_SUBNET_ZONE = 436, - VAR_CLIENT_SUBNET_ALWAYS_FORWARD = 437, - VAR_CLIENT_SUBNET_OPCODE = 438, - VAR_MAX_CLIENT_SUBNET_IPV4 = 439, - VAR_MAX_CLIENT_SUBNET_IPV6 = 440, - VAR_MIN_CLIENT_SUBNET_IPV4 = 441, - VAR_MIN_CLIENT_SUBNET_IPV6 = 442, - VAR_MAX_ECS_TREE_SIZE_IPV4 = 443, - VAR_MAX_ECS_TREE_SIZE_IPV6 = 444, - VAR_CAPS_WHITELIST = 445, - VAR_CACHE_MAX_NEGATIVE_TTL = 446, - VAR_PERMIT_SMALL_HOLDDOWN = 447, - VAR_QNAME_MINIMISATION = 448, - VAR_QNAME_MINIMISATION_STRICT = 449, - VAR_IP_FREEBIND = 450, - VAR_DEFINE_TAG = 451, - VAR_LOCAL_ZONE_TAG = 452, - VAR_ACCESS_CONTROL_TAG = 453, - VAR_LOCAL_ZONE_OVERRIDE = 454, - VAR_ACCESS_CONTROL_TAG_ACTION = 455, - VAR_ACCESS_CONTROL_TAG_DATA = 456, - VAR_VIEW = 457, - VAR_ACCESS_CONTROL_VIEW = 458, - VAR_VIEW_FIRST = 459, - VAR_SERVE_EXPIRED = 460, - VAR_SERVE_EXPIRED_TTL = 461, - VAR_SERVE_EXPIRED_TTL_RESET = 462, - VAR_SERVE_EXPIRED_REPLY_TTL = 463, - VAR_SERVE_EXPIRED_CLIENT_TIMEOUT = 464, - VAR_FAKE_DSA = 465, - VAR_FAKE_SHA1 = 466, - VAR_LOG_IDENTITY = 467, - VAR_HIDE_TRUSTANCHOR = 468, - VAR_TRUST_ANCHOR_SIGNALING = 469, - VAR_AGGRESSIVE_NSEC = 470, - VAR_USE_SYSTEMD = 471, - VAR_SHM_ENABLE = 472, - VAR_SHM_KEY = 473, - VAR_ROOT_KEY_SENTINEL = 474, - VAR_DNSCRYPT = 475, - VAR_DNSCRYPT_ENABLE = 476, - VAR_DNSCRYPT_PORT = 477, - VAR_DNSCRYPT_PROVIDER = 478, - VAR_DNSCRYPT_SECRET_KEY = 479, - VAR_DNSCRYPT_PROVIDER_CERT = 480, - VAR_DNSCRYPT_PROVIDER_CERT_ROTATED = 481, - VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE = 482, - VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS = 483, - VAR_DNSCRYPT_NONCE_CACHE_SIZE = 484, - VAR_DNSCRYPT_NONCE_CACHE_SLABS = 485, - VAR_IPSECMOD_ENABLED = 486, - VAR_IPSECMOD_HOOK = 487, - VAR_IPSECMOD_IGNORE_BOGUS = 488, - VAR_IPSECMOD_MAX_TTL = 489, - VAR_IPSECMOD_WHITELIST = 490, - VAR_IPSECMOD_STRICT = 491, - VAR_CACHEDB = 492, - VAR_CACHEDB_BACKEND = 493, - VAR_CACHEDB_SECRETSEED = 494, - VAR_CACHEDB_REDISHOST = 495, - VAR_CACHEDB_REDISPORT = 496, - VAR_CACHEDB_REDISTIMEOUT = 497, - VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 498, - VAR_FOR_UPSTREAM = 499, - VAR_AUTH_ZONE = 500, - VAR_ZONEFILE = 501, - VAR_MASTER = 502, - VAR_URL = 503, - VAR_FOR_DOWNSTREAM = 504, - VAR_FALLBACK_ENABLED = 505, - VAR_TLS_ADDITIONAL_PORT = 506, - VAR_LOW_RTT = 507, - VAR_LOW_RTT_PERMIL = 508, - VAR_FAST_SERVER_PERMIL = 509, - VAR_FAST_SERVER_NUM = 510, - VAR_ALLOW_NOTIFY = 511, - VAR_TLS_WIN_CERT = 512, - VAR_TCP_CONNECTION_LIMIT = 513, - VAR_FORWARD_NO_CACHE = 514, - VAR_STUB_NO_CACHE = 515, - VAR_LOG_SERVFAIL = 516, - VAR_DENY_ANY = 517, - VAR_UNKNOWN_SERVER_TIME_LIMIT = 518, - VAR_LOG_TAG_QUERYREPLY = 519, - VAR_STREAM_WAIT_SIZE = 520, - VAR_TLS_CIPHERS = 521, - VAR_TLS_CIPHERSUITES = 522, - VAR_IPSET = 523, - VAR_IPSET_NAME_V4 = 524, - VAR_IPSET_NAME_V6 = 525, - VAR_TLS_SESSION_TICKET_KEYS = 526, - VAR_RPZ = 527, - VAR_TAGS = 528, - VAR_RPZ_ACTION_OVERRIDE = 529, - VAR_RPZ_CNAME_OVERRIDE = 530, - VAR_RPZ_LOG = 531, - VAR_RPZ_LOG_NAME = 532 + VAR_DNSTAP_IP = 409, + VAR_DNSTAP_TLS = 410, + VAR_DNSTAP_TLS_SERVER_NAME = 411, + VAR_DNSTAP_TLS_CERT_BUNDLE = 412, + VAR_DNSTAP_TLS_CLIENT_KEY_FILE = 413, + VAR_DNSTAP_TLS_CLIENT_CERT_FILE = 414, + VAR_DNSTAP_SEND_IDENTITY = 415, + VAR_DNSTAP_SEND_VERSION = 416, + VAR_DNSTAP_IDENTITY = 417, + VAR_DNSTAP_VERSION = 418, + VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES = 419, + VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES = 420, + VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES = 421, + VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES = 422, + VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES = 423, + VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES = 424, + VAR_RESPONSE_IP_TAG = 425, + VAR_RESPONSE_IP = 426, + VAR_RESPONSE_IP_DATA = 427, + VAR_HARDEN_ALGO_DOWNGRADE = 428, + VAR_IP_TRANSPARENT = 429, + VAR_DISABLE_DNSSEC_LAME_CHECK = 430, + VAR_IP_RATELIMIT = 431, + VAR_IP_RATELIMIT_SLABS = 432, + VAR_IP_RATELIMIT_SIZE = 433, + VAR_RATELIMIT = 434, + VAR_RATELIMIT_SLABS = 435, + VAR_RATELIMIT_SIZE = 436, + VAR_RATELIMIT_FOR_DOMAIN = 437, + VAR_RATELIMIT_BELOW_DOMAIN = 438, + VAR_IP_RATELIMIT_FACTOR = 439, + VAR_RATELIMIT_FACTOR = 440, + VAR_SEND_CLIENT_SUBNET = 441, + VAR_CLIENT_SUBNET_ZONE = 442, + VAR_CLIENT_SUBNET_ALWAYS_FORWARD = 443, + VAR_CLIENT_SUBNET_OPCODE = 444, + VAR_MAX_CLIENT_SUBNET_IPV4 = 445, + VAR_MAX_CLIENT_SUBNET_IPV6 = 446, + VAR_MIN_CLIENT_SUBNET_IPV4 = 447, + VAR_MIN_CLIENT_SUBNET_IPV6 = 448, + VAR_MAX_ECS_TREE_SIZE_IPV4 = 449, + VAR_MAX_ECS_TREE_SIZE_IPV6 = 450, + VAR_CAPS_WHITELIST = 451, + VAR_CACHE_MAX_NEGATIVE_TTL = 452, + VAR_PERMIT_SMALL_HOLDDOWN = 453, + VAR_QNAME_MINIMISATION = 454, + VAR_QNAME_MINIMISATION_STRICT = 455, + VAR_IP_FREEBIND = 456, + VAR_DEFINE_TAG = 457, + VAR_LOCAL_ZONE_TAG = 458, + VAR_ACCESS_CONTROL_TAG = 459, + VAR_LOCAL_ZONE_OVERRIDE = 460, + VAR_ACCESS_CONTROL_TAG_ACTION = 461, + VAR_ACCESS_CONTROL_TAG_DATA = 462, + VAR_VIEW = 463, + VAR_ACCESS_CONTROL_VIEW = 464, + VAR_VIEW_FIRST = 465, + VAR_SERVE_EXPIRED = 466, + VAR_SERVE_EXPIRED_TTL = 467, + VAR_SERVE_EXPIRED_TTL_RESET = 468, + VAR_SERVE_EXPIRED_REPLY_TTL = 469, + VAR_SERVE_EXPIRED_CLIENT_TIMEOUT = 470, + VAR_FAKE_DSA = 471, + VAR_FAKE_SHA1 = 472, + VAR_LOG_IDENTITY = 473, + VAR_HIDE_TRUSTANCHOR = 474, + VAR_TRUST_ANCHOR_SIGNALING = 475, + VAR_AGGRESSIVE_NSEC = 476, + VAR_USE_SYSTEMD = 477, + VAR_SHM_ENABLE = 478, + VAR_SHM_KEY = 479, + VAR_ROOT_KEY_SENTINEL = 480, + VAR_DNSCRYPT = 481, + VAR_DNSCRYPT_ENABLE = 482, + VAR_DNSCRYPT_PORT = 483, + VAR_DNSCRYPT_PROVIDER = 484, + VAR_DNSCRYPT_SECRET_KEY = 485, + VAR_DNSCRYPT_PROVIDER_CERT = 486, + VAR_DNSCRYPT_PROVIDER_CERT_ROTATED = 487, + VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE = 488, + VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS = 489, + VAR_DNSCRYPT_NONCE_CACHE_SIZE = 490, + VAR_DNSCRYPT_NONCE_CACHE_SLABS = 491, + VAR_IPSECMOD_ENABLED = 492, + VAR_IPSECMOD_HOOK = 493, + VAR_IPSECMOD_IGNORE_BOGUS = 494, + VAR_IPSECMOD_MAX_TTL = 495, + VAR_IPSECMOD_WHITELIST = 496, + VAR_IPSECMOD_STRICT = 497, + VAR_CACHEDB = 498, + VAR_CACHEDB_BACKEND = 499, + VAR_CACHEDB_SECRETSEED = 500, + VAR_CACHEDB_REDISHOST = 501, + VAR_CACHEDB_REDISPORT = 502, + VAR_CACHEDB_REDISTIMEOUT = 503, + VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 504, + VAR_FOR_UPSTREAM = 505, + VAR_AUTH_ZONE = 506, + VAR_ZONEFILE = 507, + VAR_MASTER = 508, + VAR_URL = 509, + VAR_FOR_DOWNSTREAM = 510, + VAR_FALLBACK_ENABLED = 511, + VAR_TLS_ADDITIONAL_PORT = 512, + VAR_LOW_RTT = 513, + VAR_LOW_RTT_PERMIL = 514, + VAR_FAST_SERVER_PERMIL = 515, + VAR_FAST_SERVER_NUM = 516, + VAR_ALLOW_NOTIFY = 517, + VAR_TLS_WIN_CERT = 518, + VAR_TCP_CONNECTION_LIMIT = 519, + VAR_FORWARD_NO_CACHE = 520, + VAR_STUB_NO_CACHE = 521, + VAR_LOG_SERVFAIL = 522, + VAR_DENY_ANY = 523, + VAR_UNKNOWN_SERVER_TIME_LIMIT = 524, + VAR_LOG_TAG_QUERYREPLY = 525, + VAR_STREAM_WAIT_SIZE = 526, + VAR_TLS_CIPHERS = 527, + VAR_TLS_CIPHERSUITES = 528, + VAR_IPSET = 529, + VAR_IPSET_NAME_V4 = 530, + VAR_IPSET_NAME_V6 = 531, + VAR_TLS_SESSION_TICKET_KEYS = 532, + VAR_RPZ = 533, + VAR_TAGS = 534, + VAR_RPZ_ACTION_OVERRIDE = 535, + VAR_RPZ_CNAME_OVERRIDE = 536, + VAR_RPZ_LOG = 537, + VAR_RPZ_LOG_NAME = 538 }; #endif /* Tokens. */ @@ -478,130 +484,136 @@ extern int yydebug; #define VAR_DNSTAP 406 #define VAR_DNSTAP_ENABLE 407 #define VAR_DNSTAP_SOCKET_PATH 408 -#define VAR_DNSTAP_SEND_IDENTITY 409 -#define VAR_DNSTAP_SEND_VERSION 410 -#define VAR_DNSTAP_IDENTITY 411 -#define VAR_DNSTAP_VERSION 412 -#define VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES 413 -#define VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES 414 -#define VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES 415 -#define VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES 416 -#define VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES 417 -#define VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES 418 -#define VAR_RESPONSE_IP_TAG 419 -#define VAR_RESPONSE_IP 420 -#define VAR_RESPONSE_IP_DATA 421 -#define VAR_HARDEN_ALGO_DOWNGRADE 422 -#define VAR_IP_TRANSPARENT 423 -#define VAR_DISABLE_DNSSEC_LAME_CHECK 424 -#define VAR_IP_RATELIMIT 425 -#define VAR_IP_RATELIMIT_SLABS 426 -#define VAR_IP_RATELIMIT_SIZE 427 -#define VAR_RATELIMIT 428 -#define VAR_RATELIMIT_SLABS 429 -#define VAR_RATELIMIT_SIZE 430 -#define VAR_RATELIMIT_FOR_DOMAIN 431 -#define VAR_RATELIMIT_BELOW_DOMAIN 432 -#define VAR_IP_RATELIMIT_FACTOR 433 -#define VAR_RATELIMIT_FACTOR 434 -#define VAR_SEND_CLIENT_SUBNET 435 -#define VAR_CLIENT_SUBNET_ZONE 436 -#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 437 -#define VAR_CLIENT_SUBNET_OPCODE 438 -#define VAR_MAX_CLIENT_SUBNET_IPV4 439 -#define VAR_MAX_CLIENT_SUBNET_IPV6 440 -#define VAR_MIN_CLIENT_SUBNET_IPV4 441 -#define VAR_MIN_CLIENT_SUBNET_IPV6 442 -#define VAR_MAX_ECS_TREE_SIZE_IPV4 443 -#define VAR_MAX_ECS_TREE_SIZE_IPV6 444 -#define VAR_CAPS_WHITELIST 445 -#define VAR_CACHE_MAX_NEGATIVE_TTL 446 -#define VAR_PERMIT_SMALL_HOLDDOWN 447 -#define VAR_QNAME_MINIMISATION 448 -#define VAR_QNAME_MINIMISATION_STRICT 449 -#define VAR_IP_FREEBIND 450 -#define VAR_DEFINE_TAG 451 -#define VAR_LOCAL_ZONE_TAG 452 -#define VAR_ACCESS_CONTROL_TAG 453 -#define VAR_LOCAL_ZONE_OVERRIDE 454 -#define VAR_ACCESS_CONTROL_TAG_ACTION 455 -#define VAR_ACCESS_CONTROL_TAG_DATA 456 -#define VAR_VIEW 457 -#define VAR_ACCESS_CONTROL_VIEW 458 -#define VAR_VIEW_FIRST 459 -#define VAR_SERVE_EXPIRED 460 -#define VAR_SERVE_EXPIRED_TTL 461 -#define VAR_SERVE_EXPIRED_TTL_RESET 462 -#define VAR_SERVE_EXPIRED_REPLY_TTL 463 -#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 464 -#define VAR_FAKE_DSA 465 -#define VAR_FAKE_SHA1 466 -#define VAR_LOG_IDENTITY 467 -#define VAR_HIDE_TRUSTANCHOR 468 -#define VAR_TRUST_ANCHOR_SIGNALING 469 -#define VAR_AGGRESSIVE_NSEC 470 -#define VAR_USE_SYSTEMD 471 -#define VAR_SHM_ENABLE 472 -#define VAR_SHM_KEY 473 -#define VAR_ROOT_KEY_SENTINEL 474 -#define VAR_DNSCRYPT 475 -#define VAR_DNSCRYPT_ENABLE 476 -#define VAR_DNSCRYPT_PORT 477 -#define VAR_DNSCRYPT_PROVIDER 478 -#define VAR_DNSCRYPT_SECRET_KEY 479 -#define VAR_DNSCRYPT_PROVIDER_CERT 480 -#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 481 -#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 482 -#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 483 -#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 484 -#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 485 -#define VAR_IPSECMOD_ENABLED 486 -#define VAR_IPSECMOD_HOOK 487 -#define VAR_IPSECMOD_IGNORE_BOGUS 488 -#define VAR_IPSECMOD_MAX_TTL 489 -#define VAR_IPSECMOD_WHITELIST 490 -#define VAR_IPSECMOD_STRICT 491 -#define VAR_CACHEDB 492 -#define VAR_CACHEDB_BACKEND 493 -#define VAR_CACHEDB_SECRETSEED 494 -#define VAR_CACHEDB_REDISHOST 495 -#define VAR_CACHEDB_REDISPORT 496 -#define VAR_CACHEDB_REDISTIMEOUT 497 -#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 498 -#define VAR_FOR_UPSTREAM 499 -#define VAR_AUTH_ZONE 500 -#define VAR_ZONEFILE 501 -#define VAR_MASTER 502 -#define VAR_URL 503 -#define VAR_FOR_DOWNSTREAM 504 -#define VAR_FALLBACK_ENABLED 505 -#define VAR_TLS_ADDITIONAL_PORT 506 -#define VAR_LOW_RTT 507 -#define VAR_LOW_RTT_PERMIL 508 -#define VAR_FAST_SERVER_PERMIL 509 -#define VAR_FAST_SERVER_NUM 510 -#define VAR_ALLOW_NOTIFY 511 -#define VAR_TLS_WIN_CERT 512 -#define VAR_TCP_CONNECTION_LIMIT 513 -#define VAR_FORWARD_NO_CACHE 514 -#define VAR_STUB_NO_CACHE 515 -#define VAR_LOG_SERVFAIL 516 -#define VAR_DENY_ANY 517 -#define VAR_UNKNOWN_SERVER_TIME_LIMIT 518 -#define VAR_LOG_TAG_QUERYREPLY 519 -#define VAR_STREAM_WAIT_SIZE 520 -#define VAR_TLS_CIPHERS 521 -#define VAR_TLS_CIPHERSUITES 522 -#define VAR_IPSET 523 -#define VAR_IPSET_NAME_V4 524 -#define VAR_IPSET_NAME_V6 525 -#define VAR_TLS_SESSION_TICKET_KEYS 526 -#define VAR_RPZ 527 -#define VAR_TAGS 528 -#define VAR_RPZ_ACTION_OVERRIDE 529 -#define VAR_RPZ_CNAME_OVERRIDE 530 -#define VAR_RPZ_LOG 531 -#define VAR_RPZ_LOG_NAME 532 +#define VAR_DNSTAP_IP 409 +#define VAR_DNSTAP_TLS 410 +#define VAR_DNSTAP_TLS_SERVER_NAME 411 +#define VAR_DNSTAP_TLS_CERT_BUNDLE 412 +#define VAR_DNSTAP_TLS_CLIENT_KEY_FILE 413 +#define VAR_DNSTAP_TLS_CLIENT_CERT_FILE 414 +#define VAR_DNSTAP_SEND_IDENTITY 415 +#define VAR_DNSTAP_SEND_VERSION 416 +#define VAR_DNSTAP_IDENTITY 417 +#define VAR_DNSTAP_VERSION 418 +#define VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES 419 +#define VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES 420 +#define VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES 421 +#define VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES 422 +#define VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES 423 +#define VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES 424 +#define VAR_RESPONSE_IP_TAG 425 +#define VAR_RESPONSE_IP 426 +#define VAR_RESPONSE_IP_DATA 427 +#define VAR_HARDEN_ALGO_DOWNGRADE 428 +#define VAR_IP_TRANSPARENT 429 +#define VAR_DISABLE_DNSSEC_LAME_CHECK 430 +#define VAR_IP_RATELIMIT 431 +#define VAR_IP_RATELIMIT_SLABS 432 +#define VAR_IP_RATELIMIT_SIZE 433 +#define VAR_RATELIMIT 434 +#define VAR_RATELIMIT_SLABS 435 +#define VAR_RATELIMIT_SIZE 436 +#define VAR_RATELIMIT_FOR_DOMAIN 437 +#define VAR_RATELIMIT_BELOW_DOMAIN 438 +#define VAR_IP_RATELIMIT_FACTOR 439 +#define VAR_RATELIMIT_FACTOR 440 +#define VAR_SEND_CLIENT_SUBNET 441 +#define VAR_CLIENT_SUBNET_ZONE 442 +#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 443 +#define VAR_CLIENT_SUBNET_OPCODE 444 +#define VAR_MAX_CLIENT_SUBNET_IPV4 445 +#define VAR_MAX_CLIENT_SUBNET_IPV6 446 +#define VAR_MIN_CLIENT_SUBNET_IPV4 447 +#define VAR_MIN_CLIENT_SUBNET_IPV6 448 +#define VAR_MAX_ECS_TREE_SIZE_IPV4 449 +#define VAR_MAX_ECS_TREE_SIZE_IPV6 450 +#define VAR_CAPS_WHITELIST 451 +#define VAR_CACHE_MAX_NEGATIVE_TTL 452 +#define VAR_PERMIT_SMALL_HOLDDOWN 453 +#define VAR_QNAME_MINIMISATION 454 +#define VAR_QNAME_MINIMISATION_STRICT 455 +#define VAR_IP_FREEBIND 456 +#define VAR_DEFINE_TAG 457 +#define VAR_LOCAL_ZONE_TAG 458 +#define VAR_ACCESS_CONTROL_TAG 459 +#define VAR_LOCAL_ZONE_OVERRIDE 460 +#define VAR_ACCESS_CONTROL_TAG_ACTION 461 +#define VAR_ACCESS_CONTROL_TAG_DATA 462 +#define VAR_VIEW 463 +#define VAR_ACCESS_CONTROL_VIEW 464 +#define VAR_VIEW_FIRST 465 +#define VAR_SERVE_EXPIRED 466 +#define VAR_SERVE_EXPIRED_TTL 467 +#define VAR_SERVE_EXPIRED_TTL_RESET 468 +#define VAR_SERVE_EXPIRED_REPLY_TTL 469 +#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 470 +#define VAR_FAKE_DSA 471 +#define VAR_FAKE_SHA1 472 +#define VAR_LOG_IDENTITY 473 +#define VAR_HIDE_TRUSTANCHOR 474 +#define VAR_TRUST_ANCHOR_SIGNALING 475 +#define VAR_AGGRESSIVE_NSEC 476 +#define VAR_USE_SYSTEMD 477 +#define VAR_SHM_ENABLE 478 +#define VAR_SHM_KEY 479 +#define VAR_ROOT_KEY_SENTINEL 480 +#define VAR_DNSCRYPT 481 +#define VAR_DNSCRYPT_ENABLE 482 +#define VAR_DNSCRYPT_PORT 483 +#define VAR_DNSCRYPT_PROVIDER 484 +#define VAR_DNSCRYPT_SECRET_KEY 485 +#define VAR_DNSCRYPT_PROVIDER_CERT 486 +#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 487 +#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 488 +#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 489 +#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 490 +#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 491 +#define VAR_IPSECMOD_ENABLED 492 +#define VAR_IPSECMOD_HOOK 493 +#define VAR_IPSECMOD_IGNORE_BOGUS 494 +#define VAR_IPSECMOD_MAX_TTL 495 +#define VAR_IPSECMOD_WHITELIST 496 +#define VAR_IPSECMOD_STRICT 497 +#define VAR_CACHEDB 498 +#define VAR_CACHEDB_BACKEND 499 +#define VAR_CACHEDB_SECRETSEED 500 +#define VAR_CACHEDB_REDISHOST 501 +#define VAR_CACHEDB_REDISPORT 502 +#define VAR_CACHEDB_REDISTIMEOUT 503 +#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 504 +#define VAR_FOR_UPSTREAM 505 +#define VAR_AUTH_ZONE 506 +#define VAR_ZONEFILE 507 +#define VAR_MASTER 508 +#define VAR_URL 509 +#define VAR_FOR_DOWNSTREAM 510 +#define VAR_FALLBACK_ENABLED 511 +#define VAR_TLS_ADDITIONAL_PORT 512 +#define VAR_LOW_RTT 513 +#define VAR_LOW_RTT_PERMIL 514 +#define VAR_FAST_SERVER_PERMIL 515 +#define VAR_FAST_SERVER_NUM 516 +#define VAR_ALLOW_NOTIFY 517 +#define VAR_TLS_WIN_CERT 518 +#define VAR_TCP_CONNECTION_LIMIT 519 +#define VAR_FORWARD_NO_CACHE 520 +#define VAR_STUB_NO_CACHE 521 +#define VAR_LOG_SERVFAIL 522 +#define VAR_DENY_ANY 523 +#define VAR_UNKNOWN_SERVER_TIME_LIMIT 524 +#define VAR_LOG_TAG_QUERYREPLY 525 +#define VAR_STREAM_WAIT_SIZE 526 +#define VAR_TLS_CIPHERS 527 +#define VAR_TLS_CIPHERSUITES 528 +#define VAR_IPSET 529 +#define VAR_IPSET_NAME_V4 530 +#define VAR_IPSET_NAME_V6 531 +#define VAR_TLS_SESSION_TICKET_KEYS 532 +#define VAR_RPZ 533 +#define VAR_TAGS 534 +#define VAR_RPZ_ACTION_OVERRIDE 535 +#define VAR_RPZ_CNAME_OVERRIDE 536 +#define VAR_RPZ_LOG 537 +#define VAR_RPZ_LOG_NAME 538 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED @@ -611,7 +623,7 @@ union YYSTYPE char* str; -#line 615 "util/configparser.h" +#line 627 "util/configparser.h" }; typedef union YYSTYPE YYSTYPE; diff --git a/util/configparser.y b/util/configparser.y index 798f4a972..50eb5dbdb 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -116,7 +116,9 @@ extern struct config_parser_state* cfg_parser; %token VAR_UNBLOCK_LAN_ZONES VAR_INSECURE_LAN_ZONES %token VAR_INFRA_CACHE_MIN_RTT %token VAR_DNS64_PREFIX VAR_DNS64_SYNTHALL VAR_DNS64_IGNORE_AAAA -%token VAR_DNSTAP VAR_DNSTAP_ENABLE VAR_DNSTAP_SOCKET_PATH +%token VAR_DNSTAP VAR_DNSTAP_ENABLE VAR_DNSTAP_SOCKET_PATH VAR_DNSTAP_IP +%token VAR_DNSTAP_TLS VAR_DNSTAP_TLS_SERVER_NAME VAR_DNSTAP_TLS_CERT_BUNDLE +%token VAR_DNSTAP_TLS_CLIENT_KEY_FILE VAR_DNSTAP_TLS_CLIENT_CERT_FILE %token VAR_DNSTAP_SEND_IDENTITY VAR_DNSTAP_SEND_VERSION %token VAR_DNSTAP_IDENTITY VAR_DNSTAP_VERSION %token VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES @@ -2720,6 +2722,9 @@ dtstart: VAR_DNSTAP contents_dt: contents_dt content_dt | ; content_dt: dt_dnstap_enable | dt_dnstap_socket_path | + dt_dnstap_ip | dt_dnstap_tls | dt_dnstap_tls_server_name | + dt_dnstap_tls_cert_bundle | + dt_dnstap_tls_client_key_file | dt_dnstap_tls_client_cert_file | dt_dnstap_send_identity | dt_dnstap_send_version | dt_dnstap_identity | dt_dnstap_version | dt_dnstap_log_resolver_query_messages | @@ -2745,6 +2750,50 @@ dt_dnstap_socket_path: VAR_DNSTAP_SOCKET_PATH STRING_ARG cfg_parser->cfg->dnstap_socket_path = $2; } ; +dt_dnstap_ip: VAR_DNSTAP_IP STRING_ARG + { + OUTYY(("P(dt_dnstap_ip:%s)\n", $2)); + free(cfg_parser->cfg->dnstap_ip); + cfg_parser->cfg->dnstap_ip = $2; + } + ; +dt_dnstap_tls: VAR_DNSTAP_TLS STRING_ARG + { + OUTYY(("P(dt_dnstap_tls:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->dnstap_tls = (strcmp($2, "yes")==0); + free($2); + } + ; +dt_dnstap_tls_server_name: VAR_DNSTAP_TLS_SERVER_NAME STRING_ARG + { + OUTYY(("P(dt_dnstap_tls_server_name:%s)\n", $2)); + free(cfg_parser->cfg->dnstap_tls_server_name); + cfg_parser->cfg->dnstap_tls_server_name = $2; + } + ; +dt_dnstap_tls_cert_bundle: VAR_DNSTAP_TLS_CERT_BUNDLE STRING_ARG + { + OUTYY(("P(dt_dnstap_tls_cert_bundle:%s)\n", $2)); + free(cfg_parser->cfg->dnstap_tls_cert_bundle); + cfg_parser->cfg->dnstap_tls_cert_bundle = $2; + } + ; +dt_dnstap_tls_client_key_file: VAR_DNSTAP_TLS_CLIENT_KEY_FILE STRING_ARG + { + OUTYY(("P(dt_dnstap_tls_client_key_file:%s)\n", $2)); + free(cfg_parser->cfg->dnstap_tls_client_key_file); + cfg_parser->cfg->dnstap_tls_client_key_file = $2; + } + ; +dt_dnstap_tls_client_cert_file: VAR_DNSTAP_TLS_CLIENT_CERT_FILE STRING_ARG + { + OUTYY(("P(dt_dnstap_tls_client_cert_file:%s)\n", $2)); + free(cfg_parser->cfg->dnstap_tls_client_cert_file); + cfg_parser->cfg->dnstap_tls_client_cert_file = $2; + } + ; dt_dnstap_send_identity: VAR_DNSTAP_SEND_IDENTITY STRING_ARG { OUTYY(("P(dt_dnstap_send_identity:%s)\n", $2)); From 6d1b4e050d6d766707f1a18b69d684c86877b3cf Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 14 Feb 2020 10:01:37 +0100 Subject: [PATCH 69/96] dnstap io, dnstap tls default is yes, and man page documentation. --- doc/example.conf.in | 2 +- doc/unbound.conf.5.in | 72 +++++++++++++++++++++++++++++++++++++++++++ util/config_file.c | 1 + 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/doc/example.conf.in b/doc/example.conf.in index ec1b1ac70..277ea1977 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -1026,7 +1026,7 @@ remote-control: # # set it to "IPaddress[@port]" of the destination. # dnstap-ip: "" # # if set to yes if you want to use TLS to dnstap-ip, no for TCP. -# dnstap-tls: no +# dnstap-tls: yes # # name for authenticating the upstream server. or "" disabled. # dnstap-tls-server-name: "" # # if "", it uses the cert bundle from the main unbound config. diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index 38c2d2984..86a962430 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -2114,6 +2114,78 @@ If this timeout expires Unbound closes the connection, treats it as if the Redis server does not have the requested data, and will try to re-establish a new connection later. This option defaults to 100 milliseconds. +.SS DNSTAP Logging Options +DNSTAP support, when compiled in, is enabled in the \fBdnstap:\fR section. +.TP +.B dnstap-enable: \fI +If dnstap is enabled. Default no. If yes, it connects to the dnstap server +and if any of the dnstap-log-..-messages options is enabled it sends logs +for those messages to the server. +.TP +.B dnstap-socket-path: \fI +Sets the unix socket file name for connecting to the server that is +listening on that socket. Default is "@DNSTAP_SOCKET_PATH@". +.TP +.B dnstap-ip: \fI +If "", the unix socket is used, if set with an IP address (IPv4 or IPv6) +that address is used to connect to the server. +.TP +.B dnstap-tls: \fI +Set this to use TLS to connect to the server specified in \fBdnstap-ip\fR. +The default is yes. If set to no, TCP is used to connect to the server. +.TP +.B dnstap-tls-server-name: \fI +The TLS server name to authenticate the server with. Used when \fBdnstap-tls\fR is enabled. If "" it is ignored, default "". +.TP +.B dnstap-tls-cert-bundle: \fI +The pem file with certs to verify the TLS server certificate. If "" the +server default cert bundle is used, or the windows cert bundle on windows. +Default is "". +.TP +.B dnstap-tls-client-key-file: \fI +The client key file for TLS client authentication. If "" client +authentication is not used. Default is "". +.TP +.B dnstap-tls-client-cert-file: \fI +The client cert file for TLS client authentication. Default is "". +.TP +.B dnstap-send-identity: \fI +If enabled, the server identity is included in the log messages. +Default is no. +.TP +.B dnstap-send-version: \fI +If enabled, the server version if included in the log messages. +Default is no. +.TP +.B dnstap-identity: \fI +The identity to send with messages, if "" the hostname is used. +Default is "". +.TP +.B dnstap-version: \fI +The version to send with messages, if "" the package version is used. +Default is "". +.TP +.B dnstap-log-resolver-query-messages: \fI +Enable to log resolver query messages. Default is no. +These are messages from unbound to upstream servers. +.TP +.B dnstap-log-resolver-response-messages: \fI +Enable to log resolver response messages. Default is no. +These are replies from upstream servers to unbound. +.TP +.B dnstap-log-client-query-messages: \fI +Enable to log client query messages. Default is no. +These are client queries to unbound. +.TP +.B dnstap-log-client-response-messages: \fI +Enable to log client response messages. Default is no. +These are responses from unbound to clients. +.TP +.B dnstap-log-forwarder-query-messages: \fI +Enable to log forwarder query messages. Default is no. +.TP +.B dnstap-log-forwarder-response-messages: \fI +Enable to log forwarder response messages. Default is no. .SS Response Policy Zone Options .LP Response Policy Zones are configured with \fBrpz:\fR, and each one must have a diff --git a/util/config_file.c b/util/config_file.c index 19a5a0bcd..394cf17f3 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -295,6 +295,7 @@ config_create(void) if(!(cfg->dnstap_socket_path = strdup(DNSTAP_SOCKET_PATH))) goto error_exit; #endif + cfg->dnstap_tls = 1; cfg->disable_dnssec_lame_check = 0; cfg->ip_ratelimit = 0; cfg->ratelimit = 0; From 748b70ae8bf082b2967f0fb84f90b4ee4844e187 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 14 Feb 2020 10:33:33 +0100 Subject: [PATCH 70/96] dnstap io, fix clang analysis warning --- dnstap/dtstream.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 4af83cd41..7474de1e3 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -275,6 +275,10 @@ int dt_io_thread_apply_cfg(struct dt_io_thread* dtio, struct config_file *cfg) } if(dtio->upstream_is_tcp || dtio->upstream_is_tls) { + if(!cfg->dnstap_ip || cfg->dnstap_ip[0] == 0) { + log_err("dnstap setup: no dnstap-ip for TCP connect"); + return 0; + } free(dtio->ip_str); dtio->ip_str = strdup(cfg->dnstap_ip); if(!dtio->ip_str) { From 465af5845731c4cf42fed27731ae9654161c9d57 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 14 Feb 2020 13:23:58 +0100 Subject: [PATCH 71/96] dnstap io, fix to compile without ssl. --- dnstap/dtstream.c | 18 ++++++++++++++++++ dnstap/unbound-dnstap-socket.c | 22 ++++++++++++++++++++++ services/outside_network.c | 2 ++ util/net_help.c | 2 ++ 4 files changed, 44 insertions(+) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 7474de1e3..ba545dd7c 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -83,8 +83,10 @@ static int dtio_add_output_event_write(struct dt_io_thread* dtio); static void dtio_reconnect_enable(struct dt_io_thread* dtio); /** stop from stop_flush event loop */ static void dtio_stop_flush_exit(struct stop_flush_info* info); +#ifdef HAVE_SSL /** enable briefly waiting for a read event, for SSL negotiation */ static int dtio_enable_brief_read(struct dt_io_thread* dtio); +#endif struct dt_msg_queue* dt_msg_queue_create(void) @@ -638,6 +640,7 @@ static int dtio_check_nb_connect(struct dt_io_thread* dtio) return 1; /* everything okay */ } +#ifdef HAVE_SSL /** write to ssl output * returns number of bytes written, 0 if nothing happened, * try again later, or -1 if the channel is to be closed. */ @@ -679,6 +682,7 @@ static int dtio_write_ssl(struct dt_io_thread* dtio, uint8_t* buf, } return r; } +#endif /* HAVE_SSL */ /** write buffer to output. * returns number of bytes written, 0 if nothing happened, @@ -689,8 +693,10 @@ static int dtio_write_buf(struct dt_io_thread* dtio, uint8_t* buf, ssize_t ret; if(dtio->fd == -1) return -1; +#ifdef HAVE_SSL if(dtio->ssl) return dtio_write_ssl(dtio, buf, len); +#endif ret = send(dtio->fd, (void*)buf, len, 0); if(ret == -1) { #ifndef USE_WINSOCK @@ -948,6 +954,7 @@ static void dtio_sleep(struct dt_io_thread* dtio) (void)dtio_add_output_event_read(dtio); } +#ifdef HAVE_SSL /** enable the brief read condition */ static int dtio_enable_brief_read(struct dt_io_thread* dtio) { @@ -963,7 +970,9 @@ static int dtio_enable_brief_read(struct dt_io_thread* dtio) } return dtio_add_output_event_read(dtio); } +#endif /* HAVE_SSL */ +#ifdef HAVE_SSL /** disable the brief read condition */ static int dtio_disable_brief_read(struct dt_io_thread* dtio) { @@ -979,7 +988,9 @@ static int dtio_disable_brief_read(struct dt_io_thread* dtio) } return dtio_add_output_event_write(dtio); } +#endif /* HAVE_SSL */ +#ifdef HAVE_SSL /** check peer verification after ssl handshake connection, false if closed*/ static int dtio_ssl_check_peer(struct dt_io_thread* dtio) { @@ -1030,7 +1041,9 @@ static int dtio_ssl_check_peer(struct dt_io_thread* dtio) } return 1; } +#endif /* HAVE_SSL */ +#ifdef HAVE_SSL /** perform ssl handshake, returns 1 if okay, 0 to stop */ static int dtio_ssl_handshake(struct dt_io_thread* dtio, struct stop_flush_info* info) @@ -1116,6 +1129,7 @@ static int dtio_ssl_handshake(struct dt_io_thread* dtio, } return 1; } +#endif /* HAVE_SSL */ /** callback for the dnstap events, to write to the output */ static void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg) @@ -1137,11 +1151,13 @@ static void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg) /* nonblocking connect check passed, continue */ } +#ifdef HAVE_SSL if(dtio->ssl && (!dtio->ssl_handshake_done || dtio->ssl_brief_read)) { if(!dtio_ssl_handshake(dtio, NULL)) return; } +#endif if((bits&UB_EV_READ)) { if(!dtio_check_close(dtio)) @@ -1352,11 +1368,13 @@ static void dtio_stop_ev_cb(int ATTR_UNUSED(fd), short bits, void* arg) } /* nonblocking connect check passed, continue */ } +#ifdef HAVE_SSL if(dtio->ssl && (!dtio->ssl_handshake_done || dtio->ssl_brief_read)) { if(!dtio_ssl_handshake(dtio, info)) return; } +#endif if((bits&UB_EV_READ)) { if(!dtio_check_close(dtio)) { diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index eda75e0c0..803236196 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -178,7 +178,9 @@ static void tap_socket_close(struct tap_socket* s) static void tap_socket_delete(struct tap_socket* s) { if(!s) return; +#ifdef HAVE_SSL SSL_CTX_free(s->sslctx); +#endif ub_event_free(s->ev); free(s->socketpath); free(s->ip); @@ -702,6 +704,8 @@ static ssize_t receive_bytes(struct tap_data* data, int fd, void* buf, return ret; } +/* define routine for have_ssl only to avoid unused function warning */ +#ifdef HAVE_SSL /** set to wait briefly for a write event, for one event call */ static void tap_enable_brief_write(struct tap_data* data) { @@ -712,7 +716,10 @@ static void tap_enable_brief_write(struct tap_data* data) log_err("could not ub_event_add in tap_enable_brief_write"); data->ssl_brief_write = 1; } +#endif /* HAVE_SSL */ +/* define routine for have_ssl only to avoid unused function warning */ +#ifdef HAVE_SSL /** stop the brief wait for a write event. back to reading. */ static void tap_disable_brief_write(struct tap_data* data) { @@ -723,7 +730,9 @@ static void tap_disable_brief_write(struct tap_data* data) log_err("could not ub_event_add in tap_disable_brief_write"); data->ssl_brief_write = 0; } +#endif /* HAVE_SSL */ +#ifdef HAVE_SSL /** receive bytes over ssl stream, prints errors if bad, * returns 0: closed/error, -1: continue, >0 number of bytes */ static ssize_t ssl_read_bytes(struct tap_data* data, void* buf, size_t len) @@ -764,13 +773,16 @@ static ssize_t ssl_read_bytes(struct tap_data* data, void* buf, size_t len) } return r; } +#endif /* HAVE_SSL */ /** receive bytes on the tap connection, prints errors if bad, * returns 0: closed/error, -1: continue, >0 number of bytes */ static ssize_t tap_receive(struct tap_data* data, void* buf, size_t len) { +#ifdef HAVE_SSL if(data->ssl) return ssl_read_bytes(data, buf, len); +#endif return receive_bytes(data, data->fd, buf, len); } @@ -779,7 +791,9 @@ void tap_data_free(struct tap_data* data) { ub_event_del(data->ev); ub_event_free(data->ev); +#ifdef HAVE_SSL SSL_free(data->ssl); +#endif close(data->fd); free(data->id); free(data->frame); @@ -865,6 +879,7 @@ static int reply_with_finish(int fd) return 1; } +#ifdef HAVE_SSL /** check SSL peer certificate, return 0 on fail */ static int tap_check_peer(struct tap_data* data) { @@ -910,7 +925,9 @@ static int tap_check_peer(struct tap_data* data) } return 1; } +#endif /* HAVE_SSL */ +#ifdef HAVE_SSL /** perform SSL handshake, return 0 to wait for events, 1 if done */ static int tap_handshake(struct tap_data* data) { @@ -974,17 +991,20 @@ static int tap_handshake(struct tap_data* data) } return 1; } +#endif /* HAVE_SSL */ /** callback for dnstap listener */ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) { struct tap_data* data = (struct tap_data*)arg; if(verbosity>=3) log_info("tap callback"); +#ifdef HAVE_SSL if(data->ssl && (!data->ssl_handshake_done || data->ssl_brief_write)) { if(!tap_handshake(data)) return; } +#endif while(data->len_done < 4) { uint32_t l = (uint32_t)data->len; ssize_t ret = tap_receive(data, @@ -1351,6 +1371,7 @@ int main(int argc, char** argv) argv += optind; if(usessl) { +#ifdef HAVE_SSL #if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL) ERR_load_SSL_strings(); #endif @@ -1368,6 +1389,7 @@ int main(int argc, char** argv) #else (void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); #endif +#endif /* HAVE_SSL */ } setup_and_run(&local_list, &tcp_list, &tls_list, server_key, server_cert, verifypem); diff --git a/services/outside_network.c b/services/outside_network.c index 612767056..721dd335a 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -375,7 +375,9 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len) pend->c->ssl_shake_state = comm_ssl_shake_write; if(!set_auth_name_on_ssl(pend->c->ssl, w->tls_auth_name)) { pend->c->fd = s; +#ifdef HAVE_SSL SSL_free(pend->c->ssl); +#endif pend->c->ssl = NULL; comm_point_close(pend->c); return 0; diff --git a/util/net_help.c b/util/net_help.c index 007eaff0b..98c92ad86 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -1223,6 +1223,8 @@ int set_auth_name_on_ssl(void* ssl, char* auth_name) if(!auth_name) return 1; #ifdef HAVE_SSL (void)SSL_set_tlsext_host_name(ssl, auth_name); +#else + (void)ssl; #endif #ifdef HAVE_SSL_SET1_HOST SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL); From 583e8b71e4fa51f20f3db84feb98054aabdb4c2c Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 14 Feb 2020 13:54:07 +0100 Subject: [PATCH 72/96] Nicer comment text. --- dnstap/dnstap_fstrm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnstap/dnstap_fstrm.c b/dnstap/dnstap_fstrm.c index 51ff71a6e..be4acace8 100644 --- a/dnstap/dnstap_fstrm.c +++ b/dnstap/dnstap_fstrm.c @@ -52,7 +52,7 @@ void* fstrm_create_control_frame_start(char* contenttype, size_t* len) * 4byte 0: control indicator. * 4byte bigendian: length of control frame * 4byte bigendian: type START - * 4byte bigendian: frame option: content-type + * 4byte bigendian: option: content-type * 4byte bigendian: length of string * string of content type (dnstap) */ From 7da19e96cec049cc58a176576525db60df78dad1 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 14 Feb 2020 14:16:56 +0100 Subject: [PATCH 73/96] dnstap io, test for TCP and reconnect for that. --- dnstap/unbound-dnstap-socket.c | 2 + testdata/dnstap_tcp.tdir/dnstap_tcp.conf | 42 +++++++++ testdata/dnstap_tcp.tdir/dnstap_tcp.dsc | 16 ++++ testdata/dnstap_tcp.tdir/dnstap_tcp.post | 23 +++++ testdata/dnstap_tcp.tdir/dnstap_tcp.pre | 54 ++++++++++++ testdata/dnstap_tcp.tdir/dnstap_tcp.test | 91 ++++++++++++++++++++ testdata/dnstap_tcp.tdir/dnstap_tcp.testns | 22 +++++ testdata/dnstap_tcp.tdir/unbound_control.key | 15 ++++ testdata/dnstap_tcp.tdir/unbound_control.pem | 11 +++ testdata/dnstap_tcp.tdir/unbound_server.key | 15 ++++ testdata/dnstap_tcp.tdir/unbound_server.pem | 11 +++ 11 files changed, 302 insertions(+) create mode 100644 testdata/dnstap_tcp.tdir/dnstap_tcp.conf create mode 100644 testdata/dnstap_tcp.tdir/dnstap_tcp.dsc create mode 100644 testdata/dnstap_tcp.tdir/dnstap_tcp.post create mode 100644 testdata/dnstap_tcp.tdir/dnstap_tcp.pre create mode 100644 testdata/dnstap_tcp.tdir/dnstap_tcp.test create mode 100644 testdata/dnstap_tcp.tdir/dnstap_tcp.testns create mode 100644 testdata/dnstap_tcp.tdir/unbound_control.key create mode 100644 testdata/dnstap_tcp.tdir/unbound_control.pem create mode 100644 testdata/dnstap_tcp.tdir/unbound_server.key create mode 100644 testdata/dnstap_tcp.tdir/unbound_server.pem diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index 803236196..e26e12ede 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -1266,9 +1266,11 @@ setup_and_run(struct config_strlist_head* local_list, verifypem); if(!tap_socket_list_addevs(maindata->acceptlist, base)) fatal_exit("could not setup accept events"); + if(verbosity) log_info("start of service"); ub_event_base_dispatch(base); + if(verbosity) log_info("end of service"); sig_base = NULL; tap_socket_list_delete(maindata->acceptlist); ub_event_base_free(base); diff --git a/testdata/dnstap_tcp.tdir/dnstap_tcp.conf b/testdata/dnstap_tcp.tdir/dnstap_tcp.conf new file mode 100644 index 000000000..6aefaad1e --- /dev/null +++ b/testdata/dnstap_tcp.tdir/dnstap_tcp.conf @@ -0,0 +1,42 @@ +server: + verbosity: 2 + num-threads: 1 + outgoing-range: 16 + interface: 127.0.0.1 + port: @PORT@ + use-syslog: no + directory: "" + pidfile: "unbound.pid" + chroot: "" + username: "" + do-not-query-localhost: no + local-zone: "example.net." redirect + local-data: "example.net. IN A 10.20.30.41" +remote-control: + control-enable: yes + control-interface: 127.0.0.1 + # control-interface: ::1 + control-port: @CONTROL_PORT@ + server-key-file: "unbound_server.key" + server-cert-file: "unbound_server.pem" + control-key-file: "unbound_control.key" + control-cert-file: "unbound_control.pem" +forward-zone: + name: "." + forward-addr: "127.0.0.1@@TOPORT@" +dnstap: + dnstap-enable: yes + #dnstap-socket-path: "dnstap.socket" + dnstap-ip: "127.0.0.1@@TAPPORT@" + dnstap-tls: no + dnstap-send-identity: yes + dnstap-send-version: yes + #dnstap-identity + #dnstap-version + dnstap-log-resolver-query-messages: yes + dnstap-log-resolver-response-messages: yes + dnstap-log-client-query-messages: yes + dnstap-log-client-response-messages: yes + dnstap-log-forwarder-query-messages: yes + dnstap-log-forwarder-response-messages: yes + diff --git a/testdata/dnstap_tcp.tdir/dnstap_tcp.dsc b/testdata/dnstap_tcp.tdir/dnstap_tcp.dsc new file mode 100644 index 000000000..de4ad82da --- /dev/null +++ b/testdata/dnstap_tcp.tdir/dnstap_tcp.dsc @@ -0,0 +1,16 @@ +BaseName: dnstap_tcp +Version: 1.0 +Description: test dnstap tcp and reconnect +CreationDate: Tue Feb 14 14:00:38 CET 2020 +Maintainer: dr. W.C.A. Wijngaards +Category: +Component: +CmdDepends: +Depends: +Help: +Pre: dnstap_tcp.pre +Post: dnstap_tcp.post +Test: dnstap_tcp.test +AuxFiles: +Passed: +Failure: diff --git a/testdata/dnstap_tcp.tdir/dnstap_tcp.post b/testdata/dnstap_tcp.tdir/dnstap_tcp.post new file mode 100644 index 000000000..64e30db17 --- /dev/null +++ b/testdata/dnstap_tcp.tdir/dnstap_tcp.post @@ -0,0 +1,23 @@ +# #-- dnstap_tcp.post --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# source the test var file when it's there +[ -f .tpkg.var.test ] && source .tpkg.var.test +# +# do your teardown here +. ../common.sh +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi +kill_pid $DNSTAP_SOCKET_PID +kill_pid $FWD_PID +kill $UNBOUND_PID +kill $UNBOUND_PID >/dev/null 2>&1 +cat unbound.log +echo "> tap logfiles" +cat tap.log +cat tap.errlog +echo "> tap2 logfiles" +cat tap2.log +cat tap2.errlog +cat fwd.log +exit 0 diff --git a/testdata/dnstap_tcp.tdir/dnstap_tcp.pre b/testdata/dnstap_tcp.tdir/dnstap_tcp.pre new file mode 100644 index 000000000..3006603c5 --- /dev/null +++ b/testdata/dnstap_tcp.tdir/dnstap_tcp.pre @@ -0,0 +1,54 @@ +# #-- dnstap_tcp.pre--# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +. ../common.sh + +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi + +get_random_port 4 +UNBOUND_PORT=$RND_PORT +FWD_PORT=$(($RND_PORT + 1)) +CONTROL_PORT=$(($RND_PORT + 2)) +TAP_PORT=$(($RND_PORT + 3)) +echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test +echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test +echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test +echo "TAP_PORT=$TAP_PORT" >> .tpkg.var.test + +# start forwarder +get_ldns_testns +$LDNS_TESTNS -p $FWD_PORT dnstap_tcp.testns >fwd.log 2>&1 & +FWD_PID=$! +echo "FWD_PID=$FWD_PID" >> .tpkg.var.test + +# start the dnstap log server +# the -vvvv flag prints protocol and connection information from the +# unbound-dnstap-socket server. +# the -l flag prints the DNS info in the DNSTAP packet in multiline output. +# stderr is the '-vvvv' server logs and errors. +# stdout is the one-line packet logs (or with -l, multiline). +$PRE/unbound-dnstap-socket -s "127.0.0.1@$TAP_PORT" -l -vvvv 2>tap.errlog >tap.log & +if test $? -ne 0; then + echo "could not start unbound-dnstap-socket server" + exit 1 +fi +DNSTAP_SOCKET_PID=$! +echo "DNSTAP_SOCKET_PID=$DNSTAP_SOCKET_PID" >> .tpkg.var.test +# wait for the server to go up +wait_server_up "tap.errlog" "start of service" + +# make config file +sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' -e 's/@TAPPORT\@/'$TAP_PORT'/' < dnstap_tcp.conf > ub.conf +# start unbound in the background +$PRE/unbound -d -c ub.conf >unbound.log 2>&1 & +UNBOUND_PID=$! +echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test + +cat .tpkg.var.test +wait_ldns_testns_up fwd.log +wait_unbound_up unbound.log + diff --git a/testdata/dnstap_tcp.tdir/dnstap_tcp.test b/testdata/dnstap_tcp.tdir/dnstap_tcp.test new file mode 100644 index 000000000..bf79b6d72 --- /dev/null +++ b/testdata/dnstap_tcp.tdir/dnstap_tcp.test @@ -0,0 +1,91 @@ +# #-- dnstap_tcp.test --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +. ../common.sh +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi + +# test if the server is up. +echo "> dig www.example.com." +dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile +echo "> check answer" +if grep "10.20.30.40" outfile; then + echo "OK" +else + echo "> cat logfiles" + cat tap.log + cat tap.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 +fi + +echo "> check tap.log for dnstap info" +# see if it logged the information in tap.log +# wait for a moment for filesystem to catch up. +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 10; fi +if grep "www.example.com" tap.log; then echo "yes it is in tap.log"; +else + echo "information not in tap.log" + echo "failed" + echo "> cat logfiles" + cat tap.log + cat tap.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 +fi + +echo "" +echo "> test disconnect from the upstream server" + +kill_pid $DNSTAP_SOCKET_PID +dig @127.0.0.1 -p $UNBOUND_PORT down.example.net. + +# bring log socket back up +$PRE/unbound-dnstap-socket -s "127.0.0.1@$TAP_PORT" -l -vvvv 2>tap2.errlog >tap2.log & +if test $? -ne 0; then + echo "could not start (again) unbound-dnstap-socket server" + exit 1 +fi +DNSTAP_SOCKET_PID=$! +echo "DNSTAP_SOCKET_PID=$DNSTAP_SOCKET_PID" >> .tpkg.var.test +# wait for the server to go up +wait_server_up "tap2.errlog" "start of service" + +dig @127.0.0.1 -p $UNBOUND_PORT up.example.net. +sleep 2 +dig @127.0.0.1 -p $UNBOUND_PORT up2.example.net. + +for x in down up up2; do + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 10; fi + if grep "$x.example.net" tap2.log; then echo "yes it is in tap2.log"; + else + echo "$x.example.net. information not in tap2.log" + echo "failed" + echo "> cat logfiles" + cat tap.log + cat tap.errlog + echo "> tap2 logfiles" + cat tap2.log + cat tap2.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 + fi +done + +echo "> OK" +exit 0 diff --git a/testdata/dnstap_tcp.tdir/dnstap_tcp.testns b/testdata/dnstap_tcp.tdir/dnstap_tcp.testns new file mode 100644 index 000000000..0c911ca5b --- /dev/null +++ b/testdata/dnstap_tcp.tdir/dnstap_tcp.testns @@ -0,0 +1,22 @@ +; nameserver test file +$ORIGIN example.com. +$TTL 3600 + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA NOERROR +ADJUST copy_id +SECTION QUESTION +www IN A +SECTION ANSWER +www IN A 10.20.30.40 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA SERVFAIL +ADJUST copy_id +SECTION QUESTION +www.example.net. IN A +ENTRY_END + diff --git a/testdata/dnstap_tcp.tdir/unbound_control.key b/testdata/dnstap_tcp.tdir/unbound_control.key new file mode 100644 index 000000000..d7c43a06b --- /dev/null +++ b/testdata/dnstap_tcp.tdir/unbound_control.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDD6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBa +rzPA0vlyuNtUsEN3qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvH +ST6JwUdIg0Lzg/USJ81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQAB +AoGAFT3e35MIgI4uDJJ8X0RfHp2NCO2LUg4TKbWical/C0W9vlR1/x80G1pE1d2Z +WotqJVWTrOq6eBox19RCgtLg2wPGk9uD62+9SDT37heWFlUCElWq50pQG6k9ThiG +DDypkZyZ/52+DdWybiaQJkuK6O5qQXuNAtVJMpghu4GnHAECQQDsupnZUQDpapzr +4FC4MSkL2+A1PRt6g4VhwoqOpJXaHfVnH6F7AwUuOLNwGdR5Cvv70pfJ7Jqg8L2m +Kxyl5bORAkEA09rn34YQ0pHJdHidbl2kInIuYTz09+TO3LWwan17nISH9aaYvVDr +p9x1B4Qzw9qyxT9oll7ze/5Rw/7C3AQj4QJAT2B2a+b8bkgAXBs4FbruL3rHoDJg +P2FQXSpVOWU4lg2LlsuFYvDtUMVUbZdLplanjZXcral3Y9W1Ub2M+ped8QJAYQN+ +aRpge7ys7vwIw7B36Bo3aOncF+ScYe+FkM5Tm7II/JHEofT7ZQwMP1vnxIlSkgbe +YvWqNB6a3NC99LikoQJBAM4UhDdRg63Tr6Idky6CQaH///zAN7nArJfffKGWFdw9 +DKrWpNqvYZtX/cfEJucKcRCm5YL8CKFYbQy4VoCxUcE= +-----END RSA PRIVATE KEY----- diff --git a/testdata/dnstap_tcp.tdir/unbound_control.pem b/testdata/dnstap_tcp.tdir/unbound_control.pem new file mode 100644 index 000000000..8f1ba87f1 --- /dev/null +++ b/testdata/dnstap_tcp.tdir/unbound_control.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBozCCAQwCCQD6XaN6FzW/4DANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1 +bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowGjEYMBYGA1UE +AxMPdW5ib3VuZC1jb250cm9sMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDD +6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBarzPA0vlyuNtUsEN3 +qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvHST6JwUdIg0Lzg/US +J81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQABMA0GCSqGSIb3DQEB +BQUAA4GBAGFAXmaQHuFgAuc6HVhYZJdToxLBhfxGpot4oZNjcb1Cdoz3OL34MU1B +9E5psj2PpGPIi8/RwoqBtAJHJ+J5cWngo03o4ZmdwKNSzaxlp141z/3rUtFqEHEC +iO6gPCT3U7dt6MyC7r6vdMqyW6aldP3CtwD0gQziKAMoj+TAfAcq +-----END CERTIFICATE----- diff --git a/testdata/dnstap_tcp.tdir/unbound_server.key b/testdata/dnstap_tcp.tdir/unbound_server.key new file mode 100644 index 000000000..4256c421d --- /dev/null +++ b/testdata/dnstap_tcp.tdir/unbound_server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQC3F7Jsv2u01pLL9rFnjsMU/IaCFUIz/624DcaE84Z4gjMl5kWA +3axQcqul1wlwSrbKwrony+d9hH/+MX0tZwvl8w3OmhmOAiaQ+SHCsIuOjVwQjX0s +RLB61Pz5+PAiVvnPa9JIYB5QrK6DVEsxIHj8MOc5JKORrnESsFDh6yeMeQIDAQAB +AoGAAuWoGBprTOA8UGfl5LqYkaNxSWumsYXxLMFjC8WCsjN1NbtQDDr1uAwodSZS +6ujzvX+ZTHnofs7y64XC8k34HTOCD2zlW7kijWbT8YjRYFU6o9F5zUGD9RCan0ds +sVscT2psLSzfdsmFAcbmnGdxYkXk2PC1FHtaqExxehralGUCQQDcqrg9uQKXlhQi +XAaPr8SiWvtRm2a9IMMZkRfUWZclPHq6fCWNuUaCD+cTat4wAuqeknAz33VEosw3 +fXGsok//AkEA1GjIHXrOcSlpfVJb6NeOBugjRtZ7ZDT5gbtnMS9ob0qntKV6saaL +CNmJwuD9Q3XkU5j1+uHvYGP2NzcJd2CjhwJACV0hNlVMe9w9fHvFN4Gw6WbM9ViP +0oS6YrJafYNTu5vGZXVxLoNnL4u3NYa6aPUmuZXjNwBLfJ8f5VboZPf6RwJAINd2 +oYA8bSi/A755MX4qmozH74r4Fx1Nuq5UHTm8RwDe/0Javx8F/j9MWpJY9lZDEF3l +In5OebPa/NyInSmW/wJAZuP9aRn0nDBkHYri++1A7NykMiJ/nH0mDECbnk+wxx0S +LwqIetBhxb8eQwMg45+iAH7CHAMQ8BQuF/nFE6eotg== +-----END RSA PRIVATE KEY----- diff --git a/testdata/dnstap_tcp.tdir/unbound_server.pem b/testdata/dnstap_tcp.tdir/unbound_server.pem new file mode 100644 index 000000000..aeda3ff11 --- /dev/null +++ b/testdata/dnstap_tcp.tdir/unbound_server.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBmzCCAQQCCQDsNJ1UmphEFzANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1 +bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowEjEQMA4GA1UE +AxMHdW5ib3VuZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtxeybL9rtNaS +y/axZ47DFPyGghVCM/+tuA3GhPOGeIIzJeZFgN2sUHKrpdcJcEq2ysK6J8vnfYR/ +/jF9LWcL5fMNzpoZjgImkPkhwrCLjo1cEI19LESwetT8+fjwIlb5z2vSSGAeUKyu +g1RLMSB4/DDnOSSjka5xErBQ4esnjHkCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAZ +9N0lnLENs4JMvPS+mn8C5m9bkkFITd32IiLjf0zgYpIUbFXH6XaEr9GNZBUG8feG +l/6WRXnbnVSblI5odQ4XxGZ9inYY6qtW30uv76HvoKp+QZ1c3460ddR8NauhcCHH +Z7S+QbLXi+r2JAhpPozZCjBHlRD0ixzA1mKQTJhJZg== +-----END CERTIFICATE----- From 4d3524f496d21fc328b86dd2b44ee75dfe96b12c Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 14 Feb 2020 14:44:02 +0100 Subject: [PATCH 74/96] dnstap io, test for TLS and reconnect for that. And fix unused parameters for dt_create and fix check of socket path when using IP address. --- daemon/daemon.c | 3 +- dnstap/dnstap.c | 14 +-- dnstap/dnstap.h | 4 +- testdata/dnstap_tcp.tdir/dnstap_tcp.conf | 2 +- testdata/dnstap_tcp.tdir/dnstap_tcp.post | 4 +- testdata/dnstap_tls.tdir/dnstap_tls.conf | 42 +++++++++ testdata/dnstap_tls.tdir/dnstap_tls.dsc | 16 ++++ testdata/dnstap_tls.tdir/dnstap_tls.post | 23 +++++ testdata/dnstap_tls.tdir/dnstap_tls.pre | 54 ++++++++++++ testdata/dnstap_tls.tdir/dnstap_tls.test | 91 ++++++++++++++++++++ testdata/dnstap_tls.tdir/dnstap_tls.testns | 22 +++++ testdata/dnstap_tls.tdir/unbound_control.key | 15 ++++ testdata/dnstap_tls.tdir/unbound_control.pem | 11 +++ testdata/dnstap_tls.tdir/unbound_server.key | 15 ++++ testdata/dnstap_tls.tdir/unbound_server.pem | 11 +++ 15 files changed, 312 insertions(+), 15 deletions(-) create mode 100644 testdata/dnstap_tls.tdir/dnstap_tls.conf create mode 100644 testdata/dnstap_tls.tdir/dnstap_tls.dsc create mode 100644 testdata/dnstap_tls.tdir/dnstap_tls.post create mode 100644 testdata/dnstap_tls.tdir/dnstap_tls.pre create mode 100644 testdata/dnstap_tls.tdir/dnstap_tls.test create mode 100644 testdata/dnstap_tls.tdir/dnstap_tls.testns create mode 100644 testdata/dnstap_tls.tdir/unbound_control.key create mode 100644 testdata/dnstap_tls.tdir/unbound_control.pem create mode 100644 testdata/dnstap_tls.tdir/unbound_server.key create mode 100644 testdata/dnstap_tls.tdir/unbound_server.pem diff --git a/daemon/daemon.c b/daemon/daemon.c index 48f2a721d..1e1dfd002 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -451,8 +451,7 @@ daemon_create_workers(struct daemon* daemon) fatal_exit("out of memory during daemon init"); if(daemon->cfg->dnstap) { #ifdef USE_DNSTAP - daemon->dtenv = dt_create(daemon->cfg->dnstap_socket_path, - (unsigned int)daemon->num, daemon->cfg); + daemon->dtenv = dt_create(daemon->cfg); if (!daemon->dtenv) fatal_exit("dt_create failed"); #else diff --git a/dnstap/dnstap.c b/dnstap/dnstap.c index 2787c73ec..c34f08b2e 100644 --- a/dnstap/dnstap.c +++ b/dnstap/dnstap.c @@ -128,16 +128,16 @@ check_socket_file(const char* socket_path) } struct dt_env * -dt_create(const char *socket_path, unsigned num_workers, - struct config_file* cfg) +dt_create(struct config_file* cfg) { struct dt_env *env; - verbose(VERB_OPS, "attempting to connect to dnstap socket %s", - socket_path); - log_assert(socket_path != NULL); - log_assert(num_workers > 0); - check_socket_file(socket_path); + if(cfg->dnstap && cfg->dnstap_socket_path && cfg->dnstap_socket_path[0] && + (cfg->dnstap_ip==NULL || cfg->dnstap_ip[0]==0)) { + verbose(VERB_OPS, "attempting to connect to dnstap socket %s", + cfg->dnstap_socket_path); + check_socket_file(cfg->dnstap_socket_path); + } env = (struct dt_env *) calloc(1, sizeof(struct dt_env)); if (!env) diff --git a/dnstap/dnstap.h b/dnstap/dnstap.h index c87a549aa..cfef6fc42 100644 --- a/dnstap/dnstap.h +++ b/dnstap/dnstap.h @@ -84,13 +84,11 @@ struct dt_env { * of the structure) to ensure lock-free access to its own per-worker circular * queue. Duplicate the environment object if more than one worker needs to * share access to the dnstap I/O socket. - * @param socket_path: path to dnstap logging socket, must be non-NULL. - * @param num_workers: number of worker threads, must be > 0. * @param cfg: with config settings. * @return dt_env object, NULL on failure. */ struct dt_env * -dt_create(const char *socket_path, unsigned num_workers, struct config_file* cfg); +dt_create(struct config_file* cfg); /** * Apply config settings. diff --git a/testdata/dnstap_tcp.tdir/dnstap_tcp.conf b/testdata/dnstap_tcp.tdir/dnstap_tcp.conf index 6aefaad1e..3506ab56a 100644 --- a/testdata/dnstap_tcp.tdir/dnstap_tcp.conf +++ b/testdata/dnstap_tcp.tdir/dnstap_tcp.conf @@ -26,7 +26,7 @@ forward-zone: forward-addr: "127.0.0.1@@TOPORT@" dnstap: dnstap-enable: yes - #dnstap-socket-path: "dnstap.socket" + dnstap-socket-path: "dnstap.socket" dnstap-ip: "127.0.0.1@@TAPPORT@" dnstap-tls: no dnstap-send-identity: yes diff --git a/testdata/dnstap_tcp.tdir/dnstap_tcp.post b/testdata/dnstap_tcp.tdir/dnstap_tcp.post index 64e30db17..8aad21e19 100644 --- a/testdata/dnstap_tcp.tdir/dnstap_tcp.post +++ b/testdata/dnstap_tcp.tdir/dnstap_tcp.post @@ -17,7 +17,7 @@ echo "> tap logfiles" cat tap.log cat tap.errlog echo "> tap2 logfiles" -cat tap2.log -cat tap2.errlog +if test -f tap2.log; then cat tap2.log; fi +if test -f tap2.errlog; then cat tap2.errlog; fi cat fwd.log exit 0 diff --git a/testdata/dnstap_tls.tdir/dnstap_tls.conf b/testdata/dnstap_tls.tdir/dnstap_tls.conf new file mode 100644 index 000000000..3bff3d1d0 --- /dev/null +++ b/testdata/dnstap_tls.tdir/dnstap_tls.conf @@ -0,0 +1,42 @@ +server: + verbosity: 2 + num-threads: 1 + outgoing-range: 16 + interface: 127.0.0.1 + port: @PORT@ + use-syslog: no + directory: "" + pidfile: "unbound.pid" + chroot: "" + username: "" + do-not-query-localhost: no + local-zone: "example.net." redirect + local-data: "example.net. IN A 10.20.30.41" +remote-control: + control-enable: yes + control-interface: 127.0.0.1 + # control-interface: ::1 + control-port: @CONTROL_PORT@ + server-key-file: "unbound_server.key" + server-cert-file: "unbound_server.pem" + control-key-file: "unbound_control.key" + control-cert-file: "unbound_control.pem" +forward-zone: + name: "." + forward-addr: "127.0.0.1@@TOPORT@" +dnstap: + dnstap-enable: yes + dnstap-socket-path: "dnstap.socket" + dnstap-ip: "127.0.0.1@@TAPPORT@" + dnstap-tls: yes + dnstap-send-identity: yes + dnstap-send-version: yes + #dnstap-identity + #dnstap-version + dnstap-log-resolver-query-messages: yes + dnstap-log-resolver-response-messages: yes + dnstap-log-client-query-messages: yes + dnstap-log-client-response-messages: yes + dnstap-log-forwarder-query-messages: yes + dnstap-log-forwarder-response-messages: yes + diff --git a/testdata/dnstap_tls.tdir/dnstap_tls.dsc b/testdata/dnstap_tls.tdir/dnstap_tls.dsc new file mode 100644 index 000000000..20a4467ce --- /dev/null +++ b/testdata/dnstap_tls.tdir/dnstap_tls.dsc @@ -0,0 +1,16 @@ +BaseName: dnstap_tls +Version: 1.0 +Description: test dnstap tls and reconnect +CreationDate: Tue Feb 14 14:00:38 CET 2020 +Maintainer: dr. W.C.A. Wijngaards +Category: +Component: +CmdDepends: +Depends: +Help: +Pre: dnstap_tls.pre +Post: dnstap_tls.post +Test: dnstap_tls.test +AuxFiles: +Passed: +Failure: diff --git a/testdata/dnstap_tls.tdir/dnstap_tls.post b/testdata/dnstap_tls.tdir/dnstap_tls.post new file mode 100644 index 000000000..fe1824a06 --- /dev/null +++ b/testdata/dnstap_tls.tdir/dnstap_tls.post @@ -0,0 +1,23 @@ +# #-- dnstap_tls.post --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# source the test var file when it's there +[ -f .tpkg.var.test ] && source .tpkg.var.test +# +# do your teardown here +. ../common.sh +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi +kill_pid $DNSTAP_SOCKET_PID +kill_pid $FWD_PID +kill $UNBOUND_PID +kill $UNBOUND_PID >/dev/null 2>&1 +cat unbound.log +echo "> tap logfiles" +cat tap.log +cat tap.errlog +echo "> tap2 logfiles" +if test -f tap2.log; then cat tap2.log; fi +if test -f tap2.errlog; then cat tap2.errlog; fi +cat fwd.log +exit 0 diff --git a/testdata/dnstap_tls.tdir/dnstap_tls.pre b/testdata/dnstap_tls.tdir/dnstap_tls.pre new file mode 100644 index 000000000..1df914873 --- /dev/null +++ b/testdata/dnstap_tls.tdir/dnstap_tls.pre @@ -0,0 +1,54 @@ +# #-- dnstap_tls.pre--# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +. ../common.sh + +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi + +get_random_port 4 +UNBOUND_PORT=$RND_PORT +FWD_PORT=$(($RND_PORT + 1)) +CONTROL_PORT=$(($RND_PORT + 2)) +TAP_PORT=$(($RND_PORT + 3)) +echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test +echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test +echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test +echo "TAP_PORT=$TAP_PORT" >> .tpkg.var.test + +# start forwarder +get_ldns_testns +$LDNS_TESTNS -p $FWD_PORT dnstap_tls.testns >fwd.log 2>&1 & +FWD_PID=$! +echo "FWD_PID=$FWD_PID" >> .tpkg.var.test + +# start the dnstap log server +# the -vvvv flag prints protocol and connection information from the +# unbound-dnstap-socket server. +# the -l flag prints the DNS info in the DNSTAP packet in multiline output. +# stderr is the '-vvvv' server logs and errors. +# stdout is the one-line packet logs (or with -l, multiline). +$PRE/unbound-dnstap-socket -t "127.0.0.1@$TAP_PORT" -x unbound_server.key -y unbound_server.pem -l -vvvv 2>tap.errlog >tap.log & +if test $? -ne 0; then + echo "could not start unbound-dnstap-socket server" + exit 1 +fi +DNSTAP_SOCKET_PID=$! +echo "DNSTAP_SOCKET_PID=$DNSTAP_SOCKET_PID" >> .tpkg.var.test +# wait for the server to go up +wait_server_up "tap.errlog" "start of service" + +# make config file +sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' -e 's/@TAPPORT\@/'$TAP_PORT'/' < dnstap_tls.conf > ub.conf +# start unbound in the background +$PRE/unbound -d -c ub.conf >unbound.log 2>&1 & +UNBOUND_PID=$! +echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test + +cat .tpkg.var.test +wait_ldns_testns_up fwd.log +wait_unbound_up unbound.log + diff --git a/testdata/dnstap_tls.tdir/dnstap_tls.test b/testdata/dnstap_tls.tdir/dnstap_tls.test new file mode 100644 index 000000000..64260eac8 --- /dev/null +++ b/testdata/dnstap_tls.tdir/dnstap_tls.test @@ -0,0 +1,91 @@ +# #-- dnstap_tls.test --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +. ../common.sh +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi + +# test if the server is up. +echo "> dig www.example.com." +dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile +echo "> check answer" +if grep "10.20.30.40" outfile; then + echo "OK" +else + echo "> cat logfiles" + cat tap.log + cat tap.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 +fi + +echo "> check tap.log for dnstap info" +# see if it logged the information in tap.log +# wait for a moment for filesystem to catch up. +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 10; fi +if grep "www.example.com" tap.log; then echo "yes it is in tap.log"; +else + echo "information not in tap.log" + echo "failed" + echo "> cat logfiles" + cat tap.log + cat tap.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 +fi + +echo "" +echo "> test disconnect from the upstream server" + +kill_pid $DNSTAP_SOCKET_PID +dig @127.0.0.1 -p $UNBOUND_PORT down.example.net. + +# bring log socket back up +$PRE/unbound-dnstap-socket -t "127.0.0.1@$TAP_PORT" -x unbound_server.key -y unbound_server.pem -l -vvvv 2>tap2.errlog >tap2.log & +if test $? -ne 0; then + echo "could not start (again) unbound-dnstap-socket server" + exit 1 +fi +DNSTAP_SOCKET_PID=$! +echo "DNSTAP_SOCKET_PID=$DNSTAP_SOCKET_PID" >> .tpkg.var.test +# wait for the server to go up +wait_server_up "tap2.errlog" "start of service" + +dig @127.0.0.1 -p $UNBOUND_PORT up.example.net. +sleep 2 +dig @127.0.0.1 -p $UNBOUND_PORT up2.example.net. + +for x in down up up2; do + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 10; fi + if grep "$x.example.net" tap2.log; then echo "yes it is in tap2.log"; + else + echo "$x.example.net. information not in tap2.log" + echo "failed" + echo "> cat logfiles" + cat tap.log + cat tap.errlog + echo "> tap2 logfiles" + cat tap2.log + cat tap2.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 + fi +done + +echo "> OK" +exit 0 diff --git a/testdata/dnstap_tls.tdir/dnstap_tls.testns b/testdata/dnstap_tls.tdir/dnstap_tls.testns new file mode 100644 index 000000000..0c911ca5b --- /dev/null +++ b/testdata/dnstap_tls.tdir/dnstap_tls.testns @@ -0,0 +1,22 @@ +; nameserver test file +$ORIGIN example.com. +$TTL 3600 + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA NOERROR +ADJUST copy_id +SECTION QUESTION +www IN A +SECTION ANSWER +www IN A 10.20.30.40 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA SERVFAIL +ADJUST copy_id +SECTION QUESTION +www.example.net. IN A +ENTRY_END + diff --git a/testdata/dnstap_tls.tdir/unbound_control.key b/testdata/dnstap_tls.tdir/unbound_control.key new file mode 100644 index 000000000..d7c43a06b --- /dev/null +++ b/testdata/dnstap_tls.tdir/unbound_control.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDD6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBa +rzPA0vlyuNtUsEN3qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvH +ST6JwUdIg0Lzg/USJ81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQAB +AoGAFT3e35MIgI4uDJJ8X0RfHp2NCO2LUg4TKbWical/C0W9vlR1/x80G1pE1d2Z +WotqJVWTrOq6eBox19RCgtLg2wPGk9uD62+9SDT37heWFlUCElWq50pQG6k9ThiG +DDypkZyZ/52+DdWybiaQJkuK6O5qQXuNAtVJMpghu4GnHAECQQDsupnZUQDpapzr +4FC4MSkL2+A1PRt6g4VhwoqOpJXaHfVnH6F7AwUuOLNwGdR5Cvv70pfJ7Jqg8L2m +Kxyl5bORAkEA09rn34YQ0pHJdHidbl2kInIuYTz09+TO3LWwan17nISH9aaYvVDr +p9x1B4Qzw9qyxT9oll7ze/5Rw/7C3AQj4QJAT2B2a+b8bkgAXBs4FbruL3rHoDJg +P2FQXSpVOWU4lg2LlsuFYvDtUMVUbZdLplanjZXcral3Y9W1Ub2M+ped8QJAYQN+ +aRpge7ys7vwIw7B36Bo3aOncF+ScYe+FkM5Tm7II/JHEofT7ZQwMP1vnxIlSkgbe +YvWqNB6a3NC99LikoQJBAM4UhDdRg63Tr6Idky6CQaH///zAN7nArJfffKGWFdw9 +DKrWpNqvYZtX/cfEJucKcRCm5YL8CKFYbQy4VoCxUcE= +-----END RSA PRIVATE KEY----- diff --git a/testdata/dnstap_tls.tdir/unbound_control.pem b/testdata/dnstap_tls.tdir/unbound_control.pem new file mode 100644 index 000000000..8f1ba87f1 --- /dev/null +++ b/testdata/dnstap_tls.tdir/unbound_control.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBozCCAQwCCQD6XaN6FzW/4DANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1 +bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowGjEYMBYGA1UE +AxMPdW5ib3VuZC1jb250cm9sMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDD +6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBarzPA0vlyuNtUsEN3 +qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvHST6JwUdIg0Lzg/US +J81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQABMA0GCSqGSIb3DQEB +BQUAA4GBAGFAXmaQHuFgAuc6HVhYZJdToxLBhfxGpot4oZNjcb1Cdoz3OL34MU1B +9E5psj2PpGPIi8/RwoqBtAJHJ+J5cWngo03o4ZmdwKNSzaxlp141z/3rUtFqEHEC +iO6gPCT3U7dt6MyC7r6vdMqyW6aldP3CtwD0gQziKAMoj+TAfAcq +-----END CERTIFICATE----- diff --git a/testdata/dnstap_tls.tdir/unbound_server.key b/testdata/dnstap_tls.tdir/unbound_server.key new file mode 100644 index 000000000..4256c421d --- /dev/null +++ b/testdata/dnstap_tls.tdir/unbound_server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQC3F7Jsv2u01pLL9rFnjsMU/IaCFUIz/624DcaE84Z4gjMl5kWA +3axQcqul1wlwSrbKwrony+d9hH/+MX0tZwvl8w3OmhmOAiaQ+SHCsIuOjVwQjX0s +RLB61Pz5+PAiVvnPa9JIYB5QrK6DVEsxIHj8MOc5JKORrnESsFDh6yeMeQIDAQAB +AoGAAuWoGBprTOA8UGfl5LqYkaNxSWumsYXxLMFjC8WCsjN1NbtQDDr1uAwodSZS +6ujzvX+ZTHnofs7y64XC8k34HTOCD2zlW7kijWbT8YjRYFU6o9F5zUGD9RCan0ds +sVscT2psLSzfdsmFAcbmnGdxYkXk2PC1FHtaqExxehralGUCQQDcqrg9uQKXlhQi +XAaPr8SiWvtRm2a9IMMZkRfUWZclPHq6fCWNuUaCD+cTat4wAuqeknAz33VEosw3 +fXGsok//AkEA1GjIHXrOcSlpfVJb6NeOBugjRtZ7ZDT5gbtnMS9ob0qntKV6saaL +CNmJwuD9Q3XkU5j1+uHvYGP2NzcJd2CjhwJACV0hNlVMe9w9fHvFN4Gw6WbM9ViP +0oS6YrJafYNTu5vGZXVxLoNnL4u3NYa6aPUmuZXjNwBLfJ8f5VboZPf6RwJAINd2 +oYA8bSi/A755MX4qmozH74r4Fx1Nuq5UHTm8RwDe/0Javx8F/j9MWpJY9lZDEF3l +In5OebPa/NyInSmW/wJAZuP9aRn0nDBkHYri++1A7NykMiJ/nH0mDECbnk+wxx0S +LwqIetBhxb8eQwMg45+iAH7CHAMQ8BQuF/nFE6eotg== +-----END RSA PRIVATE KEY----- diff --git a/testdata/dnstap_tls.tdir/unbound_server.pem b/testdata/dnstap_tls.tdir/unbound_server.pem new file mode 100644 index 000000000..aeda3ff11 --- /dev/null +++ b/testdata/dnstap_tls.tdir/unbound_server.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBmzCCAQQCCQDsNJ1UmphEFzANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1 +bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowEjEQMA4GA1UE +AxMHdW5ib3VuZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtxeybL9rtNaS +y/axZ47DFPyGghVCM/+tuA3GhPOGeIIzJeZFgN2sUHKrpdcJcEq2ysK6J8vnfYR/ +/jF9LWcL5fMNzpoZjgImkPkhwrCLjo1cEI19LESwetT8+fjwIlb5z2vSSGAeUKyu +g1RLMSB4/DDnOSSjka5xErBQ4esnjHkCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAZ +9N0lnLENs4JMvPS+mn8C5m9bkkFITd32IiLjf0zgYpIUbFXH6XaEr9GNZBUG8feG +l/6WRXnbnVSblI5odQ4XxGZ9inYY6qtW30uv76HvoKp+QZ1c3460ddR8NauhcCHH +Z7S+QbLXi+r2JAhpPozZCjBHlRD0ixzA1mKQTJhJZg== +-----END CERTIFICATE----- From 7b19ba3d57138871c8c17ac22acfa301847892fa Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 14 Feb 2020 15:41:17 +0100 Subject: [PATCH 75/96] dnstap io, fix spinning reconnect when handshake fails for TLS. --- dnstap/dtstream.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index ba545dd7c..27a3d570c 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -65,6 +65,8 @@ #define DTIO_RECONNECT_TIMEOUT_MIN 10 /** the msec to wait for reconnect max after backoff */ #define DTIO_RECONNECT_TIMEOUT_MAX 1000 +/** the msec to wait for reconnect slow, to stop busy spinning on reconnect */ +#define DTIO_RECONNECT_TIMEOUT_SLOW 1000 struct stop_flush_info; /** DTIO command channel commands */ @@ -529,6 +531,14 @@ static void dtio_reconnect_clear(struct dt_io_thread* dtio) dtio_reconnect_del(dtio); } +/** reconnect slowly, because we already know we have to wait for a bit */ +static void dtio_reconnect_slow(struct dt_io_thread* dtio, int msec) +{ + dtio_reconnect_del(dtio); + dtio->reconnect_timeout = msec; + dtio_reconnect_enable(dtio); +} + /** delete the current message in the dtio, and reset counters */ static void dtio_cur_msg_free(struct dt_io_thread* dtio) { @@ -1078,6 +1088,7 @@ static int dtio_ssl_handshake(struct dt_io_thread* dtio, /* closed */ if(info) dtio_stop_flush_exit(info); dtio_del_output_event(dtio); + dtio_reconnect_slow(dtio, DTIO_RECONNECT_TIMEOUT_SLOW); dtio_close_output(dtio); return 0; } else if(want == SSL_ERROR_SYSCALL) { @@ -1099,6 +1110,7 @@ static int dtio_ssl_handshake(struct dt_io_thread* dtio, /* closed */ if(info) dtio_stop_flush_exit(info); dtio_del_output_event(dtio); + dtio_reconnect_slow(dtio, DTIO_RECONNECT_TIMEOUT_SLOW); dtio_close_output(dtio); return 0; } else { @@ -1112,6 +1124,7 @@ static int dtio_ssl_handshake(struct dt_io_thread* dtio, /* closed */ if(info) dtio_stop_flush_exit(info); dtio_del_output_event(dtio); + dtio_reconnect_slow(dtio, DTIO_RECONNECT_TIMEOUT_SLOW); dtio_close_output(dtio); return 0; } @@ -1124,6 +1137,7 @@ static int dtio_ssl_handshake(struct dt_io_thread* dtio, /* closed */ if(info) dtio_stop_flush_exit(info); dtio_del_output_event(dtio); + dtio_reconnect_slow(dtio, DTIO_RECONNECT_TIMEOUT_SLOW); dtio_close_output(dtio); return 0; } From 2106692a891048e1d4a7de5232ca44c8561bcb66 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 14 Feb 2020 15:44:55 +0100 Subject: [PATCH 76/96] dnstap io, test TLS with peername and TLS authentication. --- .../dnstap_tls_peername.conf | 44 +++++++++ .../dnstap_tls_peername.dsc | 16 ++++ .../dnstap_tls_peername.post | 23 +++++ .../dnstap_tls_peername.pre | 54 +++++++++++ .../dnstap_tls_peername.test | 91 +++++++++++++++++++ .../dnstap_tls_peername.testns | 22 +++++ .../unbound_control.key | 15 +++ .../unbound_control.pem | 11 +++ .../unbound_server.key | 15 +++ .../unbound_server.pem | 11 +++ 10 files changed, 302 insertions(+) create mode 100644 testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.conf create mode 100644 testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.dsc create mode 100644 testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.post create mode 100644 testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.pre create mode 100644 testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.test create mode 100644 testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.testns create mode 100644 testdata/dnstap_tls_peername.tdir/unbound_control.key create mode 100644 testdata/dnstap_tls_peername.tdir/unbound_control.pem create mode 100644 testdata/dnstap_tls_peername.tdir/unbound_server.key create mode 100644 testdata/dnstap_tls_peername.tdir/unbound_server.pem diff --git a/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.conf b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.conf new file mode 100644 index 000000000..55f844ae4 --- /dev/null +++ b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.conf @@ -0,0 +1,44 @@ +server: + verbosity: 4 + num-threads: 1 + outgoing-range: 16 + interface: 127.0.0.1 + port: @PORT@ + use-syslog: no + directory: "" + pidfile: "unbound.pid" + chroot: "" + username: "" + do-not-query-localhost: no + local-zone: "example.net." redirect + local-data: "example.net. IN A 10.20.30.41" +remote-control: + control-enable: yes + control-interface: 127.0.0.1 + # control-interface: ::1 + control-port: @CONTROL_PORT@ + server-key-file: "unbound_server.key" + server-cert-file: "unbound_server.pem" + control-key-file: "unbound_control.key" + control-cert-file: "unbound_control.pem" +forward-zone: + name: "." + forward-addr: "127.0.0.1@@TOPORT@" +dnstap: + dnstap-enable: yes + dnstap-socket-path: "dnstap.socket" + dnstap-ip: "127.0.0.1@@TAPPORT@" + dnstap-tls: yes + dnstap-tls-server-name: "unbound" + dnstap-tls-cert-bundle: "unbound_server.pem" + dnstap-send-identity: yes + dnstap-send-version: yes + #dnstap-identity + #dnstap-version + dnstap-log-resolver-query-messages: yes + dnstap-log-resolver-response-messages: yes + dnstap-log-client-query-messages: yes + dnstap-log-client-response-messages: yes + dnstap-log-forwarder-query-messages: yes + dnstap-log-forwarder-response-messages: yes + diff --git a/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.dsc b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.dsc new file mode 100644 index 000000000..d011d5ece --- /dev/null +++ b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.dsc @@ -0,0 +1,16 @@ +BaseName: dnstap_tls_peername +Version: 1.0 +Description: test dnstap tls and reconnect +CreationDate: Tue Feb 14 14:00:38 CET 2020 +Maintainer: dr. W.C.A. Wijngaards +Category: +Component: +CmdDepends: +Depends: +Help: +Pre: dnstap_tls_peername.pre +Post: dnstap_tls_peername.post +Test: dnstap_tls_peername.test +AuxFiles: +Passed: +Failure: diff --git a/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.post b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.post new file mode 100644 index 000000000..b2c29d0da --- /dev/null +++ b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.post @@ -0,0 +1,23 @@ +# #-- dnstap_tls_peername.post --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# source the test var file when it's there +[ -f .tpkg.var.test ] && source .tpkg.var.test +# +# do your teardown here +. ../common.sh +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi +kill_pid $DNSTAP_SOCKET_PID +kill_pid $FWD_PID +kill $UNBOUND_PID +kill $UNBOUND_PID >/dev/null 2>&1 +cat unbound.log +echo "> tap logfiles" +cat tap.log +cat tap.errlog +echo "> tap2 logfiles" +if test -f tap2.log; then cat tap2.log; fi +if test -f tap2.errlog; then cat tap2.errlog; fi +cat fwd.log +exit 0 diff --git a/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.pre b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.pre new file mode 100644 index 000000000..25b838d8b --- /dev/null +++ b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.pre @@ -0,0 +1,54 @@ +# #-- dnstap_tls_peername.pre--# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +. ../common.sh + +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi + +get_random_port 4 +UNBOUND_PORT=$RND_PORT +FWD_PORT=$(($RND_PORT + 1)) +CONTROL_PORT=$(($RND_PORT + 2)) +TAP_PORT=$(($RND_PORT + 3)) +echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test +echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test +echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test +echo "TAP_PORT=$TAP_PORT" >> .tpkg.var.test + +# start forwarder +get_ldns_testns +$LDNS_TESTNS -p $FWD_PORT dnstap_tls_peername.testns >fwd.log 2>&1 & +FWD_PID=$! +echo "FWD_PID=$FWD_PID" >> .tpkg.var.test + +# start the dnstap log server +# the -vvvv flag prints protocol and connection information from the +# unbound-dnstap-socket server. +# the -l flag prints the DNS info in the DNSTAP packet in multiline output. +# stderr is the '-vvvv' server logs and errors. +# stdout is the one-line packet logs (or with -l, multiline). +$PRE/unbound-dnstap-socket -t "127.0.0.1@$TAP_PORT" -x unbound_server.key -y unbound_server.pem -l -vvvv 2>tap.errlog >tap.log & +if test $? -ne 0; then + echo "could not start unbound-dnstap-socket server" + exit 1 +fi +DNSTAP_SOCKET_PID=$! +echo "DNSTAP_SOCKET_PID=$DNSTAP_SOCKET_PID" >> .tpkg.var.test +# wait for the server to go up +wait_server_up "tap.errlog" "start of service" + +# make config file +sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' -e 's/@TAPPORT\@/'$TAP_PORT'/' < dnstap_tls_peername.conf > ub.conf +# start unbound in the background +$PRE/unbound -d -c ub.conf >unbound.log 2>&1 & +UNBOUND_PID=$! +echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test + +cat .tpkg.var.test +wait_ldns_testns_up fwd.log +wait_unbound_up unbound.log + diff --git a/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.test b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.test new file mode 100644 index 000000000..6082c3a89 --- /dev/null +++ b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.test @@ -0,0 +1,91 @@ +# #-- dnstap_tls_peername.test --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +. ../common.sh +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi + +# test if the server is up. +echo "> dig www.example.com." +dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile +echo "> check answer" +if grep "10.20.30.40" outfile; then + echo "OK" +else + echo "> cat logfiles" + cat tap.log + cat tap.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 +fi + +echo "> check tap.log for dnstap info" +# see if it logged the information in tap.log +# wait for a moment for filesystem to catch up. +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 10; fi +if grep "www.example.com" tap.log; then echo "yes it is in tap.log"; +else + echo "information not in tap.log" + echo "failed" + echo "> cat logfiles" + cat tap.log + cat tap.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 +fi + +echo "" +echo "> test disconnect from the upstream server" + +kill_pid $DNSTAP_SOCKET_PID +dig @127.0.0.1 -p $UNBOUND_PORT down.example.net. + +# bring log socket back up +$PRE/unbound-dnstap-socket -t "127.0.0.1@$TAP_PORT" -x unbound_server.key -y unbound_server.pem -l -vvvv 2>tap2.errlog >tap2.log & +if test $? -ne 0; then + echo "could not start (again) unbound-dnstap-socket server" + exit 1 +fi +DNSTAP_SOCKET_PID=$! +echo "DNSTAP_SOCKET_PID=$DNSTAP_SOCKET_PID" >> .tpkg.var.test +# wait for the server to go up +wait_server_up "tap2.errlog" "start of service" + +dig @127.0.0.1 -p $UNBOUND_PORT up.example.net. +sleep 2 +dig @127.0.0.1 -p $UNBOUND_PORT up2.example.net. + +for x in down up up2; do + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 10; fi + if grep "$x.example.net" tap2.log; then echo "yes it is in tap2.log"; + else + echo "$x.example.net. information not in tap2.log" + echo "failed" + echo "> cat logfiles" + cat tap.log + cat tap.errlog + echo "> tap2 logfiles" + cat tap2.log + cat tap2.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 + fi +done + +echo "> OK" +exit 0 diff --git a/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.testns b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.testns new file mode 100644 index 000000000..0c911ca5b --- /dev/null +++ b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.testns @@ -0,0 +1,22 @@ +; nameserver test file +$ORIGIN example.com. +$TTL 3600 + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA NOERROR +ADJUST copy_id +SECTION QUESTION +www IN A +SECTION ANSWER +www IN A 10.20.30.40 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA SERVFAIL +ADJUST copy_id +SECTION QUESTION +www.example.net. IN A +ENTRY_END + diff --git a/testdata/dnstap_tls_peername.tdir/unbound_control.key b/testdata/dnstap_tls_peername.tdir/unbound_control.key new file mode 100644 index 000000000..d7c43a06b --- /dev/null +++ b/testdata/dnstap_tls_peername.tdir/unbound_control.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDD6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBa +rzPA0vlyuNtUsEN3qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvH +ST6JwUdIg0Lzg/USJ81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQAB +AoGAFT3e35MIgI4uDJJ8X0RfHp2NCO2LUg4TKbWical/C0W9vlR1/x80G1pE1d2Z +WotqJVWTrOq6eBox19RCgtLg2wPGk9uD62+9SDT37heWFlUCElWq50pQG6k9ThiG +DDypkZyZ/52+DdWybiaQJkuK6O5qQXuNAtVJMpghu4GnHAECQQDsupnZUQDpapzr +4FC4MSkL2+A1PRt6g4VhwoqOpJXaHfVnH6F7AwUuOLNwGdR5Cvv70pfJ7Jqg8L2m +Kxyl5bORAkEA09rn34YQ0pHJdHidbl2kInIuYTz09+TO3LWwan17nISH9aaYvVDr +p9x1B4Qzw9qyxT9oll7ze/5Rw/7C3AQj4QJAT2B2a+b8bkgAXBs4FbruL3rHoDJg +P2FQXSpVOWU4lg2LlsuFYvDtUMVUbZdLplanjZXcral3Y9W1Ub2M+ped8QJAYQN+ +aRpge7ys7vwIw7B36Bo3aOncF+ScYe+FkM5Tm7II/JHEofT7ZQwMP1vnxIlSkgbe +YvWqNB6a3NC99LikoQJBAM4UhDdRg63Tr6Idky6CQaH///zAN7nArJfffKGWFdw9 +DKrWpNqvYZtX/cfEJucKcRCm5YL8CKFYbQy4VoCxUcE= +-----END RSA PRIVATE KEY----- diff --git a/testdata/dnstap_tls_peername.tdir/unbound_control.pem b/testdata/dnstap_tls_peername.tdir/unbound_control.pem new file mode 100644 index 000000000..8f1ba87f1 --- /dev/null +++ b/testdata/dnstap_tls_peername.tdir/unbound_control.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBozCCAQwCCQD6XaN6FzW/4DANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1 +bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowGjEYMBYGA1UE +AxMPdW5ib3VuZC1jb250cm9sMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDD +6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBarzPA0vlyuNtUsEN3 +qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvHST6JwUdIg0Lzg/US +J81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQABMA0GCSqGSIb3DQEB +BQUAA4GBAGFAXmaQHuFgAuc6HVhYZJdToxLBhfxGpot4oZNjcb1Cdoz3OL34MU1B +9E5psj2PpGPIi8/RwoqBtAJHJ+J5cWngo03o4ZmdwKNSzaxlp141z/3rUtFqEHEC +iO6gPCT3U7dt6MyC7r6vdMqyW6aldP3CtwD0gQziKAMoj+TAfAcq +-----END CERTIFICATE----- diff --git a/testdata/dnstap_tls_peername.tdir/unbound_server.key b/testdata/dnstap_tls_peername.tdir/unbound_server.key new file mode 100644 index 000000000..4256c421d --- /dev/null +++ b/testdata/dnstap_tls_peername.tdir/unbound_server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQC3F7Jsv2u01pLL9rFnjsMU/IaCFUIz/624DcaE84Z4gjMl5kWA +3axQcqul1wlwSrbKwrony+d9hH/+MX0tZwvl8w3OmhmOAiaQ+SHCsIuOjVwQjX0s +RLB61Pz5+PAiVvnPa9JIYB5QrK6DVEsxIHj8MOc5JKORrnESsFDh6yeMeQIDAQAB +AoGAAuWoGBprTOA8UGfl5LqYkaNxSWumsYXxLMFjC8WCsjN1NbtQDDr1uAwodSZS +6ujzvX+ZTHnofs7y64XC8k34HTOCD2zlW7kijWbT8YjRYFU6o9F5zUGD9RCan0ds +sVscT2psLSzfdsmFAcbmnGdxYkXk2PC1FHtaqExxehralGUCQQDcqrg9uQKXlhQi +XAaPr8SiWvtRm2a9IMMZkRfUWZclPHq6fCWNuUaCD+cTat4wAuqeknAz33VEosw3 +fXGsok//AkEA1GjIHXrOcSlpfVJb6NeOBugjRtZ7ZDT5gbtnMS9ob0qntKV6saaL +CNmJwuD9Q3XkU5j1+uHvYGP2NzcJd2CjhwJACV0hNlVMe9w9fHvFN4Gw6WbM9ViP +0oS6YrJafYNTu5vGZXVxLoNnL4u3NYa6aPUmuZXjNwBLfJ8f5VboZPf6RwJAINd2 +oYA8bSi/A755MX4qmozH74r4Fx1Nuq5UHTm8RwDe/0Javx8F/j9MWpJY9lZDEF3l +In5OebPa/NyInSmW/wJAZuP9aRn0nDBkHYri++1A7NykMiJ/nH0mDECbnk+wxx0S +LwqIetBhxb8eQwMg45+iAH7CHAMQ8BQuF/nFE6eotg== +-----END RSA PRIVATE KEY----- diff --git a/testdata/dnstap_tls_peername.tdir/unbound_server.pem b/testdata/dnstap_tls_peername.tdir/unbound_server.pem new file mode 100644 index 000000000..aeda3ff11 --- /dev/null +++ b/testdata/dnstap_tls_peername.tdir/unbound_server.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBmzCCAQQCCQDsNJ1UmphEFzANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1 +bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowEjEQMA4GA1UE +AxMHdW5ib3VuZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtxeybL9rtNaS +y/axZ47DFPyGghVCM/+tuA3GhPOGeIIzJeZFgN2sUHKrpdcJcEq2ysK6J8vnfYR/ +/jF9LWcL5fMNzpoZjgImkPkhwrCLjo1cEI19LESwetT8+fjwIlb5z2vSSGAeUKyu +g1RLMSB4/DDnOSSjka5xErBQ4esnjHkCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAZ +9N0lnLENs4JMvPS+mn8C5m9bkkFITd32IiLjf0zgYpIUbFXH6XaEr9GNZBUG8feG +l/6WRXnbnVSblI5odQ4XxGZ9inYY6qtW30uv76HvoKp+QZ1c3460ddR8NauhcCHH +Z7S+QbLXi+r2JAhpPozZCjBHlRD0ixzA1mKQTJhJZg== +-----END CERTIFICATE----- From 9556d595368ae0c63823775c4feb96d57c5c34f0 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 18 Feb 2020 14:18:03 +0100 Subject: [PATCH 77/96] dnstap io, test that failed name or auth certificate fails to connect tls. --- testdata/dnstap.tdir/dnstap.test | 4 ++ testdata/dnstap_tcp.tdir/dnstap_tcp.test | 4 ++ testdata/dnstap_tls.tdir/dnstap_tls.test | 4 ++ .../dnstap_tls_badcert.conf | 48 +++++++++++++++++ .../dnstap_tls_badcert.dsc | 16 ++++++ .../dnstap_tls_badcert.post | 20 +++++++ .../dnstap_tls_badcert.pre | 54 +++++++++++++++++++ .../dnstap_tls_badcert.test | 51 ++++++++++++++++++ .../dnstap_tls_badcert.testns | 22 ++++++++ .../unbound_control.key | 15 ++++++ .../unbound_control.pem | 11 ++++ .../unbound_server.key | 15 ++++++ .../unbound_server.pem | 11 ++++ .../dnstap_tls_badname.conf | 46 ++++++++++++++++ .../dnstap_tls_badname.dsc | 16 ++++++ .../dnstap_tls_badname.post | 20 +++++++ .../dnstap_tls_badname.pre | 54 +++++++++++++++++++ .../dnstap_tls_badname.test | 51 ++++++++++++++++++ .../dnstap_tls_badname.testns | 22 ++++++++ .../unbound_control.key | 15 ++++++ .../unbound_control.pem | 11 ++++ .../unbound_server.key | 15 ++++++ .../unbound_server.pem | 11 ++++ .../dnstap_tls_peername.dsc | 2 +- .../dnstap_tls_peername.post | 3 -- .../dnstap_tls_peername.test | 45 +--------------- 26 files changed, 539 insertions(+), 47 deletions(-) create mode 100644 testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.conf create mode 100644 testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.dsc create mode 100644 testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.post create mode 100644 testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.pre create mode 100644 testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.test create mode 100644 testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.testns create mode 100644 testdata/dnstap_tls_badcert.tdir/unbound_control.key create mode 100644 testdata/dnstap_tls_badcert.tdir/unbound_control.pem create mode 100644 testdata/dnstap_tls_badcert.tdir/unbound_server.key create mode 100644 testdata/dnstap_tls_badcert.tdir/unbound_server.pem create mode 100644 testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.conf create mode 100644 testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.dsc create mode 100644 testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.post create mode 100644 testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.pre create mode 100644 testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.test create mode 100644 testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.testns create mode 100644 testdata/dnstap_tls_badname.tdir/unbound_control.key create mode 100644 testdata/dnstap_tls_badname.tdir/unbound_control.pem create mode 100644 testdata/dnstap_tls_badname.tdir/unbound_server.key create mode 100644 testdata/dnstap_tls_badname.tdir/unbound_server.pem diff --git a/testdata/dnstap.tdir/dnstap.test b/testdata/dnstap.tdir/dnstap.test index 4ee4daf4c..04db17b27 100644 --- a/testdata/dnstap.tdir/dnstap.test +++ b/testdata/dnstap.tdir/dnstap.test @@ -30,6 +30,8 @@ echo "> check tap.log for dnstap info" if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi if grep "www.example.com" tap.log >/dev/null; then :; else sleep 10; fi if grep "www.example.com" tap.log; then echo "yes it is in tap.log"; else @@ -56,6 +58,8 @@ dig @127.0.0.1 -p $UNBOUND_PORT q8.example.net. dig @127.0.0.1 -p $UNBOUND_PORT q9.example.net. dig @127.0.0.1 -p $UNBOUND_PORT q10.example.net. for x in q1 q2 q3 q4 5 q6 q7 q8 q9 q10; do + if grep "$x.example.net" tap.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap.log >/dev/null; then :; else sleep 1; fi if grep "$x.example.net" tap.log >/dev/null; then :; else sleep 1; fi if grep "$x.example.net" tap.log >/dev/null; then :; else sleep 1; fi if grep "$x.example.net" tap.log >/dev/null; then :; else sleep 1; fi diff --git a/testdata/dnstap_tcp.tdir/dnstap_tcp.test b/testdata/dnstap_tcp.tdir/dnstap_tcp.test index bf79b6d72..d57eecfdb 100644 --- a/testdata/dnstap_tcp.tdir/dnstap_tcp.test +++ b/testdata/dnstap_tcp.tdir/dnstap_tcp.test @@ -30,6 +30,8 @@ echo "> check tap.log for dnstap info" if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi if grep "www.example.com" tap.log >/dev/null; then :; else sleep 10; fi if grep "www.example.com" tap.log; then echo "yes it is in tap.log"; else @@ -66,6 +68,8 @@ sleep 2 dig @127.0.0.1 -p $UNBOUND_PORT up2.example.net. for x in down up up2; do + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi diff --git a/testdata/dnstap_tls.tdir/dnstap_tls.test b/testdata/dnstap_tls.tdir/dnstap_tls.test index 64260eac8..f9a2bf00d 100644 --- a/testdata/dnstap_tls.tdir/dnstap_tls.test +++ b/testdata/dnstap_tls.tdir/dnstap_tls.test @@ -30,6 +30,8 @@ echo "> check tap.log for dnstap info" if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi if grep "www.example.com" tap.log >/dev/null; then :; else sleep 10; fi if grep "www.example.com" tap.log; then echo "yes it is in tap.log"; else @@ -66,6 +68,8 @@ sleep 2 dig @127.0.0.1 -p $UNBOUND_PORT up2.example.net. for x in down up up2; do + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi + if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi diff --git a/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.conf b/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.conf new file mode 100644 index 000000000..32698b621 --- /dev/null +++ b/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.conf @@ -0,0 +1,48 @@ +server: + verbosity: 4 + num-threads: 1 + outgoing-range: 16 + interface: 127.0.0.1 + port: @PORT@ + use-syslog: no + directory: "" + pidfile: "unbound.pid" + chroot: "" + username: "" + do-not-query-localhost: no + local-zone: "example.net." redirect + local-data: "example.net. IN A 10.20.30.41" +remote-control: + control-enable: yes + control-interface: 127.0.0.1 + # control-interface: ::1 + control-port: @CONTROL_PORT@ + server-key-file: "unbound_server.key" + server-cert-file: "unbound_server.pem" + control-key-file: "unbound_control.key" + control-cert-file: "unbound_control.pem" +forward-zone: + name: "." + forward-addr: "127.0.0.1@@TOPORT@" +dnstap: + dnstap-enable: yes + dnstap-socket-path: "dnstap.socket" + dnstap-ip: "127.0.0.1@@TAPPORT@" + dnstap-tls: yes + dnstap-tls-server-name: "unbound" + # the actual tls cert bundle that authenticates the server + # is the unbound_server.pem bundle. + # we pass the wrong bundle. (of another key we also use in the client + # authentication test) + dnstap-tls-cert-bundle: "unbound_control.pem" + dnstap-send-identity: yes + dnstap-send-version: yes + #dnstap-identity + #dnstap-version + dnstap-log-resolver-query-messages: yes + dnstap-log-resolver-response-messages: yes + dnstap-log-client-query-messages: yes + dnstap-log-client-response-messages: yes + dnstap-log-forwarder-query-messages: yes + dnstap-log-forwarder-response-messages: yes + diff --git a/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.dsc b/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.dsc new file mode 100644 index 000000000..e495e6c99 --- /dev/null +++ b/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.dsc @@ -0,0 +1,16 @@ +BaseName: dnstap_tls_badcert +Version: 1.0 +Description: test dnstap tls with bad cert for authentication +CreationDate: Tue Feb 14 14:00:38 CET 2020 +Maintainer: dr. W.C.A. Wijngaards +Category: +Component: +CmdDepends: +Depends: +Help: +Pre: dnstap_tls_badcert.pre +Post: dnstap_tls_badcert.post +Test: dnstap_tls_badcert.test +AuxFiles: +Passed: +Failure: diff --git a/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.post b/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.post new file mode 100644 index 000000000..d71eb28ae --- /dev/null +++ b/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.post @@ -0,0 +1,20 @@ +# #-- dnstap_tls_badcert.post --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# source the test var file when it's there +[ -f .tpkg.var.test ] && source .tpkg.var.test +# +# do your teardown here +. ../common.sh +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi +kill_pid $DNSTAP_SOCKET_PID +kill_pid $FWD_PID +kill $UNBOUND_PID +kill $UNBOUND_PID >/dev/null 2>&1 +cat unbound.log +echo "> tap logfiles" +cat tap.log +cat tap.errlog +cat fwd.log +exit 0 diff --git a/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.pre b/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.pre new file mode 100644 index 000000000..eff7074d0 --- /dev/null +++ b/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.pre @@ -0,0 +1,54 @@ +# #-- dnstap_tls_badcert.pre--# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +. ../common.sh + +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi + +get_random_port 4 +UNBOUND_PORT=$RND_PORT +FWD_PORT=$(($RND_PORT + 1)) +CONTROL_PORT=$(($RND_PORT + 2)) +TAP_PORT=$(($RND_PORT + 3)) +echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test +echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test +echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test +echo "TAP_PORT=$TAP_PORT" >> .tpkg.var.test + +# start forwarder +get_ldns_testns +$LDNS_TESTNS -p $FWD_PORT dnstap_tls_badcert.testns >fwd.log 2>&1 & +FWD_PID=$! +echo "FWD_PID=$FWD_PID" >> .tpkg.var.test + +# start the dnstap log server +# the -vvvv flag prints protocol and connection information from the +# unbound-dnstap-socket server. +# the -l flag prints the DNS info in the DNSTAP packet in multiline output. +# stderr is the '-vvvv' server logs and errors. +# stdout is the one-line packet logs (or with -l, multiline). +$PRE/unbound-dnstap-socket -t "127.0.0.1@$TAP_PORT" -x unbound_server.key -y unbound_server.pem -l -vvvv 2>tap.errlog >tap.log & +if test $? -ne 0; then + echo "could not start unbound-dnstap-socket server" + exit 1 +fi +DNSTAP_SOCKET_PID=$! +echo "DNSTAP_SOCKET_PID=$DNSTAP_SOCKET_PID" >> .tpkg.var.test +# wait for the server to go up +wait_server_up "tap.errlog" "start of service" + +# make config file +sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' -e 's/@TAPPORT\@/'$TAP_PORT'/' < dnstap_tls_badcert.conf > ub.conf +# start unbound in the background +$PRE/unbound -d -c ub.conf >unbound.log 2>&1 & +UNBOUND_PID=$! +echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test + +cat .tpkg.var.test +wait_ldns_testns_up fwd.log +wait_unbound_up unbound.log + diff --git a/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.test b/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.test new file mode 100644 index 000000000..0b85f64ac --- /dev/null +++ b/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.test @@ -0,0 +1,51 @@ +# #-- dnstap_tls_badcert.test --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +. ../common.sh +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi + +# test if the server is up. +echo "> dig www.example.com." +dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile +echo "> check answer" +if grep "10.20.30.40" outfile; then + echo "OK" +else + echo "> cat logfiles" + cat tap.log + cat tap.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 +fi + +echo "> check tap.log for dnstap info" +# see if it logged the information in tap.log +# wait for a moment for filesystem to catch up. +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log; then + echo "it is in tap.log"; + echo "but there should not be a connection" + echo "failed" + echo "> cat logfiles" + cat tap.log + cat tap.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 +else + echo "information not in tap.log" +fi + +echo "> OK" +exit 0 diff --git a/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.testns b/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.testns new file mode 100644 index 000000000..0c911ca5b --- /dev/null +++ b/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.testns @@ -0,0 +1,22 @@ +; nameserver test file +$ORIGIN example.com. +$TTL 3600 + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA NOERROR +ADJUST copy_id +SECTION QUESTION +www IN A +SECTION ANSWER +www IN A 10.20.30.40 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA SERVFAIL +ADJUST copy_id +SECTION QUESTION +www.example.net. IN A +ENTRY_END + diff --git a/testdata/dnstap_tls_badcert.tdir/unbound_control.key b/testdata/dnstap_tls_badcert.tdir/unbound_control.key new file mode 100644 index 000000000..d7c43a06b --- /dev/null +++ b/testdata/dnstap_tls_badcert.tdir/unbound_control.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDD6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBa +rzPA0vlyuNtUsEN3qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvH +ST6JwUdIg0Lzg/USJ81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQAB +AoGAFT3e35MIgI4uDJJ8X0RfHp2NCO2LUg4TKbWical/C0W9vlR1/x80G1pE1d2Z +WotqJVWTrOq6eBox19RCgtLg2wPGk9uD62+9SDT37heWFlUCElWq50pQG6k9ThiG +DDypkZyZ/52+DdWybiaQJkuK6O5qQXuNAtVJMpghu4GnHAECQQDsupnZUQDpapzr +4FC4MSkL2+A1PRt6g4VhwoqOpJXaHfVnH6F7AwUuOLNwGdR5Cvv70pfJ7Jqg8L2m +Kxyl5bORAkEA09rn34YQ0pHJdHidbl2kInIuYTz09+TO3LWwan17nISH9aaYvVDr +p9x1B4Qzw9qyxT9oll7ze/5Rw/7C3AQj4QJAT2B2a+b8bkgAXBs4FbruL3rHoDJg +P2FQXSpVOWU4lg2LlsuFYvDtUMVUbZdLplanjZXcral3Y9W1Ub2M+ped8QJAYQN+ +aRpge7ys7vwIw7B36Bo3aOncF+ScYe+FkM5Tm7II/JHEofT7ZQwMP1vnxIlSkgbe +YvWqNB6a3NC99LikoQJBAM4UhDdRg63Tr6Idky6CQaH///zAN7nArJfffKGWFdw9 +DKrWpNqvYZtX/cfEJucKcRCm5YL8CKFYbQy4VoCxUcE= +-----END RSA PRIVATE KEY----- diff --git a/testdata/dnstap_tls_badcert.tdir/unbound_control.pem b/testdata/dnstap_tls_badcert.tdir/unbound_control.pem new file mode 100644 index 000000000..8f1ba87f1 --- /dev/null +++ b/testdata/dnstap_tls_badcert.tdir/unbound_control.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBozCCAQwCCQD6XaN6FzW/4DANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1 +bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowGjEYMBYGA1UE +AxMPdW5ib3VuZC1jb250cm9sMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDD +6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBarzPA0vlyuNtUsEN3 +qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvHST6JwUdIg0Lzg/US +J81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQABMA0GCSqGSIb3DQEB +BQUAA4GBAGFAXmaQHuFgAuc6HVhYZJdToxLBhfxGpot4oZNjcb1Cdoz3OL34MU1B +9E5psj2PpGPIi8/RwoqBtAJHJ+J5cWngo03o4ZmdwKNSzaxlp141z/3rUtFqEHEC +iO6gPCT3U7dt6MyC7r6vdMqyW6aldP3CtwD0gQziKAMoj+TAfAcq +-----END CERTIFICATE----- diff --git a/testdata/dnstap_tls_badcert.tdir/unbound_server.key b/testdata/dnstap_tls_badcert.tdir/unbound_server.key new file mode 100644 index 000000000..4256c421d --- /dev/null +++ b/testdata/dnstap_tls_badcert.tdir/unbound_server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQC3F7Jsv2u01pLL9rFnjsMU/IaCFUIz/624DcaE84Z4gjMl5kWA +3axQcqul1wlwSrbKwrony+d9hH/+MX0tZwvl8w3OmhmOAiaQ+SHCsIuOjVwQjX0s +RLB61Pz5+PAiVvnPa9JIYB5QrK6DVEsxIHj8MOc5JKORrnESsFDh6yeMeQIDAQAB +AoGAAuWoGBprTOA8UGfl5LqYkaNxSWumsYXxLMFjC8WCsjN1NbtQDDr1uAwodSZS +6ujzvX+ZTHnofs7y64XC8k34HTOCD2zlW7kijWbT8YjRYFU6o9F5zUGD9RCan0ds +sVscT2psLSzfdsmFAcbmnGdxYkXk2PC1FHtaqExxehralGUCQQDcqrg9uQKXlhQi +XAaPr8SiWvtRm2a9IMMZkRfUWZclPHq6fCWNuUaCD+cTat4wAuqeknAz33VEosw3 +fXGsok//AkEA1GjIHXrOcSlpfVJb6NeOBugjRtZ7ZDT5gbtnMS9ob0qntKV6saaL +CNmJwuD9Q3XkU5j1+uHvYGP2NzcJd2CjhwJACV0hNlVMe9w9fHvFN4Gw6WbM9ViP +0oS6YrJafYNTu5vGZXVxLoNnL4u3NYa6aPUmuZXjNwBLfJ8f5VboZPf6RwJAINd2 +oYA8bSi/A755MX4qmozH74r4Fx1Nuq5UHTm8RwDe/0Javx8F/j9MWpJY9lZDEF3l +In5OebPa/NyInSmW/wJAZuP9aRn0nDBkHYri++1A7NykMiJ/nH0mDECbnk+wxx0S +LwqIetBhxb8eQwMg45+iAH7CHAMQ8BQuF/nFE6eotg== +-----END RSA PRIVATE KEY----- diff --git a/testdata/dnstap_tls_badcert.tdir/unbound_server.pem b/testdata/dnstap_tls_badcert.tdir/unbound_server.pem new file mode 100644 index 000000000..aeda3ff11 --- /dev/null +++ b/testdata/dnstap_tls_badcert.tdir/unbound_server.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBmzCCAQQCCQDsNJ1UmphEFzANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1 +bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowEjEQMA4GA1UE +AxMHdW5ib3VuZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtxeybL9rtNaS +y/axZ47DFPyGghVCM/+tuA3GhPOGeIIzJeZFgN2sUHKrpdcJcEq2ysK6J8vnfYR/ +/jF9LWcL5fMNzpoZjgImkPkhwrCLjo1cEI19LESwetT8+fjwIlb5z2vSSGAeUKyu +g1RLMSB4/DDnOSSjka5xErBQ4esnjHkCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAZ +9N0lnLENs4JMvPS+mn8C5m9bkkFITd32IiLjf0zgYpIUbFXH6XaEr9GNZBUG8feG +l/6WRXnbnVSblI5odQ4XxGZ9inYY6qtW30uv76HvoKp+QZ1c3460ddR8NauhcCHH +Z7S+QbLXi+r2JAhpPozZCjBHlRD0ixzA1mKQTJhJZg== +-----END CERTIFICATE----- diff --git a/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.conf b/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.conf new file mode 100644 index 000000000..75e98a71d --- /dev/null +++ b/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.conf @@ -0,0 +1,46 @@ +server: + verbosity: 4 + num-threads: 1 + outgoing-range: 16 + interface: 127.0.0.1 + port: @PORT@ + use-syslog: no + directory: "" + pidfile: "unbound.pid" + chroot: "" + username: "" + do-not-query-localhost: no + local-zone: "example.net." redirect + local-data: "example.net. IN A 10.20.30.41" +remote-control: + control-enable: yes + control-interface: 127.0.0.1 + # control-interface: ::1 + control-port: @CONTROL_PORT@ + server-key-file: "unbound_server.key" + server-cert-file: "unbound_server.pem" + control-key-file: "unbound_control.key" + control-cert-file: "unbound_control.pem" +forward-zone: + name: "." + forward-addr: "127.0.0.1@@TOPORT@" +dnstap: + dnstap-enable: yes + dnstap-socket-path: "dnstap.socket" + dnstap-ip: "127.0.0.1@@TAPPORT@" + dnstap-tls: yes + # actual certificate name: "unbound" + # we enter another name here. + dnstap-tls-server-name: "anothername" + dnstap-tls-cert-bundle: "unbound_server.pem" + dnstap-send-identity: yes + dnstap-send-version: yes + #dnstap-identity + #dnstap-version + dnstap-log-resolver-query-messages: yes + dnstap-log-resolver-response-messages: yes + dnstap-log-client-query-messages: yes + dnstap-log-client-response-messages: yes + dnstap-log-forwarder-query-messages: yes + dnstap-log-forwarder-response-messages: yes + diff --git a/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.dsc b/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.dsc new file mode 100644 index 000000000..33cc38a6c --- /dev/null +++ b/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.dsc @@ -0,0 +1,16 @@ +BaseName: dnstap_tls_badname +Version: 1.0 +Description: test dnstap tls test bad peer name for authentication +CreationDate: Tue Feb 14 14:00:38 CET 2020 +Maintainer: dr. W.C.A. Wijngaards +Category: +Component: +CmdDepends: +Depends: +Help: +Pre: dnstap_tls_badname.pre +Post: dnstap_tls_badname.post +Test: dnstap_tls_badname.test +AuxFiles: +Passed: +Failure: diff --git a/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.post b/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.post new file mode 100644 index 000000000..59f05b81d --- /dev/null +++ b/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.post @@ -0,0 +1,20 @@ +# #-- dnstap_tls_badname.post --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# source the test var file when it's there +[ -f .tpkg.var.test ] && source .tpkg.var.test +# +# do your teardown here +. ../common.sh +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi +kill_pid $DNSTAP_SOCKET_PID +kill_pid $FWD_PID +kill $UNBOUND_PID +kill $UNBOUND_PID >/dev/null 2>&1 +cat unbound.log +echo "> tap logfiles" +cat tap.log +cat tap.errlog +cat fwd.log +exit 0 diff --git a/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.pre b/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.pre new file mode 100644 index 000000000..0ffee6081 --- /dev/null +++ b/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.pre @@ -0,0 +1,54 @@ +# #-- dnstap_tls_badname.pre--# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +. ../common.sh + +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi + +get_random_port 4 +UNBOUND_PORT=$RND_PORT +FWD_PORT=$(($RND_PORT + 1)) +CONTROL_PORT=$(($RND_PORT + 2)) +TAP_PORT=$(($RND_PORT + 3)) +echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test +echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test +echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test +echo "TAP_PORT=$TAP_PORT" >> .tpkg.var.test + +# start forwarder +get_ldns_testns +$LDNS_TESTNS -p $FWD_PORT dnstap_tls_badname.testns >fwd.log 2>&1 & +FWD_PID=$! +echo "FWD_PID=$FWD_PID" >> .tpkg.var.test + +# start the dnstap log server +# the -vvvv flag prints protocol and connection information from the +# unbound-dnstap-socket server. +# the -l flag prints the DNS info in the DNSTAP packet in multiline output. +# stderr is the '-vvvv' server logs and errors. +# stdout is the one-line packet logs (or with -l, multiline). +$PRE/unbound-dnstap-socket -t "127.0.0.1@$TAP_PORT" -x unbound_server.key -y unbound_server.pem -l -vvvv 2>tap.errlog >tap.log & +if test $? -ne 0; then + echo "could not start unbound-dnstap-socket server" + exit 1 +fi +DNSTAP_SOCKET_PID=$! +echo "DNSTAP_SOCKET_PID=$DNSTAP_SOCKET_PID" >> .tpkg.var.test +# wait for the server to go up +wait_server_up "tap.errlog" "start of service" + +# make config file +sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' -e 's/@TAPPORT\@/'$TAP_PORT'/' < dnstap_tls_badname.conf > ub.conf +# start unbound in the background +$PRE/unbound -d -c ub.conf >unbound.log 2>&1 & +UNBOUND_PID=$! +echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test + +cat .tpkg.var.test +wait_ldns_testns_up fwd.log +wait_unbound_up unbound.log + diff --git a/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.test b/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.test new file mode 100644 index 000000000..248d8f222 --- /dev/null +++ b/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.test @@ -0,0 +1,51 @@ +# #-- dnstap_tls_badname.test --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +. ../common.sh +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi + +# test if the server is up. +echo "> dig www.example.com." +dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile +echo "> check answer" +if grep "10.20.30.40" outfile; then + echo "OK" +else + echo "> cat logfiles" + cat tap.log + cat tap.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 +fi + +echo "> check tap.log for dnstap info" +# see if it logged the information in tap.log +# wait for a moment for filesystem to catch up. +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log; then + echo "it is in tap.log"; + echo "but there should not be a connection" + echo "failed" + echo "> cat logfiles" + cat tap.log + cat tap.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 +else + echo "information not in tap.log" +fi + +echo "> OK" +exit 0 diff --git a/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.testns b/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.testns new file mode 100644 index 000000000..0c911ca5b --- /dev/null +++ b/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.testns @@ -0,0 +1,22 @@ +; nameserver test file +$ORIGIN example.com. +$TTL 3600 + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA NOERROR +ADJUST copy_id +SECTION QUESTION +www IN A +SECTION ANSWER +www IN A 10.20.30.40 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA SERVFAIL +ADJUST copy_id +SECTION QUESTION +www.example.net. IN A +ENTRY_END + diff --git a/testdata/dnstap_tls_badname.tdir/unbound_control.key b/testdata/dnstap_tls_badname.tdir/unbound_control.key new file mode 100644 index 000000000..d7c43a06b --- /dev/null +++ b/testdata/dnstap_tls_badname.tdir/unbound_control.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDD6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBa +rzPA0vlyuNtUsEN3qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvH +ST6JwUdIg0Lzg/USJ81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQAB +AoGAFT3e35MIgI4uDJJ8X0RfHp2NCO2LUg4TKbWical/C0W9vlR1/x80G1pE1d2Z +WotqJVWTrOq6eBox19RCgtLg2wPGk9uD62+9SDT37heWFlUCElWq50pQG6k9ThiG +DDypkZyZ/52+DdWybiaQJkuK6O5qQXuNAtVJMpghu4GnHAECQQDsupnZUQDpapzr +4FC4MSkL2+A1PRt6g4VhwoqOpJXaHfVnH6F7AwUuOLNwGdR5Cvv70pfJ7Jqg8L2m +Kxyl5bORAkEA09rn34YQ0pHJdHidbl2kInIuYTz09+TO3LWwan17nISH9aaYvVDr +p9x1B4Qzw9qyxT9oll7ze/5Rw/7C3AQj4QJAT2B2a+b8bkgAXBs4FbruL3rHoDJg +P2FQXSpVOWU4lg2LlsuFYvDtUMVUbZdLplanjZXcral3Y9W1Ub2M+ped8QJAYQN+ +aRpge7ys7vwIw7B36Bo3aOncF+ScYe+FkM5Tm7II/JHEofT7ZQwMP1vnxIlSkgbe +YvWqNB6a3NC99LikoQJBAM4UhDdRg63Tr6Idky6CQaH///zAN7nArJfffKGWFdw9 +DKrWpNqvYZtX/cfEJucKcRCm5YL8CKFYbQy4VoCxUcE= +-----END RSA PRIVATE KEY----- diff --git a/testdata/dnstap_tls_badname.tdir/unbound_control.pem b/testdata/dnstap_tls_badname.tdir/unbound_control.pem new file mode 100644 index 000000000..8f1ba87f1 --- /dev/null +++ b/testdata/dnstap_tls_badname.tdir/unbound_control.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBozCCAQwCCQD6XaN6FzW/4DANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1 +bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowGjEYMBYGA1UE +AxMPdW5ib3VuZC1jb250cm9sMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDD +6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBarzPA0vlyuNtUsEN3 +qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvHST6JwUdIg0Lzg/US +J81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQABMA0GCSqGSIb3DQEB +BQUAA4GBAGFAXmaQHuFgAuc6HVhYZJdToxLBhfxGpot4oZNjcb1Cdoz3OL34MU1B +9E5psj2PpGPIi8/RwoqBtAJHJ+J5cWngo03o4ZmdwKNSzaxlp141z/3rUtFqEHEC +iO6gPCT3U7dt6MyC7r6vdMqyW6aldP3CtwD0gQziKAMoj+TAfAcq +-----END CERTIFICATE----- diff --git a/testdata/dnstap_tls_badname.tdir/unbound_server.key b/testdata/dnstap_tls_badname.tdir/unbound_server.key new file mode 100644 index 000000000..4256c421d --- /dev/null +++ b/testdata/dnstap_tls_badname.tdir/unbound_server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQC3F7Jsv2u01pLL9rFnjsMU/IaCFUIz/624DcaE84Z4gjMl5kWA +3axQcqul1wlwSrbKwrony+d9hH/+MX0tZwvl8w3OmhmOAiaQ+SHCsIuOjVwQjX0s +RLB61Pz5+PAiVvnPa9JIYB5QrK6DVEsxIHj8MOc5JKORrnESsFDh6yeMeQIDAQAB +AoGAAuWoGBprTOA8UGfl5LqYkaNxSWumsYXxLMFjC8WCsjN1NbtQDDr1uAwodSZS +6ujzvX+ZTHnofs7y64XC8k34HTOCD2zlW7kijWbT8YjRYFU6o9F5zUGD9RCan0ds +sVscT2psLSzfdsmFAcbmnGdxYkXk2PC1FHtaqExxehralGUCQQDcqrg9uQKXlhQi +XAaPr8SiWvtRm2a9IMMZkRfUWZclPHq6fCWNuUaCD+cTat4wAuqeknAz33VEosw3 +fXGsok//AkEA1GjIHXrOcSlpfVJb6NeOBugjRtZ7ZDT5gbtnMS9ob0qntKV6saaL +CNmJwuD9Q3XkU5j1+uHvYGP2NzcJd2CjhwJACV0hNlVMe9w9fHvFN4Gw6WbM9ViP +0oS6YrJafYNTu5vGZXVxLoNnL4u3NYa6aPUmuZXjNwBLfJ8f5VboZPf6RwJAINd2 +oYA8bSi/A755MX4qmozH74r4Fx1Nuq5UHTm8RwDe/0Javx8F/j9MWpJY9lZDEF3l +In5OebPa/NyInSmW/wJAZuP9aRn0nDBkHYri++1A7NykMiJ/nH0mDECbnk+wxx0S +LwqIetBhxb8eQwMg45+iAH7CHAMQ8BQuF/nFE6eotg== +-----END RSA PRIVATE KEY----- diff --git a/testdata/dnstap_tls_badname.tdir/unbound_server.pem b/testdata/dnstap_tls_badname.tdir/unbound_server.pem new file mode 100644 index 000000000..aeda3ff11 --- /dev/null +++ b/testdata/dnstap_tls_badname.tdir/unbound_server.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBmzCCAQQCCQDsNJ1UmphEFzANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1 +bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowEjEQMA4GA1UE +AxMHdW5ib3VuZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtxeybL9rtNaS +y/axZ47DFPyGghVCM/+tuA3GhPOGeIIzJeZFgN2sUHKrpdcJcEq2ysK6J8vnfYR/ +/jF9LWcL5fMNzpoZjgImkPkhwrCLjo1cEI19LESwetT8+fjwIlb5z2vSSGAeUKyu +g1RLMSB4/DDnOSSjka5xErBQ4esnjHkCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAZ +9N0lnLENs4JMvPS+mn8C5m9bkkFITd32IiLjf0zgYpIUbFXH6XaEr9GNZBUG8feG +l/6WRXnbnVSblI5odQ4XxGZ9inYY6qtW30uv76HvoKp+QZ1c3460ddR8NauhcCHH +Z7S+QbLXi+r2JAhpPozZCjBHlRD0ixzA1mKQTJhJZg== +-----END CERTIFICATE----- diff --git a/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.dsc b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.dsc index d011d5ece..bce84f55c 100644 --- a/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.dsc +++ b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.dsc @@ -1,6 +1,6 @@ BaseName: dnstap_tls_peername Version: 1.0 -Description: test dnstap tls and reconnect +Description: test dnstap tls with auth name and tls authentication CreationDate: Tue Feb 14 14:00:38 CET 2020 Maintainer: dr. W.C.A. Wijngaards Category: diff --git a/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.post b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.post index b2c29d0da..3ca63ada4 100644 --- a/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.post +++ b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.post @@ -16,8 +16,5 @@ cat unbound.log echo "> tap logfiles" cat tap.log cat tap.errlog -echo "> tap2 logfiles" -if test -f tap2.log; then cat tap2.log; fi -if test -f tap2.errlog; then cat tap2.errlog; fi cat fwd.log exit 0 diff --git a/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.test b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.test index 6082c3a89..03bcbadfd 100644 --- a/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.test +++ b/testdata/dnstap_tls_peername.tdir/dnstap_tls_peername.test @@ -30,6 +30,8 @@ echo "> check tap.log for dnstap info" if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi if grep "www.example.com" tap.log >/dev/null; then :; else sleep 10; fi if grep "www.example.com" tap.log; then echo "yes it is in tap.log"; else @@ -44,48 +46,5 @@ else exit 1 fi -echo "" -echo "> test disconnect from the upstream server" - -kill_pid $DNSTAP_SOCKET_PID -dig @127.0.0.1 -p $UNBOUND_PORT down.example.net. - -# bring log socket back up -$PRE/unbound-dnstap-socket -t "127.0.0.1@$TAP_PORT" -x unbound_server.key -y unbound_server.pem -l -vvvv 2>tap2.errlog >tap2.log & -if test $? -ne 0; then - echo "could not start (again) unbound-dnstap-socket server" - exit 1 -fi -DNSTAP_SOCKET_PID=$! -echo "DNSTAP_SOCKET_PID=$DNSTAP_SOCKET_PID" >> .tpkg.var.test -# wait for the server to go up -wait_server_up "tap2.errlog" "start of service" - -dig @127.0.0.1 -p $UNBOUND_PORT up.example.net. -sleep 2 -dig @127.0.0.1 -p $UNBOUND_PORT up2.example.net. - -for x in down up up2; do - if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi - if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi - if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 1; fi - if grep "$x.example.net" tap2.log >/dev/null; then :; else sleep 10; fi - if grep "$x.example.net" tap2.log; then echo "yes it is in tap2.log"; - else - echo "$x.example.net. information not in tap2.log" - echo "failed" - echo "> cat logfiles" - cat tap.log - cat tap.errlog - echo "> tap2 logfiles" - cat tap2.log - cat tap2.errlog - cat fwd.log - cat unbound.log - echo "Not OK" - exit 1 - fi -done - echo "> OK" exit 0 From 3753d01253e4f60bcd306480b6d3f50c3c79670b Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 18 Feb 2020 16:30:13 +0100 Subject: [PATCH 78/96] dnstap io, test for client authentication, unbound can send client authentication credentials, when configured, and unbound-dnstap-socket can verify the client credentials, and refuses the connection if missing. --- .../dnstap_tls_badcert.dsc | 2 +- .../dnstap_tls_badname.dsc | 2 +- .../dnstap_tls_clientauth.conf | 46 ++++++++++++++++ .../dnstap_tls_clientauth.dsc | 16 ++++++ .../dnstap_tls_clientauth.post | 20 +++++++ .../dnstap_tls_clientauth.pre | 54 +++++++++++++++++++ .../dnstap_tls_clientauth.test | 50 +++++++++++++++++ .../dnstap_tls_clientauth.testns | 22 ++++++++ .../unbound_control.key | 15 ++++++ .../unbound_control.pem | 11 ++++ .../unbound_server.key | 15 ++++++ .../unbound_server.pem | 11 ++++ 12 files changed, 262 insertions(+), 2 deletions(-) create mode 100644 testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.conf create mode 100644 testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.dsc create mode 100644 testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.post create mode 100644 testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.pre create mode 100644 testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.test create mode 100644 testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.testns create mode 100644 testdata/dnstap_tls_clientauth.tdir/unbound_control.key create mode 100644 testdata/dnstap_tls_clientauth.tdir/unbound_control.pem create mode 100644 testdata/dnstap_tls_clientauth.tdir/unbound_server.key create mode 100644 testdata/dnstap_tls_clientauth.tdir/unbound_server.pem diff --git a/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.dsc b/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.dsc index e495e6c99..7d392ff56 100644 --- a/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.dsc +++ b/testdata/dnstap_tls_badcert.tdir/dnstap_tls_badcert.dsc @@ -1,7 +1,7 @@ BaseName: dnstap_tls_badcert Version: 1.0 Description: test dnstap tls with bad cert for authentication -CreationDate: Tue Feb 14 14:00:38 CET 2020 +CreationDate: Tue Feb 18 13:00:38 CET 2020 Maintainer: dr. W.C.A. Wijngaards Category: Component: diff --git a/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.dsc b/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.dsc index 33cc38a6c..9f878b91c 100644 --- a/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.dsc +++ b/testdata/dnstap_tls_badname.tdir/dnstap_tls_badname.dsc @@ -1,7 +1,7 @@ BaseName: dnstap_tls_badname Version: 1.0 Description: test dnstap tls test bad peer name for authentication -CreationDate: Tue Feb 14 14:00:38 CET 2020 +CreationDate: Tue Feb 18 13:00:38 CET 2020 Maintainer: dr. W.C.A. Wijngaards Category: Component: diff --git a/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.conf b/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.conf new file mode 100644 index 000000000..6182526ac --- /dev/null +++ b/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.conf @@ -0,0 +1,46 @@ +server: + verbosity: 4 + num-threads: 1 + outgoing-range: 16 + interface: 127.0.0.1 + port: @PORT@ + use-syslog: no + directory: "" + pidfile: "unbound.pid" + chroot: "" + username: "" + do-not-query-localhost: no + local-zone: "example.net." redirect + local-data: "example.net. IN A 10.20.30.41" +remote-control: + control-enable: yes + control-interface: 127.0.0.1 + # control-interface: ::1 + control-port: @CONTROL_PORT@ + server-key-file: "unbound_server.key" + server-cert-file: "unbound_server.pem" + control-key-file: "unbound_control.key" + control-cert-file: "unbound_control.pem" +forward-zone: + name: "." + forward-addr: "127.0.0.1@@TOPORT@" +dnstap: + dnstap-enable: yes + dnstap-socket-path: "dnstap.socket" + dnstap-ip: "127.0.0.1@@TAPPORT@" + dnstap-tls: yes + dnstap-tls-server-name: "unbound" + dnstap-tls-cert-bundle: "unbound_server.pem" + dnstap-tls-client-key-file: "unbound_control.key" + dnstap-tls-client-cert-file: "unbound_control.pem" + dnstap-send-identity: yes + dnstap-send-version: yes + #dnstap-identity + #dnstap-version + dnstap-log-resolver-query-messages: yes + dnstap-log-resolver-response-messages: yes + dnstap-log-client-query-messages: yes + dnstap-log-client-response-messages: yes + dnstap-log-forwarder-query-messages: yes + dnstap-log-forwarder-response-messages: yes + diff --git a/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.dsc b/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.dsc new file mode 100644 index 000000000..37aacbbd9 --- /dev/null +++ b/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.dsc @@ -0,0 +1,16 @@ +BaseName: dnstap_tls_clientauth +Version: 1.0 +Description: test dnstap tls with client authentication +CreationDate: Tue Feb 18 14:00:38 CET 2020 +Maintainer: dr. W.C.A. Wijngaards +Category: +Component: +CmdDepends: +Depends: +Help: +Pre: dnstap_tls_clientauth.pre +Post: dnstap_tls_clientauth.post +Test: dnstap_tls_clientauth.test +AuxFiles: +Passed: +Failure: diff --git a/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.post b/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.post new file mode 100644 index 000000000..83df2a72e --- /dev/null +++ b/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.post @@ -0,0 +1,20 @@ +# #-- dnstap_tls_clientauth.post --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# source the test var file when it's there +[ -f .tpkg.var.test ] && source .tpkg.var.test +# +# do your teardown here +. ../common.sh +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi +kill_pid $DNSTAP_SOCKET_PID +kill_pid $FWD_PID +kill $UNBOUND_PID +kill $UNBOUND_PID >/dev/null 2>&1 +cat unbound.log +echo "> tap logfiles" +cat tap.log +cat tap.errlog +cat fwd.log +exit 0 diff --git a/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.pre b/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.pre new file mode 100644 index 000000000..a035181ce --- /dev/null +++ b/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.pre @@ -0,0 +1,54 @@ +# #-- dnstap_tls_clientauth.pre--# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +. ../common.sh + +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi + +get_random_port 4 +UNBOUND_PORT=$RND_PORT +FWD_PORT=$(($RND_PORT + 1)) +CONTROL_PORT=$(($RND_PORT + 2)) +TAP_PORT=$(($RND_PORT + 3)) +echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test +echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test +echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test +echo "TAP_PORT=$TAP_PORT" >> .tpkg.var.test + +# start forwarder +get_ldns_testns +$LDNS_TESTNS -p $FWD_PORT dnstap_tls_clientauth.testns >fwd.log 2>&1 & +FWD_PID=$! +echo "FWD_PID=$FWD_PID" >> .tpkg.var.test + +# start the dnstap log server +# the -vvvv flag prints protocol and connection information from the +# unbound-dnstap-socket server. +# the -l flag prints the DNS info in the DNSTAP packet in multiline output. +# stderr is the '-vvvv' server logs and errors. +# stdout is the one-line packet logs (or with -l, multiline). +$PRE/unbound-dnstap-socket -t "127.0.0.1@$TAP_PORT" -x unbound_server.key -y unbound_server.pem -z unbound_server.pem -l -vvvv 2>tap.errlog >tap.log & +if test $? -ne 0; then + echo "could not start unbound-dnstap-socket server" + exit 1 +fi +DNSTAP_SOCKET_PID=$! +echo "DNSTAP_SOCKET_PID=$DNSTAP_SOCKET_PID" >> .tpkg.var.test +# wait for the server to go up +wait_server_up "tap.errlog" "start of service" + +# make config file +sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' -e 's/@TAPPORT\@/'$TAP_PORT'/' < dnstap_tls_clientauth.conf > ub.conf +# start unbound in the background +$PRE/unbound -d -c ub.conf >unbound.log 2>&1 & +UNBOUND_PID=$! +echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test + +cat .tpkg.var.test +wait_ldns_testns_up fwd.log +wait_unbound_up unbound.log + diff --git a/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.test b/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.test new file mode 100644 index 000000000..5b9cce0a4 --- /dev/null +++ b/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.test @@ -0,0 +1,50 @@ +# #-- dnstap_tls_clientauth.test --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +. ../common.sh +PRE="../.." +if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi + +# test if the server is up. +echo "> dig www.example.com." +dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile +echo "> check answer" +if grep "10.20.30.40" outfile; then + echo "OK" +else + echo "> cat logfiles" + cat tap.log + cat tap.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 +fi + +echo "> check tap.log for dnstap info" +# see if it logged the information in tap.log +# wait for a moment for filesystem to catch up. +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi +if grep "www.example.com" tap.log >/dev/null; then :; else sleep 10; fi +if grep "www.example.com" tap.log; then echo "yes it is in tap.log"; +else + echo "information not in tap.log" + echo "failed" + echo "> cat logfiles" + cat tap.log + cat tap.errlog + cat fwd.log + cat unbound.log + echo "Not OK" + exit 1 +fi + +echo "> OK" +exit 0 diff --git a/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.testns b/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.testns new file mode 100644 index 000000000..0c911ca5b --- /dev/null +++ b/testdata/dnstap_tls_clientauth.tdir/dnstap_tls_clientauth.testns @@ -0,0 +1,22 @@ +; nameserver test file +$ORIGIN example.com. +$TTL 3600 + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA NOERROR +ADJUST copy_id +SECTION QUESTION +www IN A +SECTION ANSWER +www IN A 10.20.30.40 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA SERVFAIL +ADJUST copy_id +SECTION QUESTION +www.example.net. IN A +ENTRY_END + diff --git a/testdata/dnstap_tls_clientauth.tdir/unbound_control.key b/testdata/dnstap_tls_clientauth.tdir/unbound_control.key new file mode 100644 index 000000000..d7c43a06b --- /dev/null +++ b/testdata/dnstap_tls_clientauth.tdir/unbound_control.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDD6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBa +rzPA0vlyuNtUsEN3qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvH +ST6JwUdIg0Lzg/USJ81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQAB +AoGAFT3e35MIgI4uDJJ8X0RfHp2NCO2LUg4TKbWical/C0W9vlR1/x80G1pE1d2Z +WotqJVWTrOq6eBox19RCgtLg2wPGk9uD62+9SDT37heWFlUCElWq50pQG6k9ThiG +DDypkZyZ/52+DdWybiaQJkuK6O5qQXuNAtVJMpghu4GnHAECQQDsupnZUQDpapzr +4FC4MSkL2+A1PRt6g4VhwoqOpJXaHfVnH6F7AwUuOLNwGdR5Cvv70pfJ7Jqg8L2m +Kxyl5bORAkEA09rn34YQ0pHJdHidbl2kInIuYTz09+TO3LWwan17nISH9aaYvVDr +p9x1B4Qzw9qyxT9oll7ze/5Rw/7C3AQj4QJAT2B2a+b8bkgAXBs4FbruL3rHoDJg +P2FQXSpVOWU4lg2LlsuFYvDtUMVUbZdLplanjZXcral3Y9W1Ub2M+ped8QJAYQN+ +aRpge7ys7vwIw7B36Bo3aOncF+ScYe+FkM5Tm7II/JHEofT7ZQwMP1vnxIlSkgbe +YvWqNB6a3NC99LikoQJBAM4UhDdRg63Tr6Idky6CQaH///zAN7nArJfffKGWFdw9 +DKrWpNqvYZtX/cfEJucKcRCm5YL8CKFYbQy4VoCxUcE= +-----END RSA PRIVATE KEY----- diff --git a/testdata/dnstap_tls_clientauth.tdir/unbound_control.pem b/testdata/dnstap_tls_clientauth.tdir/unbound_control.pem new file mode 100644 index 000000000..8f1ba87f1 --- /dev/null +++ b/testdata/dnstap_tls_clientauth.tdir/unbound_control.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBozCCAQwCCQD6XaN6FzW/4DANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1 +bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowGjEYMBYGA1UE +AxMPdW5ib3VuZC1jb250cm9sMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDD +6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBarzPA0vlyuNtUsEN3 +qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvHST6JwUdIg0Lzg/US +J81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQABMA0GCSqGSIb3DQEB +BQUAA4GBAGFAXmaQHuFgAuc6HVhYZJdToxLBhfxGpot4oZNjcb1Cdoz3OL34MU1B +9E5psj2PpGPIi8/RwoqBtAJHJ+J5cWngo03o4ZmdwKNSzaxlp141z/3rUtFqEHEC +iO6gPCT3U7dt6MyC7r6vdMqyW6aldP3CtwD0gQziKAMoj+TAfAcq +-----END CERTIFICATE----- diff --git a/testdata/dnstap_tls_clientauth.tdir/unbound_server.key b/testdata/dnstap_tls_clientauth.tdir/unbound_server.key new file mode 100644 index 000000000..4256c421d --- /dev/null +++ b/testdata/dnstap_tls_clientauth.tdir/unbound_server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQC3F7Jsv2u01pLL9rFnjsMU/IaCFUIz/624DcaE84Z4gjMl5kWA +3axQcqul1wlwSrbKwrony+d9hH/+MX0tZwvl8w3OmhmOAiaQ+SHCsIuOjVwQjX0s +RLB61Pz5+PAiVvnPa9JIYB5QrK6DVEsxIHj8MOc5JKORrnESsFDh6yeMeQIDAQAB +AoGAAuWoGBprTOA8UGfl5LqYkaNxSWumsYXxLMFjC8WCsjN1NbtQDDr1uAwodSZS +6ujzvX+ZTHnofs7y64XC8k34HTOCD2zlW7kijWbT8YjRYFU6o9F5zUGD9RCan0ds +sVscT2psLSzfdsmFAcbmnGdxYkXk2PC1FHtaqExxehralGUCQQDcqrg9uQKXlhQi +XAaPr8SiWvtRm2a9IMMZkRfUWZclPHq6fCWNuUaCD+cTat4wAuqeknAz33VEosw3 +fXGsok//AkEA1GjIHXrOcSlpfVJb6NeOBugjRtZ7ZDT5gbtnMS9ob0qntKV6saaL +CNmJwuD9Q3XkU5j1+uHvYGP2NzcJd2CjhwJACV0hNlVMe9w9fHvFN4Gw6WbM9ViP +0oS6YrJafYNTu5vGZXVxLoNnL4u3NYa6aPUmuZXjNwBLfJ8f5VboZPf6RwJAINd2 +oYA8bSi/A755MX4qmozH74r4Fx1Nuq5UHTm8RwDe/0Javx8F/j9MWpJY9lZDEF3l +In5OebPa/NyInSmW/wJAZuP9aRn0nDBkHYri++1A7NykMiJ/nH0mDECbnk+wxx0S +LwqIetBhxb8eQwMg45+iAH7CHAMQ8BQuF/nFE6eotg== +-----END RSA PRIVATE KEY----- diff --git a/testdata/dnstap_tls_clientauth.tdir/unbound_server.pem b/testdata/dnstap_tls_clientauth.tdir/unbound_server.pem new file mode 100644 index 000000000..aeda3ff11 --- /dev/null +++ b/testdata/dnstap_tls_clientauth.tdir/unbound_server.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBmzCCAQQCCQDsNJ1UmphEFzANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1 +bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowEjEQMA4GA1UE +AxMHdW5ib3VuZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtxeybL9rtNaS +y/axZ47DFPyGghVCM/+tuA3GhPOGeIIzJeZFgN2sUHKrpdcJcEq2ysK6J8vnfYR/ +/jF9LWcL5fMNzpoZjgImkPkhwrCLjo1cEI19LESwetT8+fjwIlb5z2vSSGAeUKyu +g1RLMSB4/DDnOSSjka5xErBQ4esnjHkCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAZ +9N0lnLENs4JMvPS+mn8C5m9bkkFITd32IiLjf0zgYpIUbFXH6XaEr9GNZBUG8feG +l/6WRXnbnVSblI5odQ4XxGZ9inYY6qtW30uv76HvoKp+QZ1c3460ddR8NauhcCHH +Z7S+QbLXi+r2JAhpPozZCjBHlRD0ixzA1mKQTJhJZg== +-----END CERTIFICATE----- From 8f14388cb43be382a43619b7c0abe7308d4a3505 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 18 Feb 2020 17:04:08 +0100 Subject: [PATCH 79/96] dnstap io, move control frame ready, accept and log to dnstap_fstrm code. --- dnstap/dnstap_fstrm.c | 112 +++++++++++++++++++++++++++++++++ dnstap/dnstap_fstrm.h | 37 +++++++++++ dnstap/unbound-dnstap-socket.c | 95 ++++++---------------------- 3 files changed, 168 insertions(+), 76 deletions(-) diff --git a/dnstap/dnstap_fstrm.c b/dnstap/dnstap_fstrm.c index be4acace8..aac98e567 100644 --- a/dnstap/dnstap_fstrm.c +++ b/dnstap/dnstap_fstrm.c @@ -43,6 +43,7 @@ #include "config.h" #include "dnstap/dnstap_fstrm.h" +#include "sldns/sbuffer.h" void* fstrm_create_control_frame_start(char* contenttype, size_t* len) { @@ -89,3 +90,114 @@ void* fstrm_create_control_frame_stop(size_t* len) *len = n; return control; } + +void* fstrm_create_control_frame_accept(char* contenttype, size_t* len) +{ + uint32_t* control; + size_t n; + /* control frame on reply: + * 4 bytes 0 escape + * 4 bytes bigendian length of frame + * 4 bytes bigendian type ACCEPT + * 4 bytes bigendian frame option content type + * 4 bytes bigendian length of string + * string of content type. + */ + /* len includes the escape and framelength */ + n = 4+4+4+4+4+strlen(contenttype); + control = malloc(n); + if(!control) { + return NULL; + } + control[0] = 0; + control[1] = htonl(4+4+4+strlen(contenttype)); + control[2] = htonl(FSTRM_CONTROL_FRAME_ACCEPT); + control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE); + control[4] = htonl(strlen(contenttype)); + memmove(&control[5], contenttype, strlen(contenttype)); + *len = n; + return control; +} + +void* fstrm_create_control_frame_finish(size_t* len) +{ + uint32_t* control; + size_t n; + /* control frame on reply: + * 4 bytes 0 escape + * 4 bytes bigendian length of frame + * 4 bytes bigendian type FINISH + */ + /* len includes the escape and framelength */ + n = 4+4+4; + control = malloc(n); + if(!control) { + return NULL; + } + control[0] = 0; + control[1] = htonl(4); + control[2] = htonl(FSTRM_CONTROL_FRAME_FINISH); + *len = n; + return control; +} + +char* fstrm_describe_control(void* pkt, size_t len) +{ + uint32_t frametype = 0; + char buf[512]; + size_t at = 0, remain; + uint8_t* pos; + + buf[0]=0; + if(len < 4) { + snprintf(buf, sizeof(buf), "malformed control frame, " + "too short, len=%u", (unsigned int)len); + return strdup(buf); + } + frametype = sldns_read_uint32(pkt); + if(frametype == FSTRM_CONTROL_FRAME_ACCEPT) { + at+=snprintf(buf+at, sizeof(buf)-at, "accept"); + } else if(frametype == FSTRM_CONTROL_FRAME_START) { + at+=snprintf(buf+at, sizeof(buf)-at, "start"); + } else if(frametype == FSTRM_CONTROL_FRAME_STOP) { + at+=snprintf(buf+at, sizeof(buf)-at, "stop"); + } else if(frametype == FSTRM_CONTROL_FRAME_READY) { + at+=snprintf(buf+at, sizeof(buf)-at, "ready"); + } else if(frametype == FSTRM_CONTROL_FRAME_FINISH) { + at+=snprintf(buf+at, sizeof(buf)-at, "finish"); + } else { + at+=snprintf(buf+at, sizeof(buf)-at, "type%d", + (int)frametype); + } + + /* show the content type options */ + pos = pkt + 4; + remain = len - 4; + while(remain >= 8) { + uint32_t field_type = sldns_read_uint32(pos); + uint32_t field_len = sldns_read_uint32(pos+4); + if(remain < field_len) { + at+=snprintf(buf+at, sizeof(buf)-at, "malformed_field"); + break; + } + if(field_type == FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE) { + at+=snprintf(buf+at, sizeof(buf)-at, " content-type("); + if(at+field_len < sizeof(buf)) { + memmove(buf+at, pos+8, field_len); + at += field_len; + } + at+=snprintf(buf+at, sizeof(buf)-at, ")"); + } else { + at+=snprintf(buf+at, sizeof(buf)-at, + " field(type %u, length %u)", + (unsigned int)field_type, + (unsigned int)field_len); + } + pos += 8 + field_len; + remain -= (8 + field_len); + } + if(remain > 0) + at+=snprintf(buf+at, sizeof(buf)-at, " trailing-bytes" + "(length %u)", (unsigned int)remain); + return strdup(buf); +} diff --git a/dnstap/dnstap_fstrm.h b/dnstap/dnstap_fstrm.h index 3b70547f1..f0cf93628 100644 --- a/dnstap/dnstap_fstrm.h +++ b/dnstap/dnstap_fstrm.h @@ -139,4 +139,41 @@ void* fstrm_create_control_frame_start(char* contenttype, size_t* len); */ void* fstrm_create_control_frame_stop(size_t* len); +/** + * This creates an FSTRM control frame of type ACCEPT. + * @param contenttype: a zero delimited string with the content type. + * for dnstap streams use DNSTAP_CONTENT_TYPE. + * @param len: if a buffer is returned this is the length of that buffer. + * @return NULL on malloc failure. Returns a malloced buffer with the + * protocol message. The buffer starts with the 4 bytes of 0 that indicate + * a control frame. The buffer should be sent without preceding it with + * the 'len' variable (like data frames are), but straight the content of the + * buffer, because the lengths are included in the buffer. This is so that + * the zero control indicator can be included before the control frame length. + */ +void* fstrm_create_control_frame_accept(char* contenttype, size_t* len); + +/** + * This creates an FSTRM control frame of type FINISH. + * @param len: if a buffer is returned this is the length of that buffer. + * @return NULL on malloc failure. Returns a malloced buffer with the + * protocol message. The buffer starts with the 4 bytes of 0 that indicate + * a control frame. The buffer should be sent without preceding it with + * the 'len' variable (like data frames are), but straight the content of the + * buffer, because the lengths are included in the buffer. This is so that + * the zero control indicator can be included before the control frame length. + */ +void* fstrm_create_control_frame_finish(size_t* len); + +/** + * Return string that describes a control packet. For debug, logs. + * Like 'start content-type(protobuf:dnstap.Dnstap)' or 'stop'. + * @param pkt: the packet data, that is the data after the 4 zero start + * bytes and 4 length bytes. + * @param len: the length of the control packet data, in pkt. This is the + * ntohl of the 4 bytes length preceding the data. + * @return zero delimited string, malloced. Or NULL on malloc failure. + */ +char* fstrm_describe_control(void* pkt, size_t len); + #endif /* DNSTAP_FSTRM_H */ diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index e26e12ede..0605d4d7c 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -409,54 +409,15 @@ static int tap_socket_list_addevs(struct tap_socket_list* list, /** log control frame contents */ static void log_control_frame(uint8_t* pkt, size_t len) { - uint32_t frametype = 0; - char buf[256]; - size_t at = 0, remain; - uint8_t* pos; + char* desc; if(verbosity == 0) return; - if(len < 4) { - log_err("malformed control frame, too short, len=%d", (int)len); + desc = fstrm_describe_control(pkt, len); + if(!desc) { + log_err("out of memory"); return; } - buf[0]=0; - frametype = sldns_read_uint32(pkt); - if(frametype == FSTRM_CONTROL_FRAME_ACCEPT) { - at+=snprintf(buf+at, sizeof(buf)-at, "accept"); - } else if(frametype == FSTRM_CONTROL_FRAME_START) { - at+=snprintf(buf+at, sizeof(buf)-at, "start"); - } else if(frametype == FSTRM_CONTROL_FRAME_STOP) { - at+=snprintf(buf+at, sizeof(buf)-at, "stop"); - } else if(frametype == FSTRM_CONTROL_FRAME_READY) { - at+=snprintf(buf+at, sizeof(buf)-at, "ready"); - } else if(frametype == FSTRM_CONTROL_FRAME_FINISH) { - at+=snprintf(buf+at, sizeof(buf)-at, "finish"); - } else { - at+=snprintf(buf+at, sizeof(buf)-at, "type%d", - (int)frametype); - } - - /* show the content type options */ - pos = pkt + 4; - remain = len - 4; - while(remain >= 8) { - uint32_t field_type = sldns_read_uint32(pos); - uint32_t field_len = sldns_read_uint32(pos+4); - if(remain < field_len) { - at+=snprintf(buf+at, sizeof(buf)-at, "malformed_field"); - break; - } - if(field_type == FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE) { - at+=snprintf(buf+at, sizeof(buf)-at, " content-type("); - if(at+field_len < sizeof(buf)) { - memmove(buf+at, pos+8, field_len); - at += field_len; - } - at+=snprintf(buf+at, sizeof(buf)-at, ")"); - } - pos += 8 + field_len; - remain -= (8 + field_len); - } - log_info("control frame %s", buf); + log_info("control frame %s", desc); + free(desc); } /** convert mtype to string */ @@ -804,32 +765,17 @@ void tap_data_free(struct tap_data* data) * returns 0 on error */ static int reply_with_accept(int fd) { - /* control frame on reply: - * 4 bytes 0 escape - * 4 bytes bigendian length of frame - * 4 bytes bigendian type ACCEPT - * 4 bytes bigendian frame option content type - * 4 bytes bigendian length of string - * string of content type. - */ - uint32_t* acceptframe; /* len includes the escape and framelength */ - size_t len = 4+4+4+4+4+strlen(DNSTAP_CONTENT_TYPE); - acceptframe = calloc(1, len); + size_t len = 0; + void* acceptframe = fstrm_create_control_frame_accept( + DNSTAP_CONTENT_TYPE, &len); if(!acceptframe) { log_err("out of memory"); return 0; } - acceptframe[0] = 0; - acceptframe[1] = htonl(4+4+4+strlen(DNSTAP_CONTENT_TYPE)); - acceptframe[2] = htonl(FSTRM_CONTROL_FRAME_ACCEPT); - acceptframe[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE); - acceptframe[4] = htonl(strlen(DNSTAP_CONTENT_TYPE)); - memmove(&acceptframe[5], DNSTAP_CONTENT_TYPE, - strlen(DNSTAP_CONTENT_TYPE)); fd_set_block(fd); - if(send(fd, (void*)acceptframe, len, 0) == -1) { + if(send(fd, acceptframe, len, 0) == -1) { #ifndef USE_WINSOCK log_err("send failed: %s", strerror(errno)); #else @@ -851,31 +797,28 @@ static int reply_with_accept(int fd) * returns 0 on error */ static int reply_with_finish(int fd) { - /* control frame on reply: - * 4 bytes 0 escape - * 4 bytes bigendian length of frame - * 4 bytes bigendian type FINISH - */ - uint32_t finishframe[3]; - /* len includes the escape and framelength */ - size_t len = 4+4+4; - finishframe[0] = 0; - finishframe[1] = htonl(4); - finishframe[2] = htonl(FSTRM_CONTROL_FRAME_FINISH); + size_t len = 0; + void* finishframe = fstrm_create_control_frame_finish(&len); + if(!finishframe) { + log_err("out of memory"); + return 0; + } fd_set_block(fd); - if(send(fd, (void*)finishframe, len, 0) == -1) { + if(send(fd, finishframe, len, 0) == -1) { #ifndef USE_WINSOCK log_err("send failed: %s", strerror(errno)); #else log_err("send failed: %s", wsa_strerror(WSAGetLastError())); #endif fd_set_nonblock(fd); + free(finishframe); return 0; } if(verbosity) log_info("sent control frame(finish)"); fd_set_nonblock(fd); + free(finishframe); return 1; } From 9473b0b2c5d9f762ca21d592610863ceb5d788c9 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Tue, 18 Feb 2020 17:20:45 +0100 Subject: [PATCH 80/96] Fix issue reported by clang analyzer. --- dnstap/dnstap_fstrm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnstap/dnstap_fstrm.c b/dnstap/dnstap_fstrm.c index aac98e567..4d4cb835e 100644 --- a/dnstap/dnstap_fstrm.c +++ b/dnstap/dnstap_fstrm.c @@ -197,7 +197,7 @@ char* fstrm_describe_control(void* pkt, size_t len) remain -= (8 + field_len); } if(remain > 0) - at+=snprintf(buf+at, sizeof(buf)-at, " trailing-bytes" + snprintf(buf+at, sizeof(buf)-at, " trailing-bytes" "(length %u)", (unsigned int)remain); return strdup(buf); } From 57baa78dd137555b9a3b23f77ad94fcb778243c7 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 19 Feb 2020 17:33:36 +0100 Subject: [PATCH 81/96] Fix memory leak in error case. From review. --- dnstap/dnstap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dnstap/dnstap.c b/dnstap/dnstap.c index c34f08b2e..cd4c070f2 100644 --- a/dnstap/dnstap.c +++ b/dnstap/dnstap.c @@ -150,6 +150,7 @@ dt_create(struct config_file* cfg) return NULL; } if(!dt_io_thread_apply_cfg(env->dtio, cfg)) { + dt_io_thread_delete(env->dtio); free(env); return NULL; } From 58b7e732b839f46b20d940d1ed062b7e7bddc8a0 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 26 Feb 2020 12:05:38 +0100 Subject: [PATCH 82/96] Fixup dtstream.h file description comment. And for dtstream.c too. --- dnstap/dtstream.c | 2 +- dnstap/dtstream.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 27a3d570c..8c51729be 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -1,5 +1,5 @@ /* - * dnstap/dtstream.c - Frame Streams implementation for unbound DNSTAP + * dnstap/dtstream.h - Frame Streams thread for unbound DNSTAP * * Copyright (c) 2020, NLnet Labs. All rights reserved. * diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index bb6cebbe6..1359af7a9 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -1,5 +1,5 @@ /* - * dnstap/dtstream.h - Frame Streams implementation for unbound DNSTAP + * dnstap/dtstream.h - Frame Streams thread for unbound DNSTAP * * Copyright (c) 2020, NLnet Labs. All rights reserved. * From 6a51e9e037549339fadfac5a68526c51f8fc88c0 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 26 Feb 2020 12:14:52 +0100 Subject: [PATCH 83/96] Add dnstap io callbacks to fptr whitelist event. --- dnstap/dtstream.c | 10 +++++----- dnstap/dtstream.h | 15 +++++++++++++++ util/fptr_wlist.c | 10 ++++++++++ 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 8c51729be..744e6acde 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -463,7 +463,7 @@ static int dtio_find_msg(struct dt_io_thread* dtio) } /** callback for the dnstap reconnect, to start reconnecting to output */ -static void dtio_reconnect_timeout_cb(int ATTR_UNUSED(fd), +void dtio_reconnect_timeout_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg) { struct dt_io_thread* dtio = (struct dt_io_thread*)arg; @@ -1146,7 +1146,7 @@ static int dtio_ssl_handshake(struct dt_io_thread* dtio, #endif /* HAVE_SSL */ /** callback for the dnstap events, to write to the output */ -static void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg) +void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg) { struct dt_io_thread* dtio = (struct dt_io_thread*)arg; int i; @@ -1210,7 +1210,7 @@ static void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg) } /** callback for the dnstap commandpipe, to stop the dnstap IO */ -static void dtio_cmd_cb(int fd, short ATTR_UNUSED(bits), void* arg) +void dtio_cmd_cb(int fd, short ATTR_UNUSED(bits), void* arg) { struct dt_io_thread* dtio = (struct dt_io_thread*)arg; uint8_t cmd; @@ -1349,7 +1349,7 @@ static int dtio_control_stop_send(struct stop_flush_info* info) return 1; } -static void dtio_stop_timer_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), +void dtio_stop_timer_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg) { struct stop_flush_info* info = (struct stop_flush_info*)arg; @@ -1360,7 +1360,7 @@ static void dtio_stop_timer_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), dtio_stop_flush_exit(info); } -static void dtio_stop_ev_cb(int ATTR_UNUSED(fd), short bits, void* arg) +void dtio_stop_ev_cb(int ATTR_UNUSED(fd), short bits, void* arg) { struct stop_flush_info* info = (struct stop_flush_info*)arg; struct dt_io_thread* dtio = info->dtio; diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 1359af7a9..5bf84757a 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -281,4 +281,19 @@ int dt_io_thread_start(struct dt_io_thread* dtio, void* event_base_nothr, */ void dt_io_thread_stop(struct dt_io_thread* dtio); +/** callback for the dnstap reconnect, to start reconnecting to output */ +void dtio_reconnect_timeout_cb(int fd, short bits, void* arg); + +/** callback for the dnstap events, to write to the output */ +void dtio_output_cb(int fd, short bits, void* arg); + +/** callback for the dnstap commandpipe, to stop the dnstap IO */ +void dtio_cmd_cb(int fd, short bits, void* arg); + +/** callback for the timer when the thread stops and wants to finish up */ +void dtio_stop_timer_cb(int fd, short bits, void* arg); + +/** callback for the output when the thread stops and wants to finish up */ +void dtio_stop_ev_cb(int fd, short bits, void* arg); + #endif /* DTSTREAM_H */ diff --git a/util/fptr_wlist.c b/util/fptr_wlist.c index 84d41cc84..cf07a7aff 100644 --- a/util/fptr_wlist.c +++ b/util/fptr_wlist.c @@ -93,6 +93,9 @@ #ifdef USE_IPSET #include "ipset/ipset.h" #endif +#ifdef USE_DNSTAP +#include "dnstap/dtstream.h" +#endif int fptr_whitelist_comm_point(comm_point_callback_type *fptr) @@ -168,6 +171,13 @@ fptr_whitelist_event(void (*fptr)(int, short, void *)) else if(fptr == &tube_handle_signal) return 1; else if(fptr == &comm_base_handle_slow_accept) return 1; else if(fptr == &comm_point_http_handle_callback) return 1; +#ifdef USE_DNSTAP + else if(fptr == &dtio_output_cb) return 1; + else if(fptr == &dtio_cmd_cb) return 1; + else if(fptr == &dtio_reconnect_timeout_cb) return 1; + else if(fptr == &dtio_stop_timer_cb) return 1; + else if(fptr == &dtio_stop_ev_cb) return 1; +#endif #ifdef UB_ON_WINDOWS else if(fptr == &worker_win_stop_cb) return 1; #endif From e24d7c64a8e13160d3fee2c6fe9f9cbf952fcc3b Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 26 Feb 2020 12:21:42 +0100 Subject: [PATCH 84/96] Dnstap io, note that it creates a thread when possible. --- doc/unbound.conf.5.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index 7b48e2eaf..a9c109e60 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -2116,6 +2116,10 @@ re-establish a new connection later. This option defaults to 100 milliseconds. .SS DNSTAP Logging Options DNSTAP support, when compiled in, is enabled in the \fBdnstap:\fR section. +This starts an extra thread (when compiled with threading) that writes +the log information to the destination. If unbound is compiled without +threading it does not spawn a thread, but connects per-process to the +destination. .TP .B dnstap-enable: \fI If dnstap is enabled. Default no. If yes, it connects to the dnstap server From 5aa8ae510ed0b69cdb6daf8aca1fe00c1d625d82 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 26 Feb 2020 13:11:27 +0100 Subject: [PATCH 85/96] Fix spelling of dtstream.c --- dnstap/dtstream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 744e6acde..67ad72d61 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -1,5 +1,5 @@ /* - * dnstap/dtstream.h - Frame Streams thread for unbound DNSTAP + * dnstap/dtstream.c - Frame Streams thread for unbound DNSTAP * * Copyright (c) 2020, NLnet Labs. All rights reserved. * From f03245c362ffc78d522f4d8143448575a3e80bca Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 27 Feb 2020 16:28:36 +0100 Subject: [PATCH 86/96] Document log check functions. --- util/netevent.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/util/netevent.h b/util/netevent.h index 60824fc42..bb2cd1e53 100644 --- a/util/netevent.h +++ b/util/netevent.h @@ -783,11 +783,22 @@ void comm_base_handle_slow_accept(int fd, short event, void* arg); void comm_point_tcp_win_bio_cb(struct comm_point* c, void* ssl); #endif -/** see if errno for tcp connect has to be logged or not. This uses errno */ +/** + * See if errno for tcp connect has to be logged or not. This uses errno + * @param addr: apart from checking errno, the addr is checked for ip4mapped + * and broadcast type, hence passed. + * @param addrlen: length of the addr parameter. + * @return true if it needs to be logged. + */ int tcp_connect_errno_needs_log(struct sockaddr* addr, socklen_t addrlen); #ifdef HAVE_SSL -/** true if the ssl handshake error has to be squelched from the logs */ +/** + * True if the ssl handshake error has to be squelched from the logs + * @param err: the error returned by the openssl routine, ERR_get_error. + * This is a packed structure with elements that are examined. + * @return true if the error is squelched (not logged). + */ int squelch_err_ssl_handshake(unsigned long err); #endif From 398e2601454ec26e91a2d5119739545b4eb66054 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 27 Feb 2020 16:57:24 +0100 Subject: [PATCH 87/96] Fixup ssl authentication not available with check for it. --- dnstap/dtstream.c | 2 ++ util/net_help.c | 13 +++++++++++++ util/net_help.h | 7 +++++++ 3 files changed, 22 insertions(+) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 67ad72d61..29fc5ee59 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -302,6 +302,8 @@ int dt_io_thread_apply_cfg(struct dt_io_thread* dtio, struct config_file *cfg) log_err("dnstap setup: malloc failure"); return 0; } + if(!check_auth_name_for_ssl(dtio->tls_server_name)) + return 0; } if(cfg->dnstap_tls_client_key_file && cfg->dnstap_tls_client_key_file[0]) { diff --git a/util/net_help.c b/util/net_help.c index 898ebc900..cc1ca7ec5 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -1217,6 +1217,19 @@ void* outgoing_ssl_fd(void* sslctx, int fd) #endif } +int check_auth_name_for_ssl(char* auth_name) +{ + if(!auth_name) return 1; +#ifdef HAVE_SSL +#if !defined(HAVE_SSL_SET1_HOST) && !defined(HAVE_X509_VERIFY_PARAM_SET1_HOST) + log_err("the query has an auth_name %s, but libssl has no call to " + "perform TLS authentication. Remove that name from config " + "or upgrade the ssl crypto library.", auth_name); +#endif +#endif + return 1; +} + /** set the authname on an SSL structure, SSL* ssl */ int set_auth_name_on_ssl(void* ssl, char* auth_name) { diff --git a/util/net_help.h b/util/net_help.h index 6df9f9b39..d9ee37ad0 100644 --- a/util/net_help.h +++ b/util/net_help.h @@ -442,6 +442,13 @@ void* incoming_ssl_fd(void* sslctx, int fd); */ void* outgoing_ssl_fd(void* sslctx, int fd); +/** + * check if authname SSL functionality is available, false if not + * @param auth_name: the name for the remote server, used for error print. + * @return false if SSL functionality to check the SSL name is not available. + */ +int check_auth_name_for_ssl(char* auth_name); + /** * set auth name on SSL for verification * @param ssl: SSL* to set From 5b61afd38c7dd7a0368a526ab8dab0bf2fb90039 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 28 Feb 2020 08:11:11 +0100 Subject: [PATCH 88/96] Return 0 when ssl authentication is not available --- util/net_help.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/util/net_help.c b/util/net_help.c index cc1ca7ec5..2a392781d 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -1220,14 +1220,14 @@ void* outgoing_ssl_fd(void* sslctx, int fd) int check_auth_name_for_ssl(char* auth_name) { if(!auth_name) return 1; -#ifdef HAVE_SSL -#if !defined(HAVE_SSL_SET1_HOST) && !defined(HAVE_X509_VERIFY_PARAM_SET1_HOST) +#if defined(HAVE_SSL) && !defined(HAVE_SSL_SET1_HOST) && !defined(HAVE_X509_VERIFY_PARAM_SET1_HOST) log_err("the query has an auth_name %s, but libssl has no call to " "perform TLS authentication. Remove that name from config " "or upgrade the ssl crypto library.", auth_name); -#endif -#endif + return 0; +#else return 1; +#endif } /** set the authname on an SSL structure, SSL* ssl */ From 85c4e5883189f96e549113ae579d0f671b6799a5 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 28 Feb 2020 08:36:44 +0100 Subject: [PATCH 89/96] dnstap debug tool, document string change more clearly. --- dnstap/unbound-dnstap-socket.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index 0605d4d7c..f7974f319 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -474,8 +474,11 @@ static char* q_of_msg(ProtobufCBinaryData message) if(sldns_wire2str_rrquestion_buf(message.data+12, message.len-12, buf, sizeof(buf)) != 0) { /* remove trailing newline, tabs to spaces */ + /* remove the newline: */ if(buf[0] != 0) buf[strlen(buf)-1]=0; + /* remove first tab (before type) */ if(strrchr(buf, '\t')) *strrchr(buf, '\t')=' '; + /* remove second tab (before class) */ if(strrchr(buf, '\t')) *strrchr(buf, '\t')=' '; return strdup(buf); } From b63032b4dd7660c0e9bd8eac6f9ba8aac4baf94b Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 28 Feb 2020 08:55:10 +0100 Subject: [PATCH 90/96] dnstap io, fixup fptr_wlist for unbound_dnstap_socket tool. --- Makefile.in | 2 +- daemon/worker.c | 15 +++ dnstap/dtstream.h | 6 + dnstap/unbound-dnstap-socket.c | 221 ++++++++++++++++++++++++++++++++- libunbound/libworker.c | 16 +++ smallapp/worker_cb.c | 16 +++ util/fptr_wlist.c | 2 + 7 files changed, 271 insertions(+), 7 deletions(-) diff --git a/Makefile.in b/Makefile.in index 2636ed4d2..4373dd66a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -235,7 +235,7 @@ IPSET_SRC=@IPSET_SRC@ IPSET_OBJ=@IPSET_OBJ@ DNSTAP_SOCKET_SRC=dnstap/unbound-dnstap-socket.c DNSTAP_SOCKET_OBJ=unbound-dnstap-socket.lo -DNSTAP_SOCKET_OBJ_LINK=$(DNSTAP_SOCKET_OBJ) worker_cb.lo $(COMMON_OBJ) \ +DNSTAP_SOCKET_OBJ_LINK=$(DNSTAP_SOCKET_OBJ) $(COMMON_OBJ) \ $(COMPAT_OBJ) $(SLDNS_OBJ) LIBUNBOUND_SRC=libunbound/context.c libunbound/libunbound.c \ libunbound/libworker.c diff --git a/daemon/worker.c b/daemon/worker.c index 56002039b..cec6bcd66 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -2124,3 +2124,18 @@ int codeline_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b)) return 0; } +#ifdef USE_DNSTAP +void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), + void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} +#endif + +#ifdef USE_DNSTAP +void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), + void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} +#endif diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 5bf84757a..4bb027d5b 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -296,4 +296,10 @@ void dtio_stop_timer_cb(int fd, short bits, void* arg); /** callback for the output when the thread stops and wants to finish up */ void dtio_stop_ev_cb(int fd, short bits, void* arg); +/** callback for unbound-dnstap-socket */ +void dtio_tap_callback(int fd, short bits, void* arg); + +/** callback for unbound-dnstap-socket */ +void dtio_mainfdcallback(int fd, short bits, void* arg); + #endif /* DTSTREAM_H */ diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index f7974f319..f7d713b53 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -940,7 +940,7 @@ static int tap_handshake(struct tap_data* data) #endif /* HAVE_SSL */ /** callback for dnstap listener */ -static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) +void dtio_tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) { struct tap_data* data = (struct tap_data*)arg; if(verbosity>=3) log_info("tap callback"); @@ -1037,7 +1037,7 @@ static void tap_callback(int fd, short ATTR_UNUSED(bits), void* arg) } /** callback for main listening file descriptor */ -void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) +void dtio_mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) { struct tap_socket* tap_sock = (struct tap_socket*)arg; struct main_tap_data* maindata = (struct main_tap_data*) @@ -1114,7 +1114,7 @@ void mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg) if(!data->ssl) fatal_exit("could not SSL_new"); } data->ev = ub_event_new(maindata->base, s, UB_EV_READ | UB_EV_PERSIST, - &tap_callback, data); + &dtio_tap_callback, data); if(!data->ev) fatal_exit("could not ub_event_new"); if(ub_event_add(data->ev, NULL) != 0) fatal_exit("could not ub_event_add"); } @@ -1126,7 +1126,7 @@ static void setup_local_list(struct main_tap_data* maindata, struct config_strlist* item; for(item = local_list->first; item; item = item->next) { struct tap_socket* s; - s = tap_socket_new_local(item->str, &mainfdcallback, + s = tap_socket_new_local(item->str, &dtio_mainfdcallback, maindata); if(!s) fatal_exit("out of memory"); if(!tap_socket_list_insert(&maindata->acceptlist, s)) @@ -1141,7 +1141,7 @@ static void setup_tcp_list(struct main_tap_data* maindata, struct config_strlist* item; for(item = tcp_list->first; item; item = item->next) { struct tap_socket* s; - s = tap_socket_new_tcpaccept(item->str, &mainfdcallback, + s = tap_socket_new_tcpaccept(item->str, &dtio_mainfdcallback, maindata); if(!s) fatal_exit("out of memory"); if(!tap_socket_list_insert(&maindata->acceptlist, s)) @@ -1157,7 +1157,7 @@ static void setup_tls_list(struct main_tap_data* maindata, struct config_strlist* item; for(item = tls_list->first; item; item = item->next) { struct tap_socket* s; - s = tap_socket_new_tlsaccept(item->str, &mainfdcallback, + s = tap_socket_new_tlsaccept(item->str, &dtio_mainfdcallback, maindata, server_key, server_cert, verifypem); if(!s) fatal_exit("out of memory"); if(!tap_socket_list_insert(&maindata->acceptlist, s)) @@ -1351,3 +1351,212 @@ int main(int argc, char** argv) #endif return 0; } + +/***--- definitions to make fptr_wlist work. ---***/ +/* These are callbacks, similar to smallapp callbacks, except the debug + * tool callbacks are not in it */ +struct tube; +struct query_info; +#include "util/data/packed_rrset.h" + +void worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), + uint8_t* ATTR_UNUSED(buffer), size_t ATTR_UNUSED(len), + int ATTR_UNUSED(error), void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} + +int worker_handle_request(struct comm_point* ATTR_UNUSED(c), + void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), + struct comm_reply* ATTR_UNUSED(repinfo)) +{ + log_assert(0); + return 0; +} + +int worker_handle_reply(struct comm_point* ATTR_UNUSED(c), + void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), + struct comm_reply* ATTR_UNUSED(reply_info)) +{ + log_assert(0); + return 0; +} + +int worker_handle_service_reply(struct comm_point* ATTR_UNUSED(c), + void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), + struct comm_reply* ATTR_UNUSED(reply_info)) +{ + log_assert(0); + return 0; +} + +int remote_accept_callback(struct comm_point* ATTR_UNUSED(c), + void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), + struct comm_reply* ATTR_UNUSED(repinfo)) +{ + log_assert(0); + return 0; +} + +int remote_control_callback(struct comm_point* ATTR_UNUSED(c), + void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), + struct comm_reply* ATTR_UNUSED(repinfo)) +{ + log_assert(0); + return 0; +} + +void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} + +struct outbound_entry* worker_send_query( + struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags), + int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec), + int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr), + socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone), + size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream), + char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q)) +{ + log_assert(0); + return 0; +} + +#ifdef UB_ON_WINDOWS +void +worker_win_stop_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), void* + ATTR_UNUSED(arg)) { + log_assert(0); +} + +void +wsvc_cron_cb(void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} +#endif /* UB_ON_WINDOWS */ + +void +worker_alloc_cleanup(void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} + +struct outbound_entry* libworker_send_query( + struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags), + int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec), + int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr), + socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone), + size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream), + char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q)) +{ + log_assert(0); + return 0; +} + +int libworker_handle_reply(struct comm_point* ATTR_UNUSED(c), + void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), + struct comm_reply* ATTR_UNUSED(reply_info)) +{ + log_assert(0); + return 0; +} + +int libworker_handle_service_reply(struct comm_point* ATTR_UNUSED(c), + void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), + struct comm_reply* ATTR_UNUSED(reply_info)) +{ + log_assert(0); + return 0; +} + +void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), + uint8_t* ATTR_UNUSED(buffer), size_t ATTR_UNUSED(len), + int ATTR_UNUSED(error), void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} + +void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), + struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), + char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited)) +{ + log_assert(0); +} + +void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), + struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), + char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited)) +{ + log_assert(0); +} + +void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), + struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), + char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited)) +{ + log_assert(0); +} + +int context_query_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b)) +{ + log_assert(0); + return 0; +} + +void worker_stat_timer_cb(void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} + +void worker_probe_timer_cb(void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} + +void worker_start_accept(void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} + +void worker_stop_accept(void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} + +/** keep track of lock id in lock-verify application */ +struct order_id { + /** the thread id that created it */ + int thr; + /** the instance number of creation */ + int instance; +}; + +int order_lock_cmp(const void* e1, const void* e2) +{ + const struct order_id* o1 = e1; + const struct order_id* o2 = e2; + if(o1->thr < o2->thr) return -1; + if(o1->thr > o2->thr) return 1; + if(o1->instance < o2->instance) return -1; + if(o1->instance > o2->instance) return 1; + return 0; +} + +int +codeline_cmp(const void* a, const void* b) +{ + return strcmp(a, b); +} + +int replay_var_compare(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b)) +{ + log_assert(0); + return 0; +} + +void remote_get_opt_ssl(char* ATTR_UNUSED(str), void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} diff --git a/libunbound/libworker.c b/libunbound/libworker.c index 6cb97ff1f..0ed778903 100644 --- a/libunbound/libworker.c +++ b/libunbound/libworker.c @@ -1047,3 +1047,19 @@ wsvc_cron_cb(void* ATTR_UNUSED(arg)) log_assert(0); } #endif /* UB_ON_WINDOWS */ + +#ifdef USE_DNSTAP +void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), + void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} +#endif + +#ifdef USE_DNSTAP +void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), + void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} +#endif diff --git a/smallapp/worker_cb.c b/smallapp/worker_cb.c index 6c3bd0049..78d921a3c 100644 --- a/smallapp/worker_cb.c +++ b/smallapp/worker_cb.c @@ -248,3 +248,19 @@ void remote_get_opt_ssl(char* ATTR_UNUSED(str), void* ATTR_UNUSED(arg)) { log_assert(0); } + +#ifdef USE_DNSTAP +void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), + void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} +#endif + +#ifdef USE_DNSTAP +void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), + void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} +#endif diff --git a/util/fptr_wlist.c b/util/fptr_wlist.c index cf07a7aff..b124e7169 100644 --- a/util/fptr_wlist.c +++ b/util/fptr_wlist.c @@ -177,6 +177,8 @@ fptr_whitelist_event(void (*fptr)(int, short, void *)) else if(fptr == &dtio_reconnect_timeout_cb) return 1; else if(fptr == &dtio_stop_timer_cb) return 1; else if(fptr == &dtio_stop_ev_cb) return 1; + else if(fptr == &dtio_tap_callback) return 1; + else if(fptr == &dtio_mainfdcallback) return 1; #endif #ifdef UB_ON_WINDOWS else if(fptr == &worker_win_stop_cb) return 1; From 065506d1a8d8200cd96c1fe128d463e07693f04f Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 28 Feb 2020 09:11:10 +0100 Subject: [PATCH 91/96] dnstap io, use sldns_str_print to print to string. --- dnstap/dnstap_fstrm.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/dnstap/dnstap_fstrm.c b/dnstap/dnstap_fstrm.c index 4d4cb835e..55105ade5 100644 --- a/dnstap/dnstap_fstrm.c +++ b/dnstap/dnstap_fstrm.c @@ -44,6 +44,7 @@ #include "config.h" #include "dnstap/dnstap_fstrm.h" #include "sldns/sbuffer.h" +#include "sldns/wire2str.h" void* fstrm_create_control_frame_start(char* contenttype, size_t* len) { @@ -145,7 +146,8 @@ char* fstrm_describe_control(void* pkt, size_t len) { uint32_t frametype = 0; char buf[512]; - size_t at = 0, remain; + char* str = buf; + size_t remain, slen = sizeof(buf); uint8_t* pos; buf[0]=0; @@ -156,18 +158,17 @@ char* fstrm_describe_control(void* pkt, size_t len) } frametype = sldns_read_uint32(pkt); if(frametype == FSTRM_CONTROL_FRAME_ACCEPT) { - at+=snprintf(buf+at, sizeof(buf)-at, "accept"); + sldns_str_print(&str, &slen, "accept"); } else if(frametype == FSTRM_CONTROL_FRAME_START) { - at+=snprintf(buf+at, sizeof(buf)-at, "start"); + sldns_str_print(&str, &slen, "start"); } else if(frametype == FSTRM_CONTROL_FRAME_STOP) { - at+=snprintf(buf+at, sizeof(buf)-at, "stop"); + sldns_str_print(&str, &slen, "stop"); } else if(frametype == FSTRM_CONTROL_FRAME_READY) { - at+=snprintf(buf+at, sizeof(buf)-at, "ready"); + sldns_str_print(&str, &slen, "ready"); } else if(frametype == FSTRM_CONTROL_FRAME_FINISH) { - at+=snprintf(buf+at, sizeof(buf)-at, "finish"); + sldns_str_print(&str, &slen, "finish"); } else { - at+=snprintf(buf+at, sizeof(buf)-at, "type%d", - (int)frametype); + sldns_str_print(&str, &slen, "type%d", (int)frametype); } /* show the content type options */ @@ -177,18 +178,22 @@ char* fstrm_describe_control(void* pkt, size_t len) uint32_t field_type = sldns_read_uint32(pos); uint32_t field_len = sldns_read_uint32(pos+4); if(remain < field_len) { - at+=snprintf(buf+at, sizeof(buf)-at, "malformed_field"); + sldns_str_print(&str, &slen, "malformed_field"); break; } if(field_type == FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE) { - at+=snprintf(buf+at, sizeof(buf)-at, " content-type("); - if(at+field_len < sizeof(buf)) { - memmove(buf+at, pos+8, field_len); - at += field_len; + char tempf[512]; + sldns_str_print(&str, &slen, " content-type("); + if(field_len < sizeof(tempf)-1) { + memmove(tempf, pos+8, field_len); + tempf[field_len] = 0; + sldns_str_print(&str, &slen, "%s", tempf); + } else { + sldns_str_print(&str, &slen, ""); } - at+=snprintf(buf+at, sizeof(buf)-at, ")"); + sldns_str_print(&str, &slen, ")"); } else { - at+=snprintf(buf+at, sizeof(buf)-at, + sldns_str_print(&str, &slen, " field(type %u, length %u)", (unsigned int)field_type, (unsigned int)field_len); @@ -197,7 +202,7 @@ char* fstrm_describe_control(void* pkt, size_t len) remain -= (8 + field_len); } if(remain > 0) - snprintf(buf+at, sizeof(buf)-at, " trailing-bytes" + sldns_str_print(&str, &slen, " trailing-bytes" "(length %u)", (unsigned int)remain); return strdup(buf); } From e856908696ba04f5254cbdb83c9745b95bd4fd2c Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 28 Feb 2020 09:17:02 +0100 Subject: [PATCH 92/96] dnstap io, free alloced resource on fail path. --- dnstap/dnstap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnstap/dnstap.c b/dnstap/dnstap.c index cd4c070f2..cc5449dff 100644 --- a/dnstap/dnstap.c +++ b/dnstap/dnstap.c @@ -249,6 +249,8 @@ dt_init(struct dt_env *env) } if(!dt_io_thread_register_queue(env->dtio, env->msgqueue)) { log_err("malloc failure"); + dt_msg_queue_delete(env->msgqueue); + env->msgqueue = NULL; return 0; } return 1; From 49622dd51a6de81ab8ed0e19ca639102cc3763c1 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 28 Feb 2020 09:19:53 +0100 Subject: [PATCH 93/96] dnstap io, fix uniform error message for no dnstap-socket-path. --- dnstap/dtstream.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index 29fc5ee59..fe02cc2aa 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -265,9 +265,8 @@ int dt_io_thread_apply_cfg(struct dt_io_thread* dtio, struct config_file *cfg) if(dtio->upstream_is_unix) { if(!cfg->dnstap_socket_path || cfg->dnstap_socket_path[0]==0) { - log_err("dnstap setup failed, because dnstap is " - "enabled, but no dnstap-ip and no " - "dnstap-socket-path are given"); + log_err("dnstap setup: no dnstap-socket-path for " + "socket connect"); return 0; } free(dtio->socket_path); From ed5a9ed1b12378f31b099b9722a39beda8099283 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 28 Feb 2020 09:22:15 +0100 Subject: [PATCH 94/96] dnstap io, fix for review comment. --- dnstap/dtstream.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index fe02cc2aa..2d55d197f 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -1681,12 +1681,12 @@ static void dtio_open_output(struct dt_io_thread* dtio) dtio_reconnect_enable(dtio); return; } - } - if(dtio->upstream_is_tls) { - if(!dtio_setup_ssl(dtio)) { - dtio_close_fd(dtio); - dtio_reconnect_enable(dtio); - return; + if(dtio->upstream_is_tls) { + if(!dtio_setup_ssl(dtio)) { + dtio_close_fd(dtio); + dtio_reconnect_enable(dtio); + return; + } } } dtio->check_nb_connect = 1; From d5544a0f13e25de9d1f62bcfe0926216788f5f94 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 28 Feb 2020 11:09:45 +0100 Subject: [PATCH 95/96] dnstap io, cast void unused return value. --- dnstap/dnstap_fstrm.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/dnstap/dnstap_fstrm.c b/dnstap/dnstap_fstrm.c index 55105ade5..cce16e2e4 100644 --- a/dnstap/dnstap_fstrm.c +++ b/dnstap/dnstap_fstrm.c @@ -158,17 +158,17 @@ char* fstrm_describe_control(void* pkt, size_t len) } frametype = sldns_read_uint32(pkt); if(frametype == FSTRM_CONTROL_FRAME_ACCEPT) { - sldns_str_print(&str, &slen, "accept"); + (void)sldns_str_print(&str, &slen, "accept"); } else if(frametype == FSTRM_CONTROL_FRAME_START) { - sldns_str_print(&str, &slen, "start"); + (void)sldns_str_print(&str, &slen, "start"); } else if(frametype == FSTRM_CONTROL_FRAME_STOP) { - sldns_str_print(&str, &slen, "stop"); + (void)sldns_str_print(&str, &slen, "stop"); } else if(frametype == FSTRM_CONTROL_FRAME_READY) { - sldns_str_print(&str, &slen, "ready"); + (void)sldns_str_print(&str, &slen, "ready"); } else if(frametype == FSTRM_CONTROL_FRAME_FINISH) { - sldns_str_print(&str, &slen, "finish"); + (void)sldns_str_print(&str, &slen, "finish"); } else { - sldns_str_print(&str, &slen, "type%d", (int)frametype); + (void)sldns_str_print(&str, &slen, "type%d", (int)frametype); } /* show the content type options */ @@ -178,22 +178,22 @@ char* fstrm_describe_control(void* pkt, size_t len) uint32_t field_type = sldns_read_uint32(pos); uint32_t field_len = sldns_read_uint32(pos+4); if(remain < field_len) { - sldns_str_print(&str, &slen, "malformed_field"); + (void)sldns_str_print(&str, &slen, "malformed_field"); break; } if(field_type == FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE) { char tempf[512]; - sldns_str_print(&str, &slen, " content-type("); + (void)sldns_str_print(&str, &slen, " content-type("); if(field_len < sizeof(tempf)-1) { memmove(tempf, pos+8, field_len); tempf[field_len] = 0; - sldns_str_print(&str, &slen, "%s", tempf); + (void)sldns_str_print(&str, &slen, "%s", tempf); } else { - sldns_str_print(&str, &slen, ""); + (void)sldns_str_print(&str, &slen, ""); } - sldns_str_print(&str, &slen, ")"); + (void)sldns_str_print(&str, &slen, ")"); } else { - sldns_str_print(&str, &slen, + (void)sldns_str_print(&str, &slen, " field(type %u, length %u)", (unsigned int)field_type, (unsigned int)field_len); @@ -202,7 +202,7 @@ char* fstrm_describe_control(void* pkt, size_t len) remain -= (8 + field_len); } if(remain > 0) - sldns_str_print(&str, &slen, " trailing-bytes" + (void)sldns_str_print(&str, &slen, " trailing-bytes" "(length %u)", (unsigned int)remain); return strdup(buf); } From e13dfc743d6864cff6ae909cbc1026b1b666c888 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 28 Feb 2020 11:10:12 +0100 Subject: [PATCH 96/96] For incoming ssl context with verifypem != NULL, we can set SSL_VERIFY_FAIL_IF_NO_PEER_CERT that can reject client connections without peer cert during the handshake, which is nicer than just a connection drop to the client (when we then check for no peer certificate afterwards). --- util/net_help.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/net_help.c b/util/net_help.c index 2a392781d..8f75da07f 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -996,7 +996,7 @@ void* listen_sslctx_create(char* key, char* pem, char* verifypem) } SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file( verifypem)); - SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); } return ctx; #else