mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-28 02:29:51 -05:00
- Add DNS-over-HTTPS support
This commit is contained in:
parent
ce7fd591c6
commit
8dae5d9f81
26 changed files with 6188 additions and 4564 deletions
49
Makefile.in
49
Makefile.in
|
|
@ -663,7 +663,7 @@ dns.lo dns.o: $(srcdir)/services/cache/dns.c config.h $(srcdir)/iterator/iter_de
|
|||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h $(srcdir)/services/cache/dns.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
|
||||
$(srcdir)/util/data/dname.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h \
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/dname.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
|
||||
infra.lo infra.o: $(srcdir)/services/cache/infra.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h \
|
||||
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/services/cache/infra.h \
|
||||
|
|
@ -704,10 +704,11 @@ msgreply.lo msgreply.o: $(srcdir)/util/data/msgreply.c config.h $(srcdir)/util/d
|
|||
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
|
||||
$(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
|
||||
$(srcdir)/respip/respip.h
|
||||
packed_rrset.lo packed_rrset.o: $(srcdir)/util/data/packed_rrset.c config.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/regional.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h
|
||||
packed_rrset.lo packed_rrset.o: $(srcdir)/util/data/packed_rrset.c config.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h \
|
||||
$(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h
|
||||
iterator.lo iterator.o: $(srcdir)/iterator/iterator.c config.h $(srcdir)/iterator/iterator.h \
|
||||
$(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \
|
||||
|
|
@ -776,7 +777,7 @@ listen_dnsport.lo listen_dnsport.o: $(srcdir)/services/listen_dnsport.c config.h
|
|||
$(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/sldns/sbuffer.h $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
|
||||
|
|
@ -799,10 +800,10 @@ mesh.lo mesh.o: $(srcdir)/services/mesh.c config.h $(srcdir)/services/mesh.h $(s
|
|||
$(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
|
||||
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
|
||||
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
|
||||
$(srcdir)/services/outbound_list.h $(srcdir)/services/cache/dns.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/util/regional.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
|
||||
$(srcdir)/util/alloc.h $(srcdir)/util/edns.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/data/dname.h \
|
||||
$(srcdir)/services/listen_dnsport.h
|
||||
$(srcdir)/services/outbound_list.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
|
||||
$(srcdir)/util/data/msgencode.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/alloc.h \
|
||||
$(srcdir)/util/edns.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/data/dname.h $(srcdir)/services/listen_dnsport.h
|
||||
modstack.lo modstack.o: $(srcdir)/services/modstack.c config.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
|
||||
|
|
@ -903,7 +904,7 @@ fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/
|
|||
$(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
|
||||
$(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/mini_event.h \
|
||||
$(srcdir)/services/outside_network.h $(srcdir)/services/cache/infra.h \
|
||||
$(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h \
|
||||
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
|
||||
|
|
@ -914,15 +915,7 @@ fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/
|
|||
$(srcdir)/libunbound/worker.h
|
||||
locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
|
||||
log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h
|
||||
mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
|
||||
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
|
||||
$(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
|
||||
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
|
||||
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h
|
||||
mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h
|
||||
module.lo module.o: $(srcdir)/util/module.c config.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
|
||||
|
|
@ -994,7 +987,7 @@ tube.lo tube.o: $(srcdir)/util/tube.c config.h $(srcdir)/util/tube.h $(srcdir)/u
|
|||
$(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/ub_event.h
|
||||
ub_event.lo ub_event.o: $(srcdir)/util/ub_event.c config.h $(srcdir)/util/ub_event.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/tube.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
|
||||
$(srcdir)/util/tube.h
|
||||
ub_event_pluggable.lo ub_event_pluggable.o: $(srcdir)/util/ub_event_pluggable.c config.h $(srcdir)/util/ub_event.h \
|
||||
$(srcdir)/libunbound/unbound-event.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
|
||||
|
|
@ -1004,7 +997,7 @@ ub_event_pluggable.lo ub_event_pluggable.o: $(srcdir)/util/ub_event_pluggable.c
|
|||
$(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
|
||||
$(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
|
||||
$(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h
|
||||
winsock_event.lo winsock_event.o: $(srcdir)/util/winsock_event.c config.h
|
||||
autotrust.lo autotrust.o: $(srcdir)/validator/autotrust.c config.h $(srcdir)/validator/autotrust.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
|
||||
|
|
@ -1273,7 +1266,8 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
|
|||
$(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.h \
|
||||
$(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h \
|
||||
$(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h \
|
||||
$(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h
|
||||
$(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h \
|
||||
$(srcdir)/dnstap/dtstream.h
|
||||
testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/testcode/testpkts.h \
|
||||
$(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h \
|
||||
|
|
@ -1307,7 +1301,8 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
|
|||
$(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.h \
|
||||
$(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h \
|
||||
$(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h \
|
||||
$(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h
|
||||
$(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h \
|
||||
$(srcdir)/dnstap/dtstream.h
|
||||
acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
|
||||
|
|
@ -1470,6 +1465,12 @@ unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c confi
|
|||
unbound-anchor.lo unbound-anchor.o: $(srcdir)/smallapp/unbound-anchor.c config.h $(srcdir)/libunbound/unbound.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h
|
||||
petal.lo petal.o: $(srcdir)/testcode/petal.c config.h
|
||||
unbound-dnstap-socket.lo unbound-dnstap-socket.o: $(srcdir)/dnstap/unbound-dnstap-socket.c config.h \
|
||||
$(srcdir)/dnstap/dtstream.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/dnstap/dnstap_fstrm.h \
|
||||
$(srcdir)/util/ub_event.h $(srcdir)/util/net_help.h $(srcdir)/services/listen_dnsport.h \
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/config_file.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h
|
||||
pythonmod_utils.lo pythonmod_utils.o: $(srcdir)/pythonmod/pythonmod_utils.c config.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
|
|
|
|||
23
config.h.in
23
config.h.in
|
|
@ -28,6 +28,9 @@
|
|||
/* Whether daemon is deprecated */
|
||||
#undef DEPRECATED_DAEMON
|
||||
|
||||
/* Define this to enable kernel based UDP source port randomization. */
|
||||
#undef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
|
||||
/* default dnstap socket path */
|
||||
#undef DNSTAP_SOCKET_PATH
|
||||
|
||||
|
|
@ -110,6 +113,10 @@
|
|||
don't. */
|
||||
#undef HAVE_DECL_INET_PTON
|
||||
|
||||
/* Define to 1 if you have the declaration of `nghttp2_session_server_new',
|
||||
and to 0 if you don't. */
|
||||
#undef HAVE_DECL_NGHTTP2_SESSION_SERVER_NEW
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_ED25519
|
||||
|
|
@ -368,6 +375,12 @@
|
|||
/* Define to 1 if you have the <nettle/eddsa.h> header file. */
|
||||
#undef HAVE_NETTLE_EDDSA_H
|
||||
|
||||
/* Define this to use nghttp2 client. */
|
||||
#undef HAVE_NGHTTP2
|
||||
|
||||
/* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */
|
||||
#undef HAVE_NGHTTP2_NGHTTP2_H
|
||||
|
||||
/* Use libnss for crypto */
|
||||
#undef HAVE_NSS
|
||||
|
||||
|
|
@ -491,6 +504,9 @@
|
|||
/* Define if you have the SSL libraries installed. */
|
||||
#undef HAVE_SSL
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_alpn_select_cb' function. */
|
||||
#undef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_ciphersuites' function. */
|
||||
#undef HAVE_SSL_CTX_SET_CIPHERSUITES
|
||||
|
||||
|
|
@ -811,9 +827,8 @@
|
|||
/* Define to 1 to use ipset support */
|
||||
#undef USE_IPSET
|
||||
|
||||
/* Define to 1 to disable explict UDP source port randomisation and rely on the
|
||||
kernel to provide random source ports */
|
||||
#undef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
/* Define if you enable libevent */
|
||||
#undef USE_LIBEVENT
|
||||
|
||||
/* Define if you want to use internal select based events */
|
||||
#undef USE_MINI_EVENT
|
||||
|
|
@ -1349,6 +1364,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
|||
#define UNBOUND_DNS_PORT 53
|
||||
/** default port for DNS over TLS traffic. */
|
||||
#define UNBOUND_DNS_OVER_TLS_PORT 853
|
||||
/** default port for DNS over HTTPS traffic. */
|
||||
#define UNBOUND_DNS_OVER_HTTPS_PORT 443
|
||||
/** default port for unbound control traffic, registered port with IANA,
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control */
|
||||
#define UNBOUND_CONTROL_PORT 8953
|
||||
|
|
|
|||
123
configure
vendored
123
configure
vendored
|
|
@ -804,6 +804,7 @@ infodir
|
|||
docdir
|
||||
oldincludedir
|
||||
includedir
|
||||
runstatedir
|
||||
localstatedir
|
||||
sharedstatedir
|
||||
sysconfdir
|
||||
|
|
@ -877,6 +878,7 @@ enable_tfo_server
|
|||
with_libevent
|
||||
with_libexpat
|
||||
with_libhiredis
|
||||
with_libnghttp2
|
||||
enable_static_exe
|
||||
enable_fully_static
|
||||
enable_lock_checks
|
||||
|
|
@ -951,6 +953,7 @@ 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,6 +1206,15 @@ 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=* \
|
||||
|
|
@ -1340,7 +1352,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
|
||||
libdir localedir mandir runstatedir
|
||||
do
|
||||
eval ac_val=\$$ac_var
|
||||
# Remove trailing slashes.
|
||||
|
|
@ -1493,6 +1505,7 @@ 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]
|
||||
|
|
@ -1635,6 +1648,7 @@ Optional Packages:
|
|||
outgoing port ranges.
|
||||
--with-libexpat=path specify explicit path for libexpat.
|
||||
--with-libhiredis=path specify explicit path for libhiredis.
|
||||
--with-libnghttp2=path specify explicit path for libnghttp2.
|
||||
--with-dnstap-socket-path=pathname
|
||||
set default dnstap socket path
|
||||
--with-protobuf-c=path Path where protobuf-c is installed, for dnstap
|
||||
|
|
@ -15666,7 +15680,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 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
|
|
@ -15712,7 +15726,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 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
|
|
@ -15736,7 +15750,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 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
|
|
@ -15781,7 +15795,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 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
|
|
@ -15805,7 +15819,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 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
|
|
@ -18306,7 +18320,7 @@ done
|
|||
# these check_funcs need -lssl
|
||||
BAKLIBS="$LIBS"
|
||||
LIBS="-lssl $LIBS"
|
||||
for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites
|
||||
for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_alpn_select_cb
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
|
|
@ -19124,31 +19138,34 @@ esac
|
|||
if test "${with_libevent+set}" = set; then :
|
||||
withval=$with_libevent;
|
||||
else
|
||||
withval="no"
|
||||
with_libevent="no"
|
||||
fi
|
||||
|
||||
if test x_$withval = x_yes -o x_$withval != x_no; then
|
||||
if test "x_$with_libevent" != x_no; then
|
||||
|
||||
$as_echo "#define USE_LIBEVENT 1" >>confdefs.h
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libevent" >&5
|
||||
$as_echo_n "checking for libevent... " >&6; }
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
if test "x_$with_libevent" = x_ -o "x_$with_libevent" = x_yes; then
|
||||
with_libevent="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
fi
|
||||
for dir in $withval; do
|
||||
for dir in $with_libevent; do
|
||||
thedir="$dir"
|
||||
if test -f "$dir/include/event.h" -o -f "$dir/include/event2/event.h"; then
|
||||
found_libevent="yes"
|
||||
if test "$thedir" != "/usr"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$thedir/include"
|
||||
fi
|
||||
break;
|
||||
fi
|
||||
if test "$thedir" != "/usr"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$thedir/include"
|
||||
fi
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libevent != x_yes; then
|
||||
if test -f "$dir/event.h" -a \( -f "$dir/libevent.la" -o -f "$dir/libev.la" \) ; then
|
||||
# libevent source directory
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $thedir" >&5
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $thedir" >&5
|
||||
$as_echo "found in $thedir" >&6; }
|
||||
CPPFLAGS="$CPPFLAGS -I$thedir -I$thedir/include"
|
||||
CPPFLAGS="$CPPFLAGS -I$thedir -I$thedir/include"
|
||||
BAK_LDFLAGS_SET="1"
|
||||
BAK_LDFLAGS="$LDFLAGS"
|
||||
# remove evdns from linking
|
||||
|
|
@ -19161,10 +19178,10 @@ $as_echo "found in $thedir" >&6; }
|
|||
cp $ev_files_o build/libevent
|
||||
cp $ev_files_lo build/libevent
|
||||
cp $ev_files_libso build/libevent/.libs
|
||||
LATE_LDFLAGS="build/libevent/*.lo -lm"
|
||||
LATE_LDFLAGS="build/libevent/*.lo -lm"
|
||||
LDFLAGS="build/libevent/*.o $LDFLAGS -lm"
|
||||
else
|
||||
as_fn_error $? "Cannot find the libevent library in $withval
|
||||
as_fn_error $? "Cannot find the libevent library in $with_libevent
|
||||
You can restart ./configure --with-libevent=no to use a builtin alternative.
|
||||
Please note that this alternative is not as capable as libevent when using
|
||||
large outgoing port ranges. " "$LINENO" 5
|
||||
|
|
@ -19615,6 +19632,70 @@ _ACEOF
|
|||
|
||||
fi
|
||||
|
||||
# nghttp2
|
||||
|
||||
# Check whether --with-libnghttp2 was given.
|
||||
if test "${with_libnghttp2+set}" = set; then :
|
||||
withval=$with_libnghttp2;
|
||||
else
|
||||
withval="no"
|
||||
fi
|
||||
|
||||
found_libnghttp2="no"
|
||||
if test x_$withval = x_yes -o x_$withval != x_no; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libnghttp2" >&5
|
||||
$as_echo_n "checking for libnghttp2... " >&6; }
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
fi
|
||||
for dir in $withval ; do
|
||||
if test -f "$dir/include/nghttp2/nghttp2.h"; then
|
||||
found_libnghttp2="yes"
|
||||
if test "$dir" != "/usr"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$dir/include"
|
||||
LDFLAGS="$LDFLAGS -L$dir/lib"
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $dir" >&5
|
||||
$as_echo "found in $dir" >&6; }
|
||||
|
||||
$as_echo "#define HAVE_NGHTTP2 1" >>confdefs.h
|
||||
|
||||
LIBS="$LIBS -lnghttp2"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libnghttp2 != x_yes; then
|
||||
as_fn_error $? "Could not find libnghttp2, nghttp2.h" "$LINENO" 5
|
||||
fi
|
||||
for ac_header in nghttp2/nghttp2.h
|
||||
do :
|
||||
ac_fn_c_check_header_compile "$LINENO" "nghttp2/nghttp2.h" "ac_cv_header_nghttp2_nghttp2_h" "$ac_includes_default
|
||||
"
|
||||
if test "x$ac_cv_header_nghttp2_nghttp2_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_NGHTTP2_NGHTTP2_H 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
ac_fn_c_check_decl "$LINENO" "nghttp2_session_server_new" "ac_cv_have_decl_nghttp2_session_server_new" "$ac_includes_default
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_have_decl_nghttp2_session_server_new" = xyes; then :
|
||||
ac_have_decl=1
|
||||
else
|
||||
ac_have_decl=0
|
||||
fi
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_DECL_NGHTTP2_SESSION_SERVER_NEW $ac_have_decl
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
# set static linking for uninstalled libraries if requested
|
||||
|
||||
staticexe=""
|
||||
|
|
|
|||
37
configure.ac
37
configure.ac
|
|
@ -830,7 +830,7 @@ AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_C
|
|||
# these check_funcs need -lssl
|
||||
BAKLIBS="$LIBS"
|
||||
LIBS="-lssl $LIBS"
|
||||
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites])
|
||||
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_alpn_select_cb])
|
||||
LIBS="$BAKLIBS"
|
||||
|
||||
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
|
||||
|
|
@ -1369,6 +1369,39 @@ if test x_$withval = x_yes -o x_$withval != x_no; then
|
|||
])
|
||||
fi
|
||||
|
||||
# nghttp2
|
||||
AC_ARG_WITH(libnghttp2, AC_HELP_STRING([--with-libnghttp2=path],
|
||||
[specify explicit path for libnghttp2.]),
|
||||
[ ],[ withval="no" ])
|
||||
found_libnghttp2="no"
|
||||
if test x_$withval = x_yes -o x_$withval != x_no; then
|
||||
AC_MSG_CHECKING(for libnghttp2)
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
fi
|
||||
for dir in $withval ; do
|
||||
if test -f "$dir/include/nghttp2/nghttp2.h"; then
|
||||
found_libnghttp2="yes"
|
||||
dnl assume /usr is in default path.
|
||||
if test "$dir" != "/usr"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$dir/include"
|
||||
LDFLAGS="$LDFLAGS -L$dir/lib"
|
||||
fi
|
||||
AC_MSG_RESULT(found in $dir)
|
||||
AC_DEFINE([HAVE_NGHTTP2], [1], [Define this to use nghttp2 client.])
|
||||
LIBS="$LIBS -lnghttp2"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libnghttp2 != x_yes; then
|
||||
AC_ERROR([Could not find libnghttp2, nghttp2.h])
|
||||
fi
|
||||
AC_CHECK_HEADERS([nghttp2/nghttp2.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_DECLS([nghttp2_session_server_new], [], [], [AC_INCLUDES_DEFAULT
|
||||
#include <nghttp2/nghttp2.h>
|
||||
])
|
||||
fi
|
||||
|
||||
# set static linking for uninstalled libraries if requested
|
||||
AC_SUBST(staticexe)
|
||||
staticexe=""
|
||||
|
|
@ -2105,6 +2138,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
|||
#define UNBOUND_DNS_PORT 53
|
||||
/** default port for DNS over TLS traffic. */
|
||||
#define UNBOUND_DNS_OVER_TLS_PORT 853
|
||||
/** default port for DNS over HTTPS traffic. */
|
||||
#define UNBOUND_DNS_OVER_HTTPS_PORT 443
|
||||
/** default port for unbound control traffic, registered port with IANA,
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control */
|
||||
#define UNBOUND_CONTROL_PORT 8953
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
|
|||
|
||||
/* open fd */
|
||||
fd = create_tcp_accept_sock(res, 1, &noproto, 0,
|
||||
cfg->ip_transparent, 0, cfg->ip_freebind, cfg->use_systemd);
|
||||
cfg->ip_transparent, 0, 0, cfg->ip_freebind, cfg->use_systemd);
|
||||
freeaddrinfo(res);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1109,7 +1109,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||
struct respip_client_info* cinfo = NULL, cinfo_tmp;
|
||||
memset(&qinfo, 0, sizeof(qinfo));
|
||||
|
||||
if(error != NETEVENT_NOERROR || !repinfo) {
|
||||
if((error != NETEVENT_NOERROR && error != NETEVENT_DONE)|| !repinfo) {
|
||||
/* some bad tcp query DNS formats give these error calls */
|
||||
verbose(VERB_ALGO, "handle request called with err=%d", error);
|
||||
return 0;
|
||||
|
|
@ -1797,7 +1797,8 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
|||
cfg->do_tcp_keepalive
|
||||
? cfg->tcp_keepalive_timeout
|
||||
: cfg->tcp_idle_timeout,
|
||||
worker->daemon->tcl,
|
||||
cfg->harden_large_queries,
|
||||
worker->daemon->tcl,
|
||||
worker->daemon->listen_sslctx,
|
||||
dtenv, worker_handle_request, worker);
|
||||
if(!worker->front) {
|
||||
|
|
|
|||
|
|
@ -729,12 +729,14 @@ server:
|
|||
# add a netblock specific override to a localzone, with zone type
|
||||
# local-zone-override: "example.com" 192.0.2.0/24 refuse
|
||||
|
||||
# service clients over TLS (on the TCP sockets), with plain DNS inside
|
||||
# the TLS stream. Give the certificate to use and private key.
|
||||
# service clients over TLS (on the TCP sockets) with plain DNS inside
|
||||
# the TLS stream, and over HTTPS using HTTP/2 as specified in RFC8484.
|
||||
# Give the certificate to use and private key.
|
||||
# default is "" (disabled). requires restart to take effect.
|
||||
# tls-service-key: "path/to/privatekeyfile.key"
|
||||
# tls-service-pem: "path/to/publiccertfile.pem"
|
||||
# tls-port: 853
|
||||
# https-port: 443
|
||||
|
||||
# cipher setting for TLSv1.2
|
||||
# tls-ciphers: "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256"
|
||||
|
|
|
|||
|
|
@ -469,15 +469,16 @@ Alternate syntax for \fBtls\-upstream\fR. If both are present in the config
|
|||
file the last is used.
|
||||
.TP
|
||||
.B tls\-service\-key: \fI<file>
|
||||
If enabled, the server provides TLS service on the TCP ports marked
|
||||
implicitly or explicitly for TLS service with tls\-port. The file must
|
||||
contain the private key for the TLS session, the public certificate is in
|
||||
the tls\-service\-pem file and it must also be specified if tls\-service\-key
|
||||
is specified. The default is "", turned off. Enabling or disabling
|
||||
this service requires a restart (a reload is not enough), because the
|
||||
key is read while root permissions are held and before chroot (if any).
|
||||
The ports enabled implicitly or explicitly via \fBtls\-port:\fR do not provide
|
||||
normal DNS TCP service.
|
||||
If enabled, the server provides DNS-over-TLS or DNS-over-HTTPS service on the
|
||||
TCP ports marked implicitly or explicitly for these services with tls\-port or
|
||||
https\-port. The file must contain the private key for the TLS session, the
|
||||
public certificate is in the tls\-service\-pem file and it must also be
|
||||
specified if tls\-service\-key is specified. The default is "", turned off.
|
||||
Enabling or disabling this service requires a restart (a reload is not enough),
|
||||
because the key is read while root permissions are held and before chroot (if any).
|
||||
The ports enabled implicitly or explicitly via \fBtls\-port:\fR and
|
||||
\fBhttps\-port:\fR do not provide normal DNS TCP service. Unbound needs to be
|
||||
compiled with libnghttp2 in order to provide DNS-over-HTTPS.
|
||||
.TP
|
||||
.B ssl\-service\-key: \fI<file>
|
||||
Alternate syntax for \fBtls\-service\-key\fR.
|
||||
|
|
@ -493,6 +494,10 @@ Alternate syntax for \fBtls\-service\-pem\fR.
|
|||
The port number on which to provide TCP TLS service, default 853, only
|
||||
interfaces configured with that port number as @number get the TLS service.
|
||||
.TP
|
||||
.B https\-port: \fI<number>
|
||||
The port number on which to provide DNS-over-HTTPS service, default 443, only
|
||||
interfaces configured with that port number as @number get the HTTPS service.
|
||||
.TP
|
||||
.B ssl\-port: \fI<number>
|
||||
Alternate syntax for \fBtls\-port\fR.
|
||||
.TP
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/parseutil.h"
|
||||
#include "services/mesh.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/locks.h"
|
||||
|
|
@ -638,7 +639,8 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
|||
|
||||
int
|
||||
create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||
int* reuseport, int transparent, int mss, int freebind, int use_systemd)
|
||||
int* reuseport, int transparent, int mss, int nodelay, int freebind,
|
||||
int use_systemd)
|
||||
{
|
||||
int s;
|
||||
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_V6ONLY) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND) || defined(SO_BINDANY)
|
||||
|
|
@ -685,6 +687,36 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
|||
#endif
|
||||
return -1;
|
||||
}
|
||||
if(nodelay) {
|
||||
#if defined(IPPROTO_TCP) && defined(TCP_NODELAY)
|
||||
if(setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void*)&on,
|
||||
(socklen_t)sizeof(on)) < 0) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err(" setsockopt(.. TCP_NODELAY ..) failed: %s",
|
||||
strerror(errno));
|
||||
#else
|
||||
log_err(" setsockopt(.. TCP_NODELAY ..) failed: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
log_warn(" setsockopt(TCP_NODELAY) unsupported");
|
||||
#endif /* defined(IPPROTO_TCP) && defined(TCP_NODELAY) */
|
||||
#if defined(IPPROTO_TCP) && defined(TCP_QUICKACK)
|
||||
if(setsockopt(s, IPPROTO_TCP, TCP_QUICKACK, (void*)&on,
|
||||
(socklen_t)sizeof(on)) < 0) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err(" setsockopt(.. TCP_QUICKACK ..) failed: %s",
|
||||
strerror(errno));
|
||||
#else
|
||||
log_err(" setsockopt(.. TCP_QUICKACK ..) failed: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
log_warn(" setsockopt(TCP_QUICKACK) unsupported");
|
||||
#endif /* defined(IPPROTO_TCP) && defined(TCP_QUICKACK) */
|
||||
}
|
||||
if (mss > 0) {
|
||||
#if defined(IPPROTO_TCP) && defined(TCP_MAXSEG)
|
||||
if(setsockopt(s, IPPROTO_TCP, TCP_MAXSEG, (void*)&mss,
|
||||
|
|
@ -952,7 +984,8 @@ err:
|
|||
static int
|
||||
make_sock(int stype, const char* ifname, const char* port,
|
||||
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
|
||||
int* reuseport, int transparent, int tcp_mss, int freebind, int use_systemd)
|
||||
int* reuseport, int transparent, int tcp_mss, int nodelay, int freebind,
|
||||
int use_systemd)
|
||||
{
|
||||
struct addrinfo *res = NULL;
|
||||
int r, s, inuse, noproto;
|
||||
|
|
@ -988,7 +1021,7 @@ make_sock(int stype, const char* ifname, const char* port,
|
|||
}
|
||||
} else {
|
||||
s = create_tcp_accept_sock(res, v6only, &noproto, reuseport,
|
||||
transparent, tcp_mss, freebind, use_systemd);
|
||||
transparent, tcp_mss, nodelay, freebind, use_systemd);
|
||||
if(s == -1 && noproto && hints->ai_family == AF_INET6){
|
||||
*noip6 = 1;
|
||||
}
|
||||
|
|
@ -1001,7 +1034,8 @@ make_sock(int stype, const char* ifname, const char* port,
|
|||
static int
|
||||
make_sock_port(int stype, const char* ifname, const char* port,
|
||||
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
|
||||
int* reuseport, int transparent, int tcp_mss, int freebind, int use_systemd)
|
||||
int* reuseport, int transparent, int tcp_mss, int nodelay, int freebind,
|
||||
int use_systemd)
|
||||
{
|
||||
char* s = strchr(ifname, '@');
|
||||
if(s) {
|
||||
|
|
@ -1023,10 +1057,11 @@ make_sock_port(int stype, const char* ifname, const char* port,
|
|||
(void)strlcpy(p, s+1, sizeof(p));
|
||||
p[strlen(s+1)]=0;
|
||||
return make_sock(stype, newif, p, hints, v6only, noip6,
|
||||
rcv, snd, reuseport, transparent, tcp_mss, freebind, use_systemd);
|
||||
rcv, snd, reuseport, transparent, tcp_mss, nodelay,
|
||||
freebind, use_systemd);
|
||||
}
|
||||
return make_sock(stype, ifname, port, hints, v6only, noip6, rcv, snd,
|
||||
reuseport, transparent, tcp_mss, freebind, use_systemd);
|
||||
reuseport, transparent, tcp_mss, nodelay, freebind, use_systemd);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1125,6 +1160,18 @@ if_is_ssl(const char* ifname, const char* port, int ssl_port,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** see if interface is https, its port number == the https port number */
|
||||
static int
|
||||
if_is_https(const char* ifname, const char* port, int https_port)
|
||||
{
|
||||
char* p = strchr(ifname, '@');
|
||||
if(!p && atoi(port) == https_port)
|
||||
return 1;
|
||||
if(p && atoi(p+1) == https_port)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for ports_open. Creates one interface (or NULL for default).
|
||||
* @param ifname: The interface ip address.
|
||||
|
|
@ -1139,6 +1186,7 @@ if_is_ssl(const char* ifname, const char* port, int ssl_port,
|
|||
* @param snd: send buffer size for UDP
|
||||
* @param ssl_port: ssl service port number
|
||||
* @param tls_additional_port: list of additional ssl service port numbers.
|
||||
* @param https_port: DoH service port number
|
||||
* @param reuseport: try to set SO_REUSEPORT if nonNULL and true.
|
||||
* set to false on exit if reuseport failed due to no kernel support.
|
||||
* @param transparent: set IP_TRANSPARENT socket option.
|
||||
|
|
@ -1152,11 +1200,13 @@ static int
|
|||
ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
struct addrinfo *hints, const char* port, struct listen_port** list,
|
||||
size_t rcv, size_t snd, int ssl_port,
|
||||
struct config_strlist* tls_additional_port, int* reuseport,
|
||||
int transparent, int tcp_mss, int freebind, int use_systemd,
|
||||
int dnscrypt_port)
|
||||
struct config_strlist* tls_additional_port, int https_port,
|
||||
int* reuseport, int transparent, int tcp_mss, int freebind,
|
||||
int use_systemd, int dnscrypt_port)
|
||||
{
|
||||
int s, noip6=0;
|
||||
int is_https = if_is_https(ifname, port, https_port);
|
||||
int nodelay = is_https; /* TODO make config option */
|
||||
#ifdef USE_DNSCRYPT
|
||||
int is_dnscrypt = ((strchr(ifname, '@') &&
|
||||
atoi(strchr(ifname, '@')+1) == dnscrypt_port) ||
|
||||
|
|
@ -1171,7 +1221,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
|||
if(do_auto) {
|
||||
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
|
||||
&noip6, rcv, snd, reuseport, transparent,
|
||||
tcp_mss, freebind, use_systemd)) == -1) {
|
||||
tcp_mss, nodelay, freebind, use_systemd)) == -1) {
|
||||
if(noip6) {
|
||||
log_warn("IPv6 protocol not available");
|
||||
return 1;
|
||||
|
|
@ -1200,7 +1250,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
|||
/* regular udp socket */
|
||||
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
|
||||
&noip6, rcv, snd, reuseport, transparent,
|
||||
tcp_mss, freebind, use_systemd)) == -1) {
|
||||
tcp_mss, nodelay, freebind, use_systemd)) == -1) {
|
||||
if(noip6) {
|
||||
log_warn("IPv6 protocol not available");
|
||||
return 1;
|
||||
|
|
@ -1220,8 +1270,17 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
|||
if(do_tcp) {
|
||||
int is_ssl = if_is_ssl(ifname, port, ssl_port,
|
||||
tls_additional_port);
|
||||
enum listen_type port_type;
|
||||
if(is_ssl)
|
||||
port_type = listen_type_ssl;
|
||||
else if(is_https)
|
||||
port_type = listen_type_http;
|
||||
else if(is_dnscrypt)
|
||||
port_type = listen_type_tcp_dnscrypt;
|
||||
else
|
||||
port_type = listen_type_tcp;
|
||||
if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1,
|
||||
&noip6, 0, 0, reuseport, transparent, tcp_mss,
|
||||
&noip6, 0, 0, reuseport, transparent, tcp_mss, nodelay,
|
||||
freebind, use_systemd)) == -1) {
|
||||
if(noip6) {
|
||||
/*log_warn("IPv6 protocol not available");*/
|
||||
|
|
@ -1231,8 +1290,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
|||
}
|
||||
if(is_ssl)
|
||||
verbose(VERB_ALGO, "setup TCP for SSL service");
|
||||
if(!port_insert(list, s, is_ssl?listen_type_ssl:
|
||||
(is_dnscrypt?listen_type_tcp_dnscrypt:listen_type_tcp))) {
|
||||
if(!port_insert(list, s, port_type)) {
|
||||
#ifndef USE_WINSOCK
|
||||
close(s);
|
||||
#else
|
||||
|
|
@ -1266,7 +1324,7 @@ listen_cp_insert(struct comm_point* c, struct listen_dnsport* front)
|
|||
struct listen_dnsport*
|
||||
listen_create(struct comm_base* base, struct listen_port* ports,
|
||||
size_t bufsize, int tcp_accept_count, int tcp_idle_timeout,
|
||||
struct tcl_list* tcp_conn_limit, void* sslctx,
|
||||
int harden_large_queries, struct tcl_list* tcp_conn_limit, void* sslctx,
|
||||
struct dt_env* dtenv, comm_point_callback_type* cb, void *cb_arg)
|
||||
{
|
||||
struct listen_dnsport* front = (struct listen_dnsport*)
|
||||
|
|
@ -1298,14 +1356,35 @@ listen_create(struct comm_base* base, struct listen_port* ports,
|
|||
ports->ftype == listen_type_tcp_dnscrypt)
|
||||
cp = comm_point_create_tcp(base, ports->fd,
|
||||
tcp_accept_count, tcp_idle_timeout,
|
||||
harden_large_queries,
|
||||
tcp_conn_limit, bufsize, front->udp_buff,
|
||||
cb, cb_arg);
|
||||
else if(ports->ftype == listen_type_ssl) {
|
||||
ports->ftype, cb, cb_arg);
|
||||
else if(ports->ftype == listen_type_ssl ||
|
||||
ports->ftype == listen_type_http) {
|
||||
cp = comm_point_create_tcp(base, ports->fd,
|
||||
tcp_accept_count, tcp_idle_timeout,
|
||||
harden_large_queries,
|
||||
tcp_conn_limit, bufsize, front->udp_buff,
|
||||
cb, cb_arg);
|
||||
ports->ftype, cb, cb_arg);
|
||||
cp->ssl = sslctx;
|
||||
if(ports->ftype == listen_type_http) {
|
||||
if(!sslctx) {
|
||||
log_warn("HTTPS port configured, but no TLS "
|
||||
"tls-service-key or tls-service-pem "
|
||||
"set");
|
||||
}
|
||||
#ifndef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
||||
log_warn("Unbound is not compiled with an "
|
||||
"OpenSSL version supporting ALPN "
|
||||
" (OpenSSL >= 1.0.2). This is required "
|
||||
"to use DNS-over-HTTPS");
|
||||
#endif
|
||||
#ifndef HAVE_NGHTTP2_NGHTTP2_H
|
||||
log_warn("Unbound is not compiled with "
|
||||
"nghttp2. This is required to use "
|
||||
"DNS-over-HTTPS.");
|
||||
#endif
|
||||
}
|
||||
} else if(ports->ftype == listen_type_udpancil ||
|
||||
ports->ftype == listen_type_udpancil_dnscrypt)
|
||||
cp = comm_point_create_udp_ancil(base, ports->fd,
|
||||
|
|
@ -1419,6 +1498,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
|||
&hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, cfg->tls_additional_port,
|
||||
cfg->https_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
|
|
@ -1433,6 +1513,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
|||
&hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, cfg->tls_additional_port,
|
||||
cfg->https_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
|
|
@ -1449,6 +1530,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
|||
do_tcp, &hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, cfg->tls_additional_port,
|
||||
cfg->https_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
|
|
@ -1463,6 +1545,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
|||
do_tcp, &hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, cfg->tls_additional_port,
|
||||
cfg->https_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
|
|
@ -1906,3 +1989,624 @@ size_t tcp_req_info_get_stream_buffer_size(void)
|
|||
lock_basic_unlock(&stream_wait_count_lock);
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef HAVE_NGHTTP2
|
||||
/** nghttp2 callback. Used to copy response from rbuffer to nghttp2 session */
|
||||
static ssize_t http2_submit_response_read_callback(
|
||||
nghttp2_session* ATTR_UNUSED(session),
|
||||
int32_t stream_id, uint8_t* buf, size_t length, uint32_t* data_flags,
|
||||
nghttp2_data_source* source, void* ATTR_UNUSED(cb_arg))
|
||||
{
|
||||
struct http2_stream* h2_stream;
|
||||
struct http2_session* h2_session = source->ptr;
|
||||
size_t copylen = length;
|
||||
if(!(h2_stream = nghttp2_session_get_stream_user_data(
|
||||
h2_session->session, stream_id))) {
|
||||
verbose(VERB_QUERY, "http2: cannot get stream data, closing "
|
||||
"stream");
|
||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||
}
|
||||
if(!h2_stream->rbuffer ||
|
||||
sldns_buffer_remaining(h2_stream->rbuffer) == 0) {
|
||||
verbose(VERB_QUERY, "http2: cannot submit buffer. No data "
|
||||
"available in rbuffer");
|
||||
sldns_buffer_free(h2_stream->rbuffer);
|
||||
h2_stream->rbuffer = NULL;
|
||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
if(copylen > sldns_buffer_remaining(h2_stream->rbuffer))
|
||||
copylen = sldns_buffer_remaining(h2_stream->rbuffer);
|
||||
if(copylen > SSIZE_MAX)
|
||||
copylen = SSIZE_MAX; /* will probably never happen */
|
||||
|
||||
memcpy(buf, sldns_buffer_current(h2_stream->rbuffer), copylen);
|
||||
sldns_buffer_skip(h2_stream->rbuffer, copylen);
|
||||
|
||||
if(sldns_buffer_remaining(h2_stream->rbuffer) == 0) {
|
||||
*data_flags |= NGHTTP2_DATA_FLAG_EOF;
|
||||
sldns_buffer_free(h2_stream->rbuffer);
|
||||
h2_stream->rbuffer = NULL;
|
||||
}
|
||||
|
||||
return copylen;
|
||||
}
|
||||
|
||||
/**
|
||||
* DNS response ready to be submitted to nghttp2, to be prepared for sending
|
||||
* out. Response is stored in c->buffer. Copy to rbuffer because the c->buffer
|
||||
* might be used before this will bne send out.
|
||||
* @param h2_session: http2 session, containing c->buffer which contains answer
|
||||
* @return 0 on error, 1 otherwise
|
||||
*/
|
||||
int http2_submit_dns_response(struct http2_session* h2_session)
|
||||
{
|
||||
int ret;
|
||||
nghttp2_data_provider data_prd;
|
||||
char status[4];
|
||||
nghttp2_nv headers[2];
|
||||
struct http2_stream* h2_stream = h2_session->c->h2_stream;
|
||||
|
||||
if(h2_stream->rbuffer) {
|
||||
log_err("http2 submit response error: rbuffer already "
|
||||
"exists");
|
||||
return 0;
|
||||
}
|
||||
if(sldns_buffer_remaining(h2_session->c->buffer) == 0) {
|
||||
log_err("http2 submit response error: c->buffer not complete");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!(h2_stream->rbuffer = sldns_buffer_new(
|
||||
sldns_buffer_remaining(h2_session->c->buffer)))) {
|
||||
log_err("http2 submit response error: malloc failure");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(snprintf(status, 4, "%d", h2_stream->status) != 3) {
|
||||
verbose(VERB_QUERY, "http2: submit response error: "
|
||||
"invalid status");
|
||||
return 0;
|
||||
}
|
||||
headers[0].name = (uint8_t*)":status";
|
||||
headers[0].namelen = 7;
|
||||
headers[0].value = (uint8_t*)status;
|
||||
headers[0].valuelen = 3;
|
||||
headers[0].flags = NGHTTP2_NV_FLAG_NONE;
|
||||
|
||||
headers[1].name = (uint8_t*)"content-type";
|
||||
headers[1].namelen = 12;
|
||||
headers[1].value = (uint8_t*)"application/dns-message";
|
||||
headers[1].valuelen = 23;
|
||||
headers[1].flags = NGHTTP2_NV_FLAG_NONE;
|
||||
|
||||
/*TODO be nice and add the content-length header
|
||||
headers[2].name = (uint8_t*)"content-length";
|
||||
headers[2].namelen = 14;
|
||||
headers[2].value =
|
||||
headers[2].valuelen =
|
||||
headers[2].flags = NGHTTP2_NV_FLAG_NONE;
|
||||
*/
|
||||
|
||||
sldns_buffer_write(h2_stream->rbuffer,
|
||||
sldns_buffer_current(h2_session->c->buffer),
|
||||
sldns_buffer_remaining(h2_stream->rbuffer));
|
||||
sldns_buffer_flip(h2_stream->rbuffer);
|
||||
|
||||
data_prd.source.ptr = h2_session;
|
||||
data_prd.read_callback = http2_submit_response_read_callback;
|
||||
ret = nghttp2_submit_response(h2_session->session, h2_stream->stream_id,
|
||||
headers, 2, &data_prd);
|
||||
if(ret) {
|
||||
verbose(VERB_QUERY, "http2: set_stream_user_data failed, "
|
||||
"error: %s", nghttp2_strerror(ret));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
int http2_submit_dns_response(void* ATTR_UNUSED(v))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NGHTTP2
|
||||
/** HTTP status to descriptive string */
|
||||
static char* http_status_to_str(enum http_status s)
|
||||
{
|
||||
switch(s) {
|
||||
case HTTP_STATUS_OK:
|
||||
return "OK";
|
||||
case HTTP_STATUS_BAD_REQUEST:
|
||||
return "Bad Request";
|
||||
case HTTP_STATUS_NOT_FOUND:
|
||||
return "Not Found";
|
||||
case HTTP_STATUS_PAYLOAD_TOO_LARGE:
|
||||
return "Payload Too Large";
|
||||
case HTTP_STATUS_URI_TOO_LONG:
|
||||
return "URI Too Long";
|
||||
case HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE:
|
||||
return "Unsupported Media Type";
|
||||
case HTTP_STATUS_NOT_IMPLEMENTED:
|
||||
return "Not Implemented";
|
||||
}
|
||||
return "Status Unknown";
|
||||
}
|
||||
|
||||
/** nghttp2 callback. Used to copy error message to nghttp2 session */
|
||||
static ssize_t http2_submit_error_read_callback(
|
||||
nghttp2_session* ATTR_UNUSED(session),
|
||||
int32_t stream_id, uint8_t* buf, size_t length, uint32_t* data_flags,
|
||||
nghttp2_data_source* source, void* ATTR_UNUSED(cb_arg))
|
||||
{
|
||||
struct http2_stream* h2_stream;
|
||||
struct http2_session* h2_session = source->ptr;
|
||||
char* msg;
|
||||
if(!(h2_stream = nghttp2_session_get_stream_user_data(
|
||||
h2_session->session, stream_id))) {
|
||||
verbose(VERB_QUERY, "http2: cannot get stream data, closing "
|
||||
"stream");
|
||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||
}
|
||||
*data_flags |= NGHTTP2_DATA_FLAG_EOF;
|
||||
msg = http_status_to_str(h2_stream->status);
|
||||
if(length < strlen(msg))
|
||||
return 0; /* not worth trying over multiple frames */
|
||||
memcpy(buf, msg, strlen(msg));
|
||||
return strlen(msg);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP error response ready to be submitted to nghttp2, to be prepared for
|
||||
* sending out. Message body will contain descriptive string for HTTP status.
|
||||
* @param h2_session: http2 session to submit to
|
||||
* @param h2_stream: http2 stream containing HTTP status to use for error
|
||||
* @return 0 on error, 1 otherwise
|
||||
*/
|
||||
static int http2_submit_error(struct http2_session* h2_session,
|
||||
struct http2_stream* h2_stream)
|
||||
{
|
||||
int ret;
|
||||
char status[4];
|
||||
nghttp2_data_provider data_prd;
|
||||
nghttp2_nv headers[1]; /* will be copied by nghttp */
|
||||
if(snprintf(status, 4, "%d", h2_stream->status) != 3) {
|
||||
verbose(VERB_QUERY, "http2: submit error failed, "
|
||||
"invalid status");
|
||||
return 0;
|
||||
}
|
||||
headers[0].name = (uint8_t*)":status";
|
||||
headers[0].namelen = 7;
|
||||
headers[0].value = (uint8_t*)status;
|
||||
headers[0].valuelen = 3;
|
||||
headers[0].flags = NGHTTP2_NV_FLAG_NONE;
|
||||
|
||||
data_prd.source.ptr = h2_session;
|
||||
data_prd.read_callback = http2_submit_error_read_callback;
|
||||
|
||||
ret = nghttp2_submit_response(h2_session->session, h2_stream->stream_id,
|
||||
headers, 1, &data_prd);
|
||||
if(ret) {
|
||||
verbose(VERB_QUERY, "http2: submit error failed, "
|
||||
"error: %s", nghttp2_strerror(ret));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start query handling. Query is stored in the stream, and will be free'd here.
|
||||
* @param h2_session: http2 session, containing comm point
|
||||
* @param h2_stream: stream containing buffered query
|
||||
* @return: -1 on error, 1 if answer is stored in c->buffer, 0 if there is no
|
||||
* reply available (yet).
|
||||
*/
|
||||
static int http2_query_read_done(struct http2_session* h2_session,
|
||||
struct http2_stream* h2_stream)
|
||||
{
|
||||
log_assert(h2_stream->qbuffer);
|
||||
|
||||
if(h2_session->c->h2_stream) {
|
||||
verbose(VERB_ALGO, "http2_query_read_done failure: shared "
|
||||
"buffer already assigned to stream");
|
||||
return -1;
|
||||
}
|
||||
if(sldns_buffer_remaining(h2_session->c->buffer) <
|
||||
sldns_buffer_remaining(h2_stream->qbuffer)) {
|
||||
sldns_buffer_free(h2_stream->qbuffer);
|
||||
h2_stream->qbuffer = NULL;
|
||||
sldns_buffer_clear(h2_session->c->buffer);
|
||||
verbose(VERB_ALGO, "http2_query_read_done failure: can't fit "
|
||||
"qbuffer in c->buffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sldns_buffer_write(h2_session->c->buffer,
|
||||
sldns_buffer_current(h2_stream->qbuffer),
|
||||
sldns_buffer_remaining(h2_stream->qbuffer));
|
||||
|
||||
sldns_buffer_free(h2_stream->qbuffer);
|
||||
h2_stream->qbuffer = NULL;
|
||||
|
||||
sldns_buffer_flip(h2_session->c->buffer);
|
||||
h2_session->c->h2_stream = h2_stream;
|
||||
fptr_ok(fptr_whitelist_comm_point(h2_session->c->callback));
|
||||
if((*h2_session->c->callback)(h2_session->c, h2_session->c->cb_arg,
|
||||
NETEVENT_NOERROR, &h2_session->c->repinfo)) {
|
||||
return 1; /* answer in c->buffer */
|
||||
}
|
||||
sldns_buffer_clear(h2_session->c->buffer);
|
||||
h2_session->c->h2_stream = NULL;
|
||||
return 0; /* mesh state added, or dropped */
|
||||
}
|
||||
|
||||
/** nghttp2 callback. Used to check if the received frame indicates the end of a
|
||||
* stream. Gather collected request data and start query handling. */
|
||||
static int http2_req_frame_recv_cb(nghttp2_session* session,
|
||||
const nghttp2_frame* frame, void* cb_arg)
|
||||
{
|
||||
struct http2_session* h2_session = (struct http2_session*)cb_arg;
|
||||
struct http2_stream* h2_stream;
|
||||
int query_read_done;
|
||||
|
||||
if((frame->hd.type != NGHTTP2_DATA &&
|
||||
frame->hd.type != NGHTTP2_HEADERS) ||
|
||||
!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!(h2_stream = nghttp2_session_get_stream_user_data(
|
||||
session, frame->hd.stream_id)))
|
||||
return 0;
|
||||
|
||||
if(h2_stream->invalid_endpoint) {
|
||||
h2_stream->status = HTTP_STATUS_NOT_FOUND;
|
||||
goto submit_http_error;
|
||||
}
|
||||
|
||||
if(h2_stream->invalid_content_type) {
|
||||
h2_stream->status = HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE;
|
||||
goto submit_http_error;
|
||||
}
|
||||
|
||||
if(h2_stream->http_method != HTTP_METHOD_GET &&
|
||||
h2_stream->http_method != HTTP_METHOD_POST) {
|
||||
h2_stream->status = HTTP_STATUS_NOT_IMPLEMENTED;
|
||||
goto submit_http_error;
|
||||
}
|
||||
|
||||
if(h2_stream->query_too_large) {
|
||||
if(h2_stream->http_method == HTTP_METHOD_POST)
|
||||
h2_stream->status = HTTP_STATUS_PAYLOAD_TOO_LARGE;
|
||||
else
|
||||
h2_stream->status = HTTP_STATUS_URI_TOO_LONG;
|
||||
goto submit_http_error;
|
||||
}
|
||||
|
||||
if(!h2_stream->qbuffer) {
|
||||
h2_stream->status = HTTP_STATUS_BAD_REQUEST;
|
||||
goto submit_http_error;
|
||||
}
|
||||
|
||||
if(h2_stream->status) {
|
||||
submit_http_error:
|
||||
verbose(VERB_QUERY, "http2 request invalid, returning :status="
|
||||
"%d", h2_stream->status);
|
||||
if(!http2_submit_error(h2_session, h2_stream)) {
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
h2_stream->status = HTTP_STATUS_OK;
|
||||
|
||||
sldns_buffer_flip(h2_stream->qbuffer);
|
||||
h2_session->postpone_drop = 1;
|
||||
query_read_done = http2_query_read_done(h2_session, h2_stream);
|
||||
if(query_read_done < 0)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
else if(!query_read_done) {
|
||||
if(h2_session->is_drop) {
|
||||
/* connection needs to be closed. Return failure to make
|
||||
* sure no other action are taken anymore on comm point.
|
||||
* failure will result in reclaiming (and closing)
|
||||
* of comm point. */
|
||||
verbose(VERB_QUERY, "http2 query dropped in worker cb");
|
||||
h2_session->postpone_drop = 0;
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
/* nothing to submit right now, query added to mesh. */
|
||||
h2_session->postpone_drop = 0;
|
||||
return 0;
|
||||
}
|
||||
if(!http2_submit_dns_response(h2_session)) {
|
||||
sldns_buffer_clear(h2_session->c->buffer);
|
||||
h2_session->c->h2_stream = NULL;
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
verbose(VERB_QUERY, "http2 query submitted to session");
|
||||
sldns_buffer_clear(h2_session->c->buffer);
|
||||
h2_session->c->h2_stream = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** nghttp2 callback. Used to detect start of new streams. */
|
||||
static int http2_req_begin_headers_cb(nghttp2_session* session,
|
||||
const nghttp2_frame* frame, void* cb_arg)
|
||||
{
|
||||
struct http2_session* h2_session = (struct http2_session*)cb_arg;
|
||||
struct http2_stream* h2_stream;
|
||||
int ret;
|
||||
if(frame->hd.type != NGHTTP2_HEADERS ||
|
||||
frame->headers.cat != NGHTTP2_HCAT_REQUEST) {
|
||||
/* only interrested in request headers */
|
||||
return 0;
|
||||
}
|
||||
if(!(h2_stream = http2_stream_create(frame->hd.stream_id))) {
|
||||
log_err("malloc failure while creating http2 stream");
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
http2_session_add_stream(h2_session, h2_stream);
|
||||
ret = nghttp2_session_set_stream_user_data(session,
|
||||
frame->hd.stream_id, h2_stream);
|
||||
if(ret) {
|
||||
/* stream does not exist */
|
||||
verbose(VERB_QUERY, "http2: set_stream_user_data failed, "
|
||||
"error: %s", nghttp2_strerror(ret));
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* base64url decode, store in qbuffer
|
||||
* @param h2_session: http2 session
|
||||
* @param h2_stream: http2 stream
|
||||
* @param start: start of the base64 string
|
||||
* @param length: length of the base64 string
|
||||
* @return: 0 on error, 1 otherwise. query will be stored in h2_stram->qbuffer,
|
||||
* buffer will be NULL is unparseble.
|
||||
*/
|
||||
static int http2_buffer_uri_query(struct http2_session* h2_session,
|
||||
struct http2_stream* h2_stream, const uint8_t* start, size_t length)
|
||||
{
|
||||
size_t expectb64len;
|
||||
int b64len;
|
||||
if(h2_stream->http_method == HTTP_METHOD_POST)
|
||||
return 1;
|
||||
if(length == 0)
|
||||
return 1;
|
||||
if(h2_stream->qbuffer) {
|
||||
verbose(VERB_ALGO, "http2_req_header fail, "
|
||||
"qbuffer already set");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* calculate size, might be a bit bigger than the real
|
||||
* decoded buffer size */
|
||||
expectb64len = sldns_b64_pton_calculate_size(length);
|
||||
log_assert(expectb64len > 0);
|
||||
if(expectb64len >
|
||||
h2_session->c->http2_max_qbuffer_size) {
|
||||
h2_stream->query_too_large = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!(h2_stream->qbuffer = sldns_buffer_new(expectb64len))) {
|
||||
log_err("http2_req_header fail, qbuffer "
|
||||
"malloc failure");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!(b64len = sldns_b64url_pton(
|
||||
(char const *)start, length,
|
||||
sldns_buffer_current(h2_stream->qbuffer),
|
||||
expectb64len)) || b64len < 0) {
|
||||
sldns_buffer_free(h2_stream->qbuffer);
|
||||
h2_stream->qbuffer = NULL;
|
||||
/* return without error, method can be an
|
||||
* unknown POST */
|
||||
return 1;
|
||||
}
|
||||
sldns_buffer_skip(h2_stream->qbuffer, (size_t)b64len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** nghttp2 callback. Used to parse headers from HEADER frames. */
|
||||
static int http2_req_header_cb(nghttp2_session* session,
|
||||
const nghttp2_frame* frame, const uint8_t* name, size_t namelen,
|
||||
const uint8_t* value, size_t valuelen, uint8_t ATTR_UNUSED(flags),
|
||||
void* cb_arg)
|
||||
{
|
||||
struct http2_stream* h2_stream = NULL;
|
||||
struct http2_session* h2_session = (struct http2_session*)cb_arg;
|
||||
/* nghttp2 deals with CONTINUATION frames and provides them as part of
|
||||
* the HEADER */
|
||||
if(frame->hd.type != NGHTTP2_HEADERS ||
|
||||
frame->headers.cat != NGHTTP2_HCAT_REQUEST) {
|
||||
/* only interrested in request headers */
|
||||
return 0;
|
||||
}
|
||||
if(!(h2_stream = nghttp2_session_get_stream_user_data(session,
|
||||
frame->hd.stream_id)))
|
||||
return 0;
|
||||
|
||||
/* earlier checks already indicate we can stop handling this query */
|
||||
if(h2_stream->http_method == HTTP_METHOD_UNSUPPORTED ||
|
||||
h2_stream->invalid_content_type ||
|
||||
h2_stream->invalid_endpoint)
|
||||
return 0;
|
||||
|
||||
|
||||
/* nghttp2 performs some sanity checks in the headers, including:
|
||||
* name and value are guaranteed to be null terminated
|
||||
* name is guaranteed to be lowercase
|
||||
* content-length value is guaranteed to contain digits
|
||||
*/
|
||||
|
||||
if(!h2_stream->http_method && namelen == 7 &&
|
||||
memcmp(":method", name, namelen) == 0) {
|
||||
/* Case insensitive check on :method value to be on the safe
|
||||
* side. I failed to find text about case sentitivity in specs.
|
||||
*/
|
||||
if(valuelen == 3 && strcasecmp("GET", (const char*)value) == 0)
|
||||
h2_stream->http_method = HTTP_METHOD_GET;
|
||||
else if(valuelen == 4 &&
|
||||
strcasecmp("POST", (const char*)value) == 0) {
|
||||
h2_stream->http_method = HTTP_METHOD_POST;
|
||||
if(h2_stream->qbuffer) {
|
||||
/* POST method uses query from DATA frames */
|
||||
sldns_buffer_free(h2_stream->qbuffer);
|
||||
h2_stream->qbuffer = NULL;
|
||||
}
|
||||
} else
|
||||
h2_stream->http_method = HTTP_METHOD_UNSUPPORTED;
|
||||
return 0;
|
||||
}
|
||||
if(namelen == 5 && memcmp(":path", name, namelen) == 0) {
|
||||
/* Hard coded /dns-query endpoint, might be nice to make
|
||||
* configurable.
|
||||
* :path may contain DNS query, depending on method. Method might
|
||||
* not be known yet here, so check after finishing receiving
|
||||
* stream. */
|
||||
#define HTTP_ENDPOINT "/dns-query"
|
||||
#define HTTP_QUERY_PARAM "?dns="
|
||||
size_t el = sizeof(HTTP_ENDPOINT) - 1;
|
||||
size_t qpl = sizeof(HTTP_QUERY_PARAM) - 1;
|
||||
|
||||
if(valuelen < el || memcmp(HTTP_ENDPOINT, value, el) != 0) {
|
||||
h2_stream->invalid_endpoint = 1;
|
||||
return 0;
|
||||
}
|
||||
/* larger than endpoint only allowed if it is for the query
|
||||
* parameter */
|
||||
if(valuelen <= el+qpl ||
|
||||
memcmp(HTTP_QUERY_PARAM, value+el, qpl) != 0) {
|
||||
if(valuelen != el)
|
||||
h2_stream->invalid_endpoint = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!http2_buffer_uri_query(h2_session, h2_stream,
|
||||
value+(el+qpl), valuelen-(el+qpl))) {
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* Content type is a SHOULD (rfc7231#section-3.1.1.5) when using POST,
|
||||
* and not needed when using GET. Don't enfore.
|
||||
* If set only allow lowercase "application/dns-message".
|
||||
*
|
||||
* Clients SHOULD (rfc8484#section-4.1) set an accept header, but MUST
|
||||
* be able to handle "application/dns-message". Since that is the only
|
||||
* content-type supported we can ignore the accept header.
|
||||
*/
|
||||
if((namelen == 12 && memcmp("content-type", name, namelen) == 0)) {
|
||||
if(valuelen != 23 || memcmp("application/dns-message", value,
|
||||
valuelen) != 0) {
|
||||
h2_stream->invalid_content_type = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Only interested in content-lentg for POST (on not yet known) method.
|
||||
*/
|
||||
if((!h2_stream->http_method ||
|
||||
h2_stream->http_method == HTTP_METHOD_POST) &&
|
||||
!h2_stream->content_length && namelen == 14 &&
|
||||
memcmp("content-length", name, namelen) == 0) {
|
||||
if(valuelen > 5) {
|
||||
h2_stream->query_too_large = 1;
|
||||
return 0;
|
||||
}
|
||||
/* guaranteed to only contian digits and be null terminated */
|
||||
h2_stream->content_length = atoi((const char*)value);
|
||||
if(h2_stream->content_length >
|
||||
h2_session->c->http2_max_qbuffer_size) {
|
||||
h2_stream->query_too_large = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** nghttp2 callback. Used to get data from DATA frames, which can contain
|
||||
* queries in POST requests. */
|
||||
static int http2_req_data_chunk_recv_cb(nghttp2_session* ATTR_UNUSED(session),
|
||||
uint8_t ATTR_UNUSED(flags), int32_t stream_id, const uint8_t* data,
|
||||
size_t len, void* cb_arg)
|
||||
{
|
||||
struct http2_session* h2_session = (struct http2_session*)cb_arg;
|
||||
struct http2_stream* h2_stream;
|
||||
|
||||
if(!(h2_stream = nghttp2_session_get_stream_user_data(
|
||||
h2_session->session, stream_id))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(h2_stream->query_too_large)
|
||||
return 0;
|
||||
|
||||
if(!h2_stream->qbuffer) {
|
||||
if(h2_stream->content_length) {
|
||||
if(h2_stream->content_length < len)
|
||||
/* getting more data in DATA frame than
|
||||
* advertised in content-length header. */
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
h2_stream->qbuffer = sldns_buffer_new(
|
||||
h2_stream->content_length);
|
||||
} else if(len <= h2_session->c->http2_max_qbuffer_size) {
|
||||
/* setting this to msg-buffer-size can result in a lot
|
||||
* of memory consuption. Most queries should fit in a
|
||||
* single DATA frame, and most POST queries will
|
||||
* containt content-length which does not impose this
|
||||
* limit. */
|
||||
h2_stream->qbuffer = sldns_buffer_new(len);
|
||||
}
|
||||
}
|
||||
|
||||
if(!h2_stream->qbuffer ||
|
||||
sldns_buffer_remaining(h2_stream->qbuffer) < len) {
|
||||
verbose(VERB_ALGO, "http2 data_chunck_recv failed. Not enough "
|
||||
"buffer space for POST query. Can happen on multi "
|
||||
"frame requests without content-length header");
|
||||
h2_stream->query_too_large = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sldns_buffer_write(h2_stream->qbuffer, data, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
nghttp2_session_callbacks* http2_req_callbacks_create()
|
||||
{
|
||||
nghttp2_session_callbacks *callbacks;
|
||||
if(nghttp2_session_callbacks_new(&callbacks) == NGHTTP2_ERR_NOMEM) {
|
||||
log_err("failed to initialize nghttp2 callback");
|
||||
return NULL;
|
||||
}
|
||||
/* reception of header block started, used to create h2_stream */
|
||||
nghttp2_session_callbacks_set_on_begin_headers_callback(callbacks,
|
||||
http2_req_begin_headers_cb);
|
||||
/* complete frame received, used to get data from stream if frame
|
||||
* has end stream flag, and start processing query */
|
||||
nghttp2_session_callbacks_set_on_frame_recv_callback(callbacks,
|
||||
http2_req_frame_recv_cb);
|
||||
/* get request info from headers */
|
||||
nghttp2_session_callbacks_set_on_header_callback(callbacks,
|
||||
http2_req_header_cb);
|
||||
/* get data from DATA frames, containing POST query */
|
||||
nghttp2_session_callbacks_set_on_data_chunk_recv_callback(callbacks,
|
||||
http2_req_data_chunk_recv_cb);
|
||||
|
||||
/* generic HTTP2 callbacks */
|
||||
nghttp2_session_callbacks_set_recv_callback(callbacks, http2_recv_cb);
|
||||
nghttp2_session_callbacks_set_send_callback(callbacks, http2_send_cb);
|
||||
nghttp2_session_callbacks_set_on_stream_close_callback(callbacks,
|
||||
http2_stream_close_cb);
|
||||
|
||||
return callbacks;
|
||||
}
|
||||
#endif /* HAVE_NGHTTP2 */
|
||||
|
|
|
|||
|
|
@ -43,6 +43,9 @@
|
|||
#define LISTEN_DNSPORT_H
|
||||
|
||||
#include "util/netevent.h"
|
||||
#ifdef HAVE_NGHTTP2_NGHTTP2_H
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#endif
|
||||
struct listen_list;
|
||||
struct config_file;
|
||||
struct addrinfo;
|
||||
|
|
@ -94,8 +97,9 @@ enum listen_type {
|
|||
/** tcp type + dnscrypt */
|
||||
listen_type_tcp_dnscrypt,
|
||||
/** udp ipv6 (v4mapped) for use with ancillary data + dnscrypt*/
|
||||
listen_type_udpancil_dnscrypt
|
||||
|
||||
listen_type_udpancil_dnscrypt,
|
||||
/** HTTP(2) over TLS over TCP */
|
||||
listen_type_http
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -139,6 +143,7 @@ void listening_ports_free(struct listen_port* list);
|
|||
* @param tcp_accept_count: max number of simultaneous TCP connections
|
||||
* from clients.
|
||||
* @param tcp_idle_timeout: idle timeout for TCP connections in msec.
|
||||
* @param harden_large_queries: whether query size should be limited.
|
||||
* @param tcp_conn_limit: TCP connection limit info.
|
||||
* @param sslctx: nonNULL if ssl context.
|
||||
* @param dtenv: nonNULL if dnstap enabled.
|
||||
|
|
@ -149,7 +154,7 @@ void listening_ports_free(struct listen_port* list);
|
|||
*/
|
||||
struct listen_dnsport* listen_create(struct comm_base* base,
|
||||
struct listen_port* ports, size_t bufsize,
|
||||
int tcp_accept_count, int tcp_idle_timeout,
|
||||
int tcp_accept_count, int tcp_idle_timeout, int harden_large_queries,
|
||||
struct tcl_list* tcp_conn_limit, void* sslctx,
|
||||
struct dt_env *dtenv, comm_point_callback_type* cb, void* cb_arg);
|
||||
|
||||
|
|
@ -220,12 +225,14 @@ int create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
|||
* listening UDP port. Set to false on return if it failed to do so.
|
||||
* @param transparent: set IP_TRANSPARENT socket option.
|
||||
* @param mss: maximum segment size of the socket. if zero, leaves the default.
|
||||
* @param nodelay: if true set TCP_NODELAY and TCP_QUICKACK socket options.
|
||||
* @param freebind: set IP_FREEBIND socket option.
|
||||
* @param use_systemd: if true, fetch sockets from systemd.
|
||||
* @return: the socket. -1 on error.
|
||||
*/
|
||||
int create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||
int* reuseport, int transparent, int mss, int freebind, int use_systemd);
|
||||
int* reuseport, int transparent, int mss, int nodelay, int freebind,
|
||||
int use_systemd);
|
||||
|
||||
/**
|
||||
* Create and bind local listening socket
|
||||
|
|
@ -367,4 +374,24 @@ int tcp_req_info_handle_read_close(struct tcp_req_info* req);
|
|||
/** get the size of currently used tcp stream wait buffers (in bytes) */
|
||||
size_t tcp_req_info_get_stream_buffer_size(void);
|
||||
|
||||
#ifdef HAVE_NGHTTP2
|
||||
/**
|
||||
* Create nghttp2 callbacks to handle HTTP2 requests.
|
||||
* @return malloc'ed struct, NULL on failure
|
||||
*/
|
||||
nghttp2_session_callbacks* http2_req_callbacks_create();
|
||||
|
||||
/**
|
||||
* DNS response ready to be submitted to nghttp2, to be prepared for sending
|
||||
* out. Response is stored in c->buffer. Copy to rbuffer because the c->buffer
|
||||
* might be used before this will be send out.
|
||||
* @param h2_session: http2 session, containing c->buffer which contains answer
|
||||
* @param h2_stream: http2 stream, containing buffer to store answer in
|
||||
* @return 0 on error, 1 otherwise
|
||||
*/
|
||||
int http2_submit_dns_response(struct http2_session* h2_session);
|
||||
#else
|
||||
int http2_submit_dns_response(void* v);
|
||||
#endif /* HAVE_NGHTTP2 */
|
||||
|
||||
#endif /* LISTEN_DNSPORT_H */
|
||||
|
|
|
|||
|
|
@ -551,6 +551,9 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
|||
goto servfail_mem;
|
||||
}
|
||||
}
|
||||
if(rep->c->alpn_h2) {
|
||||
http2_stream_add_meshstate(rep->c->h2_stream, mesh, s);
|
||||
}
|
||||
/* add serve expired timer if required and not already there */
|
||||
if(timeout && !mesh_serve_expired_init(s, timeout)) {
|
||||
log_err("mesh_new_client: out of memory initializing serve expired");
|
||||
|
|
@ -1207,6 +1210,9 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
|||
else secure = 0;
|
||||
if(!rep && rcode == LDNS_RCODE_NOERROR)
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
if(r->query_reply.c->alpn_h2) {
|
||||
r->query_reply.c->h2_stream = r->h2_stream;
|
||||
}
|
||||
/* send the reply */
|
||||
/* We don't reuse the encoded answer if either the previous or current
|
||||
* response has a local alias. We could compare the alias records
|
||||
|
|
@ -1488,6 +1494,8 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
|
|||
s->s.qinfo.qname_len);
|
||||
if(!r->qname)
|
||||
return 0;
|
||||
if(rep->c->alpn_h2)
|
||||
r->h2_stream = rep->c->h2_stream;
|
||||
|
||||
/* Data related to local alias stored in 'qinfo' (if any) is ephemeral
|
||||
* and can be different for different original queries (even if the
|
||||
|
|
|
|||
|
|
@ -230,6 +230,8 @@ struct mesh_reply {
|
|||
uint8_t* qname;
|
||||
/** same as that in query_info. */
|
||||
struct local_rrset* local_alias;
|
||||
/** send query to this http2 stream, if set */
|
||||
struct http2_stream* h2_stream;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -674,14 +674,17 @@ size_t sldns_b64_pton_calculate_size(size_t srcsize)
|
|||
return (((((srcsize + 3) / 4) * 3)) + 1);
|
||||
}
|
||||
|
||||
int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
|
||||
/* padding not required if srcsize is set */
|
||||
static int sldns_b64_pton_base(char const *src, size_t srcsize, uint8_t *target,
|
||||
size_t targsize, int base64url)
|
||||
{
|
||||
const uint8_t pad64 = 64; /* is 64th in the b64 array */
|
||||
const char* s = src;
|
||||
uint8_t in[4];
|
||||
size_t o = 0, incount = 0;
|
||||
int check_padding = (srcsize) ? 0 : 1;
|
||||
|
||||
while(*s) {
|
||||
while(*s && (check_padding || srcsize)) {
|
||||
/* skip any character that is not base64 */
|
||||
/* conceptually we do:
|
||||
const char* b64 = pad'=' is appended to array
|
||||
|
|
@ -690,30 +693,40 @@ int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
|
|||
and use d-b64;
|
||||
*/
|
||||
char d = *s++;
|
||||
srcsize--;
|
||||
if(d <= 'Z' && d >= 'A')
|
||||
d -= 'A';
|
||||
else if(d <= 'z' && d >= 'a')
|
||||
d = d - 'a' + 26;
|
||||
else if(d <= '9' && d >= '0')
|
||||
d = d - '0' + 52;
|
||||
else if(d == '+')
|
||||
else if(!base64url && d == '+')
|
||||
d = 62;
|
||||
else if(d == '/')
|
||||
else if(base64url && d == '-')
|
||||
d = 62;
|
||||
else if(!base64url && d == '/')
|
||||
d = 63;
|
||||
else if(d == '=')
|
||||
else if(base64url && d == '_')
|
||||
d = 63;
|
||||
else if(!base64url && d == '=')
|
||||
d = 64;
|
||||
else continue;
|
||||
in[incount++] = (uint8_t)d;
|
||||
if(incount != 4)
|
||||
/* work on block of 4, unless padding is not used and there are
|
||||
* less than 4 chars left */
|
||||
if(incount != 4 && (check_padding || srcsize))
|
||||
continue;
|
||||
assert(!check_padding || incount==4);
|
||||
/* process whole block of 4 characters into 3 output bytes */
|
||||
if(in[3] == pad64 && in[2] == pad64) { /* A B = = */
|
||||
if((incount == 2 ||
|
||||
(incount == 4 && in[3] == pad64 && in[2] == pad64))) { /* A B = = */
|
||||
if(o+1 > targsize)
|
||||
return -1;
|
||||
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
|
||||
o += 1;
|
||||
break; /* we are done */
|
||||
} else if(in[3] == pad64) { /* A B C = */
|
||||
} else if(incount == 3 ||
|
||||
(incount == 4 && in[3] == pad64)) { /* A B C = */
|
||||
if(o+2 > targsize)
|
||||
return -1;
|
||||
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
|
||||
|
|
@ -721,7 +734,7 @@ int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
|
|||
o += 2;
|
||||
break; /* we are done */
|
||||
} else {
|
||||
if(o+3 > targsize)
|
||||
if(incount != 4 || o+3 > targsize)
|
||||
return -1;
|
||||
/* write xxxxxxyy yyyyzzzz zzwwwwww */
|
||||
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
|
||||
|
|
@ -733,3 +746,17 @@ int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
|
|||
}
|
||||
return (int)o;
|
||||
}
|
||||
|
||||
int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
|
||||
{
|
||||
return sldns_b64_pton_base(src, 0, target, targsize, 0);
|
||||
}
|
||||
|
||||
int sldns_b64url_pton(char const *src, size_t srcsize, uint8_t *target,
|
||||
size_t targsize)
|
||||
{
|
||||
if(!srcsize) {
|
||||
return 0;
|
||||
}
|
||||
return sldns_b64_pton_base(src, srcsize, target, targsize, 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,8 +97,9 @@ int sldns_b64_ntop(uint8_t const *src, size_t srclength,
|
|||
* calculates the size needed to store the result of sldns_b64_pton
|
||||
*/
|
||||
size_t sldns_b64_pton_calculate_size(size_t srcsize);
|
||||
|
||||
int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize);
|
||||
int sldns_b64url_pton(char const *src, size_t srcsize, uint8_t *target,
|
||||
size_t targsize);
|
||||
|
||||
/**
|
||||
* calculates the size needed to store the result of b32_ntop
|
||||
|
|
|
|||
|
|
@ -868,6 +868,7 @@ struct listen_dnsport*
|
|||
listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports),
|
||||
size_t bufsize, int ATTR_UNUSED(tcp_accept_count),
|
||||
int ATTR_UNUSED(tcp_idle_timeout),
|
||||
int ATTR_UNUSED(harden_large_queries),
|
||||
struct tcl_list* ATTR_UNUSED(tcp_conn_limit),
|
||||
void* ATTR_UNUSED(sslctx), struct dt_env* ATTR_UNUSED(dtenv),
|
||||
comm_point_callback_type* cb, void* cb_arg)
|
||||
|
|
@ -1823,4 +1824,9 @@ tcp_req_info_get_stream_buffer_size(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void http2_stream_add_meshstate(struct http2_stream* ATTR_UNUSED(h2_stream),
|
||||
struct mesh_area* ATTR_UNUSED(mesh), struct mesh_state* ATTR_UNUSED(m))
|
||||
{
|
||||
}
|
||||
|
||||
/*********** End of Dummy routines ***********/
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ config_create(void)
|
|||
cfg->ssl_upstream = 0;
|
||||
cfg->tls_cert_bundle = NULL;
|
||||
cfg->tls_win_cert = 0;
|
||||
cfg->https_port = UNBOUND_DNS_OVER_HTTPS_PORT;
|
||||
cfg->use_syslog = 1;
|
||||
cfg->log_identity = NULL; /* changed later with argv[0] */
|
||||
cfg->log_time_ascii = 0;
|
||||
|
|
@ -505,6 +506,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
|||
else S_STRLIST_APPEND("tls-session-ticket-keys:", tls_session_ticket_keys)
|
||||
else S_STR("tls-ciphers:", tls_ciphers)
|
||||
else S_STR("tls-ciphersuites:", tls_ciphersuites)
|
||||
else S_NUMBER_NONZERO("https-port:", https_port)
|
||||
else S_YNO("interface-automatic:", if_automatic)
|
||||
else S_YNO("use-systemd:", use_systemd)
|
||||
else S_YNO("do-daemonize:", do_daemonize)
|
||||
|
|
@ -957,6 +959,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
|||
else O_LST(opt, "tls-session-ticket-keys", tls_session_ticket_keys.first)
|
||||
else O_STR(opt, "tls-ciphers", tls_ciphers)
|
||||
else O_STR(opt, "tls-ciphersuites", tls_ciphersuites)
|
||||
else O_DEC(opt, "https-port", https_port)
|
||||
else O_YNO(opt, "use-systemd", use_systemd)
|
||||
else O_YNO(opt, "do-daemonize", do_daemonize)
|
||||
else O_STR(opt, "chroot", chrootdir)
|
||||
|
|
|
|||
|
|
@ -128,6 +128,8 @@ struct config_file {
|
|||
char* tls_ciphers;
|
||||
/** TLS chiphersuites (TLSv1.3) */
|
||||
char* tls_ciphersuites;
|
||||
/** port on which to provide DNS over HTTPS service */
|
||||
int https_port;
|
||||
|
||||
/** outgoing port range number of ports (per thread) */
|
||||
int outgoing_num_ports;
|
||||
|
|
|
|||
4844
util/configlexer.c
4844
util/configlexer.c
File diff suppressed because it is too large
Load diff
|
|
@ -248,6 +248,7 @@ tls-additional-port{COLON} { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
|
|||
tls-session-ticket-keys{COLON} { YDVAR(1, VAR_TLS_SESSION_TICKET_KEYS) }
|
||||
tls-ciphers{COLON} { YDVAR(1, VAR_TLS_CIPHERS) }
|
||||
tls-ciphersuites{COLON} { YDVAR(1, VAR_TLS_CIPHERSUITES) }
|
||||
https-port{COLON} { YDVAR(1, VAR_HTTPS_PORT) }
|
||||
use-systemd{COLON} { YDVAR(1, VAR_USE_SYSTEMD) }
|
||||
do-daemonize{COLON} { YDVAR(1, VAR_DO_DAEMONIZE) }
|
||||
interface{COLON} { YDVAR(1, VAR_INTERFACE) }
|
||||
|
|
|
|||
3499
util/configparser.c
3499
util/configparser.c
File diff suppressed because it is too large
Load diff
|
|
@ -1,9 +1,8 @@
|
|||
/* A Bison parser, made by GNU Bison 3.4.1. */
|
||||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
|
||||
Inc.
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -31,9 +30,6 @@
|
|||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/* Undocumented macros, especially those whose name start with YY_,
|
||||
are private implementation details. Do not rely on them. */
|
||||
|
||||
#ifndef YY_YY_UTIL_CONFIGPARSER_H_INCLUDED
|
||||
# define YY_YY_UTIL_CONFIGPARSER_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
|
|
@ -187,150 +183,151 @@ extern int yydebug;
|
|||
VAR_STUB_SSL_UPSTREAM = 393,
|
||||
VAR_FORWARD_SSL_UPSTREAM = 394,
|
||||
VAR_TLS_CERT_BUNDLE = 395,
|
||||
VAR_STUB_FIRST = 396,
|
||||
VAR_MINIMAL_RESPONSES = 397,
|
||||
VAR_RRSET_ROUNDROBIN = 398,
|
||||
VAR_MAX_UDP_SIZE = 399,
|
||||
VAR_DELAY_CLOSE = 400,
|
||||
VAR_UNBLOCK_LAN_ZONES = 401,
|
||||
VAR_INSECURE_LAN_ZONES = 402,
|
||||
VAR_INFRA_CACHE_MIN_RTT = 403,
|
||||
VAR_DNS64_PREFIX = 404,
|
||||
VAR_DNS64_SYNTHALL = 405,
|
||||
VAR_DNS64_IGNORE_AAAA = 406,
|
||||
VAR_DNSTAP = 407,
|
||||
VAR_DNSTAP_ENABLE = 408,
|
||||
VAR_DNSTAP_SOCKET_PATH = 409,
|
||||
VAR_DNSTAP_IP = 410,
|
||||
VAR_DNSTAP_TLS = 411,
|
||||
VAR_DNSTAP_TLS_SERVER_NAME = 412,
|
||||
VAR_DNSTAP_TLS_CERT_BUNDLE = 413,
|
||||
VAR_DNSTAP_TLS_CLIENT_KEY_FILE = 414,
|
||||
VAR_DNSTAP_TLS_CLIENT_CERT_FILE = 415,
|
||||
VAR_DNSTAP_SEND_IDENTITY = 416,
|
||||
VAR_DNSTAP_SEND_VERSION = 417,
|
||||
VAR_DNSTAP_IDENTITY = 418,
|
||||
VAR_DNSTAP_VERSION = 419,
|
||||
VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES = 420,
|
||||
VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES = 421,
|
||||
VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES = 422,
|
||||
VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES = 423,
|
||||
VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES = 424,
|
||||
VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES = 425,
|
||||
VAR_RESPONSE_IP_TAG = 426,
|
||||
VAR_RESPONSE_IP = 427,
|
||||
VAR_RESPONSE_IP_DATA = 428,
|
||||
VAR_HARDEN_ALGO_DOWNGRADE = 429,
|
||||
VAR_IP_TRANSPARENT = 430,
|
||||
VAR_DISABLE_DNSSEC_LAME_CHECK = 431,
|
||||
VAR_IP_RATELIMIT = 432,
|
||||
VAR_IP_RATELIMIT_SLABS = 433,
|
||||
VAR_IP_RATELIMIT_SIZE = 434,
|
||||
VAR_RATELIMIT = 435,
|
||||
VAR_RATELIMIT_SLABS = 436,
|
||||
VAR_RATELIMIT_SIZE = 437,
|
||||
VAR_RATELIMIT_FOR_DOMAIN = 438,
|
||||
VAR_RATELIMIT_BELOW_DOMAIN = 439,
|
||||
VAR_IP_RATELIMIT_FACTOR = 440,
|
||||
VAR_RATELIMIT_FACTOR = 441,
|
||||
VAR_SEND_CLIENT_SUBNET = 442,
|
||||
VAR_CLIENT_SUBNET_ZONE = 443,
|
||||
VAR_CLIENT_SUBNET_ALWAYS_FORWARD = 444,
|
||||
VAR_CLIENT_SUBNET_OPCODE = 445,
|
||||
VAR_MAX_CLIENT_SUBNET_IPV4 = 446,
|
||||
VAR_MAX_CLIENT_SUBNET_IPV6 = 447,
|
||||
VAR_MIN_CLIENT_SUBNET_IPV4 = 448,
|
||||
VAR_MIN_CLIENT_SUBNET_IPV6 = 449,
|
||||
VAR_MAX_ECS_TREE_SIZE_IPV4 = 450,
|
||||
VAR_MAX_ECS_TREE_SIZE_IPV6 = 451,
|
||||
VAR_CAPS_WHITELIST = 452,
|
||||
VAR_CACHE_MAX_NEGATIVE_TTL = 453,
|
||||
VAR_PERMIT_SMALL_HOLDDOWN = 454,
|
||||
VAR_QNAME_MINIMISATION = 455,
|
||||
VAR_QNAME_MINIMISATION_STRICT = 456,
|
||||
VAR_IP_FREEBIND = 457,
|
||||
VAR_DEFINE_TAG = 458,
|
||||
VAR_LOCAL_ZONE_TAG = 459,
|
||||
VAR_ACCESS_CONTROL_TAG = 460,
|
||||
VAR_LOCAL_ZONE_OVERRIDE = 461,
|
||||
VAR_ACCESS_CONTROL_TAG_ACTION = 462,
|
||||
VAR_ACCESS_CONTROL_TAG_DATA = 463,
|
||||
VAR_VIEW = 464,
|
||||
VAR_ACCESS_CONTROL_VIEW = 465,
|
||||
VAR_VIEW_FIRST = 466,
|
||||
VAR_SERVE_EXPIRED = 467,
|
||||
VAR_SERVE_EXPIRED_TTL = 468,
|
||||
VAR_SERVE_EXPIRED_TTL_RESET = 469,
|
||||
VAR_SERVE_EXPIRED_REPLY_TTL = 470,
|
||||
VAR_SERVE_EXPIRED_CLIENT_TIMEOUT = 471,
|
||||
VAR_FAKE_DSA = 472,
|
||||
VAR_FAKE_SHA1 = 473,
|
||||
VAR_LOG_IDENTITY = 474,
|
||||
VAR_HIDE_TRUSTANCHOR = 475,
|
||||
VAR_TRUST_ANCHOR_SIGNALING = 476,
|
||||
VAR_AGGRESSIVE_NSEC = 477,
|
||||
VAR_USE_SYSTEMD = 478,
|
||||
VAR_SHM_ENABLE = 479,
|
||||
VAR_SHM_KEY = 480,
|
||||
VAR_ROOT_KEY_SENTINEL = 481,
|
||||
VAR_DNSCRYPT = 482,
|
||||
VAR_DNSCRYPT_ENABLE = 483,
|
||||
VAR_DNSCRYPT_PORT = 484,
|
||||
VAR_DNSCRYPT_PROVIDER = 485,
|
||||
VAR_DNSCRYPT_SECRET_KEY = 486,
|
||||
VAR_DNSCRYPT_PROVIDER_CERT = 487,
|
||||
VAR_DNSCRYPT_PROVIDER_CERT_ROTATED = 488,
|
||||
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE = 489,
|
||||
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS = 490,
|
||||
VAR_DNSCRYPT_NONCE_CACHE_SIZE = 491,
|
||||
VAR_DNSCRYPT_NONCE_CACHE_SLABS = 492,
|
||||
VAR_IPSECMOD_ENABLED = 493,
|
||||
VAR_IPSECMOD_HOOK = 494,
|
||||
VAR_IPSECMOD_IGNORE_BOGUS = 495,
|
||||
VAR_IPSECMOD_MAX_TTL = 496,
|
||||
VAR_IPSECMOD_WHITELIST = 497,
|
||||
VAR_IPSECMOD_STRICT = 498,
|
||||
VAR_CACHEDB = 499,
|
||||
VAR_CACHEDB_BACKEND = 500,
|
||||
VAR_CACHEDB_SECRETSEED = 501,
|
||||
VAR_CACHEDB_REDISHOST = 502,
|
||||
VAR_CACHEDB_REDISPORT = 503,
|
||||
VAR_CACHEDB_REDISTIMEOUT = 504,
|
||||
VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 505,
|
||||
VAR_FOR_UPSTREAM = 506,
|
||||
VAR_AUTH_ZONE = 507,
|
||||
VAR_ZONEFILE = 508,
|
||||
VAR_MASTER = 509,
|
||||
VAR_URL = 510,
|
||||
VAR_FOR_DOWNSTREAM = 511,
|
||||
VAR_FALLBACK_ENABLED = 512,
|
||||
VAR_TLS_ADDITIONAL_PORT = 513,
|
||||
VAR_LOW_RTT = 514,
|
||||
VAR_LOW_RTT_PERMIL = 515,
|
||||
VAR_FAST_SERVER_PERMIL = 516,
|
||||
VAR_FAST_SERVER_NUM = 517,
|
||||
VAR_ALLOW_NOTIFY = 518,
|
||||
VAR_TLS_WIN_CERT = 519,
|
||||
VAR_TCP_CONNECTION_LIMIT = 520,
|
||||
VAR_FORWARD_NO_CACHE = 521,
|
||||
VAR_STUB_NO_CACHE = 522,
|
||||
VAR_LOG_SERVFAIL = 523,
|
||||
VAR_DENY_ANY = 524,
|
||||
VAR_UNKNOWN_SERVER_TIME_LIMIT = 525,
|
||||
VAR_LOG_TAG_QUERYREPLY = 526,
|
||||
VAR_STREAM_WAIT_SIZE = 527,
|
||||
VAR_TLS_CIPHERS = 528,
|
||||
VAR_TLS_CIPHERSUITES = 529,
|
||||
VAR_IPSET = 530,
|
||||
VAR_IPSET_NAME_V4 = 531,
|
||||
VAR_IPSET_NAME_V6 = 532,
|
||||
VAR_TLS_SESSION_TICKET_KEYS = 533,
|
||||
VAR_RPZ = 534,
|
||||
VAR_TAGS = 535,
|
||||
VAR_RPZ_ACTION_OVERRIDE = 536,
|
||||
VAR_RPZ_CNAME_OVERRIDE = 537,
|
||||
VAR_RPZ_LOG = 538,
|
||||
VAR_RPZ_LOG_NAME = 539
|
||||
VAR_HTTPS_PORT = 396,
|
||||
VAR_STUB_FIRST = 397,
|
||||
VAR_MINIMAL_RESPONSES = 398,
|
||||
VAR_RRSET_ROUNDROBIN = 399,
|
||||
VAR_MAX_UDP_SIZE = 400,
|
||||
VAR_DELAY_CLOSE = 401,
|
||||
VAR_UNBLOCK_LAN_ZONES = 402,
|
||||
VAR_INSECURE_LAN_ZONES = 403,
|
||||
VAR_INFRA_CACHE_MIN_RTT = 404,
|
||||
VAR_DNS64_PREFIX = 405,
|
||||
VAR_DNS64_SYNTHALL = 406,
|
||||
VAR_DNS64_IGNORE_AAAA = 407,
|
||||
VAR_DNSTAP = 408,
|
||||
VAR_DNSTAP_ENABLE = 409,
|
||||
VAR_DNSTAP_SOCKET_PATH = 410,
|
||||
VAR_DNSTAP_IP = 411,
|
||||
VAR_DNSTAP_TLS = 412,
|
||||
VAR_DNSTAP_TLS_SERVER_NAME = 413,
|
||||
VAR_DNSTAP_TLS_CERT_BUNDLE = 414,
|
||||
VAR_DNSTAP_TLS_CLIENT_KEY_FILE = 415,
|
||||
VAR_DNSTAP_TLS_CLIENT_CERT_FILE = 416,
|
||||
VAR_DNSTAP_SEND_IDENTITY = 417,
|
||||
VAR_DNSTAP_SEND_VERSION = 418,
|
||||
VAR_DNSTAP_IDENTITY = 419,
|
||||
VAR_DNSTAP_VERSION = 420,
|
||||
VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES = 421,
|
||||
VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES = 422,
|
||||
VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES = 423,
|
||||
VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES = 424,
|
||||
VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES = 425,
|
||||
VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES = 426,
|
||||
VAR_RESPONSE_IP_TAG = 427,
|
||||
VAR_RESPONSE_IP = 428,
|
||||
VAR_RESPONSE_IP_DATA = 429,
|
||||
VAR_HARDEN_ALGO_DOWNGRADE = 430,
|
||||
VAR_IP_TRANSPARENT = 431,
|
||||
VAR_DISABLE_DNSSEC_LAME_CHECK = 432,
|
||||
VAR_IP_RATELIMIT = 433,
|
||||
VAR_IP_RATELIMIT_SLABS = 434,
|
||||
VAR_IP_RATELIMIT_SIZE = 435,
|
||||
VAR_RATELIMIT = 436,
|
||||
VAR_RATELIMIT_SLABS = 437,
|
||||
VAR_RATELIMIT_SIZE = 438,
|
||||
VAR_RATELIMIT_FOR_DOMAIN = 439,
|
||||
VAR_RATELIMIT_BELOW_DOMAIN = 440,
|
||||
VAR_IP_RATELIMIT_FACTOR = 441,
|
||||
VAR_RATELIMIT_FACTOR = 442,
|
||||
VAR_SEND_CLIENT_SUBNET = 443,
|
||||
VAR_CLIENT_SUBNET_ZONE = 444,
|
||||
VAR_CLIENT_SUBNET_ALWAYS_FORWARD = 445,
|
||||
VAR_CLIENT_SUBNET_OPCODE = 446,
|
||||
VAR_MAX_CLIENT_SUBNET_IPV4 = 447,
|
||||
VAR_MAX_CLIENT_SUBNET_IPV6 = 448,
|
||||
VAR_MIN_CLIENT_SUBNET_IPV4 = 449,
|
||||
VAR_MIN_CLIENT_SUBNET_IPV6 = 450,
|
||||
VAR_MAX_ECS_TREE_SIZE_IPV4 = 451,
|
||||
VAR_MAX_ECS_TREE_SIZE_IPV6 = 452,
|
||||
VAR_CAPS_WHITELIST = 453,
|
||||
VAR_CACHE_MAX_NEGATIVE_TTL = 454,
|
||||
VAR_PERMIT_SMALL_HOLDDOWN = 455,
|
||||
VAR_QNAME_MINIMISATION = 456,
|
||||
VAR_QNAME_MINIMISATION_STRICT = 457,
|
||||
VAR_IP_FREEBIND = 458,
|
||||
VAR_DEFINE_TAG = 459,
|
||||
VAR_LOCAL_ZONE_TAG = 460,
|
||||
VAR_ACCESS_CONTROL_TAG = 461,
|
||||
VAR_LOCAL_ZONE_OVERRIDE = 462,
|
||||
VAR_ACCESS_CONTROL_TAG_ACTION = 463,
|
||||
VAR_ACCESS_CONTROL_TAG_DATA = 464,
|
||||
VAR_VIEW = 465,
|
||||
VAR_ACCESS_CONTROL_VIEW = 466,
|
||||
VAR_VIEW_FIRST = 467,
|
||||
VAR_SERVE_EXPIRED = 468,
|
||||
VAR_SERVE_EXPIRED_TTL = 469,
|
||||
VAR_SERVE_EXPIRED_TTL_RESET = 470,
|
||||
VAR_SERVE_EXPIRED_REPLY_TTL = 471,
|
||||
VAR_SERVE_EXPIRED_CLIENT_TIMEOUT = 472,
|
||||
VAR_FAKE_DSA = 473,
|
||||
VAR_FAKE_SHA1 = 474,
|
||||
VAR_LOG_IDENTITY = 475,
|
||||
VAR_HIDE_TRUSTANCHOR = 476,
|
||||
VAR_TRUST_ANCHOR_SIGNALING = 477,
|
||||
VAR_AGGRESSIVE_NSEC = 478,
|
||||
VAR_USE_SYSTEMD = 479,
|
||||
VAR_SHM_ENABLE = 480,
|
||||
VAR_SHM_KEY = 481,
|
||||
VAR_ROOT_KEY_SENTINEL = 482,
|
||||
VAR_DNSCRYPT = 483,
|
||||
VAR_DNSCRYPT_ENABLE = 484,
|
||||
VAR_DNSCRYPT_PORT = 485,
|
||||
VAR_DNSCRYPT_PROVIDER = 486,
|
||||
VAR_DNSCRYPT_SECRET_KEY = 487,
|
||||
VAR_DNSCRYPT_PROVIDER_CERT = 488,
|
||||
VAR_DNSCRYPT_PROVIDER_CERT_ROTATED = 489,
|
||||
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE = 490,
|
||||
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS = 491,
|
||||
VAR_DNSCRYPT_NONCE_CACHE_SIZE = 492,
|
||||
VAR_DNSCRYPT_NONCE_CACHE_SLABS = 493,
|
||||
VAR_IPSECMOD_ENABLED = 494,
|
||||
VAR_IPSECMOD_HOOK = 495,
|
||||
VAR_IPSECMOD_IGNORE_BOGUS = 496,
|
||||
VAR_IPSECMOD_MAX_TTL = 497,
|
||||
VAR_IPSECMOD_WHITELIST = 498,
|
||||
VAR_IPSECMOD_STRICT = 499,
|
||||
VAR_CACHEDB = 500,
|
||||
VAR_CACHEDB_BACKEND = 501,
|
||||
VAR_CACHEDB_SECRETSEED = 502,
|
||||
VAR_CACHEDB_REDISHOST = 503,
|
||||
VAR_CACHEDB_REDISPORT = 504,
|
||||
VAR_CACHEDB_REDISTIMEOUT = 505,
|
||||
VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 506,
|
||||
VAR_FOR_UPSTREAM = 507,
|
||||
VAR_AUTH_ZONE = 508,
|
||||
VAR_ZONEFILE = 509,
|
||||
VAR_MASTER = 510,
|
||||
VAR_URL = 511,
|
||||
VAR_FOR_DOWNSTREAM = 512,
|
||||
VAR_FALLBACK_ENABLED = 513,
|
||||
VAR_TLS_ADDITIONAL_PORT = 514,
|
||||
VAR_LOW_RTT = 515,
|
||||
VAR_LOW_RTT_PERMIL = 516,
|
||||
VAR_FAST_SERVER_PERMIL = 517,
|
||||
VAR_FAST_SERVER_NUM = 518,
|
||||
VAR_ALLOW_NOTIFY = 519,
|
||||
VAR_TLS_WIN_CERT = 520,
|
||||
VAR_TCP_CONNECTION_LIMIT = 521,
|
||||
VAR_FORWARD_NO_CACHE = 522,
|
||||
VAR_STUB_NO_CACHE = 523,
|
||||
VAR_LOG_SERVFAIL = 524,
|
||||
VAR_DENY_ANY = 525,
|
||||
VAR_UNKNOWN_SERVER_TIME_LIMIT = 526,
|
||||
VAR_LOG_TAG_QUERYREPLY = 527,
|
||||
VAR_STREAM_WAIT_SIZE = 528,
|
||||
VAR_TLS_CIPHERS = 529,
|
||||
VAR_TLS_CIPHERSUITES = 530,
|
||||
VAR_IPSET = 531,
|
||||
VAR_IPSET_NAME_V4 = 532,
|
||||
VAR_IPSET_NAME_V6 = 533,
|
||||
VAR_TLS_SESSION_TICKET_KEYS = 534,
|
||||
VAR_RPZ = 535,
|
||||
VAR_TAGS = 536,
|
||||
VAR_RPZ_ACTION_OVERRIDE = 537,
|
||||
VAR_RPZ_CNAME_OVERRIDE = 538,
|
||||
VAR_RPZ_LOG = 539,
|
||||
VAR_RPZ_LOG_NAME = 540
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
|
|
@ -472,162 +469,164 @@ extern int yydebug;
|
|||
#define VAR_STUB_SSL_UPSTREAM 393
|
||||
#define VAR_FORWARD_SSL_UPSTREAM 394
|
||||
#define VAR_TLS_CERT_BUNDLE 395
|
||||
#define VAR_STUB_FIRST 396
|
||||
#define VAR_MINIMAL_RESPONSES 397
|
||||
#define VAR_RRSET_ROUNDROBIN 398
|
||||
#define VAR_MAX_UDP_SIZE 399
|
||||
#define VAR_DELAY_CLOSE 400
|
||||
#define VAR_UNBLOCK_LAN_ZONES 401
|
||||
#define VAR_INSECURE_LAN_ZONES 402
|
||||
#define VAR_INFRA_CACHE_MIN_RTT 403
|
||||
#define VAR_DNS64_PREFIX 404
|
||||
#define VAR_DNS64_SYNTHALL 405
|
||||
#define VAR_DNS64_IGNORE_AAAA 406
|
||||
#define VAR_DNSTAP 407
|
||||
#define VAR_DNSTAP_ENABLE 408
|
||||
#define VAR_DNSTAP_SOCKET_PATH 409
|
||||
#define VAR_DNSTAP_IP 410
|
||||
#define VAR_DNSTAP_TLS 411
|
||||
#define VAR_DNSTAP_TLS_SERVER_NAME 412
|
||||
#define VAR_DNSTAP_TLS_CERT_BUNDLE 413
|
||||
#define VAR_DNSTAP_TLS_CLIENT_KEY_FILE 414
|
||||
#define VAR_DNSTAP_TLS_CLIENT_CERT_FILE 415
|
||||
#define VAR_DNSTAP_SEND_IDENTITY 416
|
||||
#define VAR_DNSTAP_SEND_VERSION 417
|
||||
#define VAR_DNSTAP_IDENTITY 418
|
||||
#define VAR_DNSTAP_VERSION 419
|
||||
#define VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES 420
|
||||
#define VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES 421
|
||||
#define VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES 422
|
||||
#define VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES 423
|
||||
#define VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES 424
|
||||
#define VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES 425
|
||||
#define VAR_RESPONSE_IP_TAG 426
|
||||
#define VAR_RESPONSE_IP 427
|
||||
#define VAR_RESPONSE_IP_DATA 428
|
||||
#define VAR_HARDEN_ALGO_DOWNGRADE 429
|
||||
#define VAR_IP_TRANSPARENT 430
|
||||
#define VAR_DISABLE_DNSSEC_LAME_CHECK 431
|
||||
#define VAR_IP_RATELIMIT 432
|
||||
#define VAR_IP_RATELIMIT_SLABS 433
|
||||
#define VAR_IP_RATELIMIT_SIZE 434
|
||||
#define VAR_RATELIMIT 435
|
||||
#define VAR_RATELIMIT_SLABS 436
|
||||
#define VAR_RATELIMIT_SIZE 437
|
||||
#define VAR_RATELIMIT_FOR_DOMAIN 438
|
||||
#define VAR_RATELIMIT_BELOW_DOMAIN 439
|
||||
#define VAR_IP_RATELIMIT_FACTOR 440
|
||||
#define VAR_RATELIMIT_FACTOR 441
|
||||
#define VAR_SEND_CLIENT_SUBNET 442
|
||||
#define VAR_CLIENT_SUBNET_ZONE 443
|
||||
#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 444
|
||||
#define VAR_CLIENT_SUBNET_OPCODE 445
|
||||
#define VAR_MAX_CLIENT_SUBNET_IPV4 446
|
||||
#define VAR_MAX_CLIENT_SUBNET_IPV6 447
|
||||
#define VAR_MIN_CLIENT_SUBNET_IPV4 448
|
||||
#define VAR_MIN_CLIENT_SUBNET_IPV6 449
|
||||
#define VAR_MAX_ECS_TREE_SIZE_IPV4 450
|
||||
#define VAR_MAX_ECS_TREE_SIZE_IPV6 451
|
||||
#define VAR_CAPS_WHITELIST 452
|
||||
#define VAR_CACHE_MAX_NEGATIVE_TTL 453
|
||||
#define VAR_PERMIT_SMALL_HOLDDOWN 454
|
||||
#define VAR_QNAME_MINIMISATION 455
|
||||
#define VAR_QNAME_MINIMISATION_STRICT 456
|
||||
#define VAR_IP_FREEBIND 457
|
||||
#define VAR_DEFINE_TAG 458
|
||||
#define VAR_LOCAL_ZONE_TAG 459
|
||||
#define VAR_ACCESS_CONTROL_TAG 460
|
||||
#define VAR_LOCAL_ZONE_OVERRIDE 461
|
||||
#define VAR_ACCESS_CONTROL_TAG_ACTION 462
|
||||
#define VAR_ACCESS_CONTROL_TAG_DATA 463
|
||||
#define VAR_VIEW 464
|
||||
#define VAR_ACCESS_CONTROL_VIEW 465
|
||||
#define VAR_VIEW_FIRST 466
|
||||
#define VAR_SERVE_EXPIRED 467
|
||||
#define VAR_SERVE_EXPIRED_TTL 468
|
||||
#define VAR_SERVE_EXPIRED_TTL_RESET 469
|
||||
#define VAR_SERVE_EXPIRED_REPLY_TTL 470
|
||||
#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 471
|
||||
#define VAR_FAKE_DSA 472
|
||||
#define VAR_FAKE_SHA1 473
|
||||
#define VAR_LOG_IDENTITY 474
|
||||
#define VAR_HIDE_TRUSTANCHOR 475
|
||||
#define VAR_TRUST_ANCHOR_SIGNALING 476
|
||||
#define VAR_AGGRESSIVE_NSEC 477
|
||||
#define VAR_USE_SYSTEMD 478
|
||||
#define VAR_SHM_ENABLE 479
|
||||
#define VAR_SHM_KEY 480
|
||||
#define VAR_ROOT_KEY_SENTINEL 481
|
||||
#define VAR_DNSCRYPT 482
|
||||
#define VAR_DNSCRYPT_ENABLE 483
|
||||
#define VAR_DNSCRYPT_PORT 484
|
||||
#define VAR_DNSCRYPT_PROVIDER 485
|
||||
#define VAR_DNSCRYPT_SECRET_KEY 486
|
||||
#define VAR_DNSCRYPT_PROVIDER_CERT 487
|
||||
#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 488
|
||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 489
|
||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 490
|
||||
#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 491
|
||||
#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 492
|
||||
#define VAR_IPSECMOD_ENABLED 493
|
||||
#define VAR_IPSECMOD_HOOK 494
|
||||
#define VAR_IPSECMOD_IGNORE_BOGUS 495
|
||||
#define VAR_IPSECMOD_MAX_TTL 496
|
||||
#define VAR_IPSECMOD_WHITELIST 497
|
||||
#define VAR_IPSECMOD_STRICT 498
|
||||
#define VAR_CACHEDB 499
|
||||
#define VAR_CACHEDB_BACKEND 500
|
||||
#define VAR_CACHEDB_SECRETSEED 501
|
||||
#define VAR_CACHEDB_REDISHOST 502
|
||||
#define VAR_CACHEDB_REDISPORT 503
|
||||
#define VAR_CACHEDB_REDISTIMEOUT 504
|
||||
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 505
|
||||
#define VAR_FOR_UPSTREAM 506
|
||||
#define VAR_AUTH_ZONE 507
|
||||
#define VAR_ZONEFILE 508
|
||||
#define VAR_MASTER 509
|
||||
#define VAR_URL 510
|
||||
#define VAR_FOR_DOWNSTREAM 511
|
||||
#define VAR_FALLBACK_ENABLED 512
|
||||
#define VAR_TLS_ADDITIONAL_PORT 513
|
||||
#define VAR_LOW_RTT 514
|
||||
#define VAR_LOW_RTT_PERMIL 515
|
||||
#define VAR_FAST_SERVER_PERMIL 516
|
||||
#define VAR_FAST_SERVER_NUM 517
|
||||
#define VAR_ALLOW_NOTIFY 518
|
||||
#define VAR_TLS_WIN_CERT 519
|
||||
#define VAR_TCP_CONNECTION_LIMIT 520
|
||||
#define VAR_FORWARD_NO_CACHE 521
|
||||
#define VAR_STUB_NO_CACHE 522
|
||||
#define VAR_LOG_SERVFAIL 523
|
||||
#define VAR_DENY_ANY 524
|
||||
#define VAR_UNKNOWN_SERVER_TIME_LIMIT 525
|
||||
#define VAR_LOG_TAG_QUERYREPLY 526
|
||||
#define VAR_STREAM_WAIT_SIZE 527
|
||||
#define VAR_TLS_CIPHERS 528
|
||||
#define VAR_TLS_CIPHERSUITES 529
|
||||
#define VAR_IPSET 530
|
||||
#define VAR_IPSET_NAME_V4 531
|
||||
#define VAR_IPSET_NAME_V6 532
|
||||
#define VAR_TLS_SESSION_TICKET_KEYS 533
|
||||
#define VAR_RPZ 534
|
||||
#define VAR_TAGS 535
|
||||
#define VAR_RPZ_ACTION_OVERRIDE 536
|
||||
#define VAR_RPZ_CNAME_OVERRIDE 537
|
||||
#define VAR_RPZ_LOG 538
|
||||
#define VAR_RPZ_LOG_NAME 539
|
||||
#define VAR_HTTPS_PORT 396
|
||||
#define VAR_STUB_FIRST 397
|
||||
#define VAR_MINIMAL_RESPONSES 398
|
||||
#define VAR_RRSET_ROUNDROBIN 399
|
||||
#define VAR_MAX_UDP_SIZE 400
|
||||
#define VAR_DELAY_CLOSE 401
|
||||
#define VAR_UNBLOCK_LAN_ZONES 402
|
||||
#define VAR_INSECURE_LAN_ZONES 403
|
||||
#define VAR_INFRA_CACHE_MIN_RTT 404
|
||||
#define VAR_DNS64_PREFIX 405
|
||||
#define VAR_DNS64_SYNTHALL 406
|
||||
#define VAR_DNS64_IGNORE_AAAA 407
|
||||
#define VAR_DNSTAP 408
|
||||
#define VAR_DNSTAP_ENABLE 409
|
||||
#define VAR_DNSTAP_SOCKET_PATH 410
|
||||
#define VAR_DNSTAP_IP 411
|
||||
#define VAR_DNSTAP_TLS 412
|
||||
#define VAR_DNSTAP_TLS_SERVER_NAME 413
|
||||
#define VAR_DNSTAP_TLS_CERT_BUNDLE 414
|
||||
#define VAR_DNSTAP_TLS_CLIENT_KEY_FILE 415
|
||||
#define VAR_DNSTAP_TLS_CLIENT_CERT_FILE 416
|
||||
#define VAR_DNSTAP_SEND_IDENTITY 417
|
||||
#define VAR_DNSTAP_SEND_VERSION 418
|
||||
#define VAR_DNSTAP_IDENTITY 419
|
||||
#define VAR_DNSTAP_VERSION 420
|
||||
#define VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES 421
|
||||
#define VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES 422
|
||||
#define VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES 423
|
||||
#define VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES 424
|
||||
#define VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES 425
|
||||
#define VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES 426
|
||||
#define VAR_RESPONSE_IP_TAG 427
|
||||
#define VAR_RESPONSE_IP 428
|
||||
#define VAR_RESPONSE_IP_DATA 429
|
||||
#define VAR_HARDEN_ALGO_DOWNGRADE 430
|
||||
#define VAR_IP_TRANSPARENT 431
|
||||
#define VAR_DISABLE_DNSSEC_LAME_CHECK 432
|
||||
#define VAR_IP_RATELIMIT 433
|
||||
#define VAR_IP_RATELIMIT_SLABS 434
|
||||
#define VAR_IP_RATELIMIT_SIZE 435
|
||||
#define VAR_RATELIMIT 436
|
||||
#define VAR_RATELIMIT_SLABS 437
|
||||
#define VAR_RATELIMIT_SIZE 438
|
||||
#define VAR_RATELIMIT_FOR_DOMAIN 439
|
||||
#define VAR_RATELIMIT_BELOW_DOMAIN 440
|
||||
#define VAR_IP_RATELIMIT_FACTOR 441
|
||||
#define VAR_RATELIMIT_FACTOR 442
|
||||
#define VAR_SEND_CLIENT_SUBNET 443
|
||||
#define VAR_CLIENT_SUBNET_ZONE 444
|
||||
#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 445
|
||||
#define VAR_CLIENT_SUBNET_OPCODE 446
|
||||
#define VAR_MAX_CLIENT_SUBNET_IPV4 447
|
||||
#define VAR_MAX_CLIENT_SUBNET_IPV6 448
|
||||
#define VAR_MIN_CLIENT_SUBNET_IPV4 449
|
||||
#define VAR_MIN_CLIENT_SUBNET_IPV6 450
|
||||
#define VAR_MAX_ECS_TREE_SIZE_IPV4 451
|
||||
#define VAR_MAX_ECS_TREE_SIZE_IPV6 452
|
||||
#define VAR_CAPS_WHITELIST 453
|
||||
#define VAR_CACHE_MAX_NEGATIVE_TTL 454
|
||||
#define VAR_PERMIT_SMALL_HOLDDOWN 455
|
||||
#define VAR_QNAME_MINIMISATION 456
|
||||
#define VAR_QNAME_MINIMISATION_STRICT 457
|
||||
#define VAR_IP_FREEBIND 458
|
||||
#define VAR_DEFINE_TAG 459
|
||||
#define VAR_LOCAL_ZONE_TAG 460
|
||||
#define VAR_ACCESS_CONTROL_TAG 461
|
||||
#define VAR_LOCAL_ZONE_OVERRIDE 462
|
||||
#define VAR_ACCESS_CONTROL_TAG_ACTION 463
|
||||
#define VAR_ACCESS_CONTROL_TAG_DATA 464
|
||||
#define VAR_VIEW 465
|
||||
#define VAR_ACCESS_CONTROL_VIEW 466
|
||||
#define VAR_VIEW_FIRST 467
|
||||
#define VAR_SERVE_EXPIRED 468
|
||||
#define VAR_SERVE_EXPIRED_TTL 469
|
||||
#define VAR_SERVE_EXPIRED_TTL_RESET 470
|
||||
#define VAR_SERVE_EXPIRED_REPLY_TTL 471
|
||||
#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 472
|
||||
#define VAR_FAKE_DSA 473
|
||||
#define VAR_FAKE_SHA1 474
|
||||
#define VAR_LOG_IDENTITY 475
|
||||
#define VAR_HIDE_TRUSTANCHOR 476
|
||||
#define VAR_TRUST_ANCHOR_SIGNALING 477
|
||||
#define VAR_AGGRESSIVE_NSEC 478
|
||||
#define VAR_USE_SYSTEMD 479
|
||||
#define VAR_SHM_ENABLE 480
|
||||
#define VAR_SHM_KEY 481
|
||||
#define VAR_ROOT_KEY_SENTINEL 482
|
||||
#define VAR_DNSCRYPT 483
|
||||
#define VAR_DNSCRYPT_ENABLE 484
|
||||
#define VAR_DNSCRYPT_PORT 485
|
||||
#define VAR_DNSCRYPT_PROVIDER 486
|
||||
#define VAR_DNSCRYPT_SECRET_KEY 487
|
||||
#define VAR_DNSCRYPT_PROVIDER_CERT 488
|
||||
#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 489
|
||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 490
|
||||
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 491
|
||||
#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 492
|
||||
#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 493
|
||||
#define VAR_IPSECMOD_ENABLED 494
|
||||
#define VAR_IPSECMOD_HOOK 495
|
||||
#define VAR_IPSECMOD_IGNORE_BOGUS 496
|
||||
#define VAR_IPSECMOD_MAX_TTL 497
|
||||
#define VAR_IPSECMOD_WHITELIST 498
|
||||
#define VAR_IPSECMOD_STRICT 499
|
||||
#define VAR_CACHEDB 500
|
||||
#define VAR_CACHEDB_BACKEND 501
|
||||
#define VAR_CACHEDB_SECRETSEED 502
|
||||
#define VAR_CACHEDB_REDISHOST 503
|
||||
#define VAR_CACHEDB_REDISPORT 504
|
||||
#define VAR_CACHEDB_REDISTIMEOUT 505
|
||||
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 506
|
||||
#define VAR_FOR_UPSTREAM 507
|
||||
#define VAR_AUTH_ZONE 508
|
||||
#define VAR_ZONEFILE 509
|
||||
#define VAR_MASTER 510
|
||||
#define VAR_URL 511
|
||||
#define VAR_FOR_DOWNSTREAM 512
|
||||
#define VAR_FALLBACK_ENABLED 513
|
||||
#define VAR_TLS_ADDITIONAL_PORT 514
|
||||
#define VAR_LOW_RTT 515
|
||||
#define VAR_LOW_RTT_PERMIL 516
|
||||
#define VAR_FAST_SERVER_PERMIL 517
|
||||
#define VAR_FAST_SERVER_NUM 518
|
||||
#define VAR_ALLOW_NOTIFY 519
|
||||
#define VAR_TLS_WIN_CERT 520
|
||||
#define VAR_TCP_CONNECTION_LIMIT 521
|
||||
#define VAR_FORWARD_NO_CACHE 522
|
||||
#define VAR_STUB_NO_CACHE 523
|
||||
#define VAR_LOG_SERVFAIL 524
|
||||
#define VAR_DENY_ANY 525
|
||||
#define VAR_UNKNOWN_SERVER_TIME_LIMIT 526
|
||||
#define VAR_LOG_TAG_QUERYREPLY 527
|
||||
#define VAR_STREAM_WAIT_SIZE 528
|
||||
#define VAR_TLS_CIPHERS 529
|
||||
#define VAR_TLS_CIPHERSUITES 530
|
||||
#define VAR_IPSET 531
|
||||
#define VAR_IPSET_NAME_V4 532
|
||||
#define VAR_IPSET_NAME_V6 533
|
||||
#define VAR_TLS_SESSION_TICKET_KEYS 534
|
||||
#define VAR_RPZ 535
|
||||
#define VAR_TAGS 536
|
||||
#define VAR_RPZ_ACTION_OVERRIDE 537
|
||||
#define VAR_RPZ_CNAME_OVERRIDE 538
|
||||
#define VAR_RPZ_LOG 539
|
||||
#define VAR_RPZ_LOG_NAME 540
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 66 "./util/configparser.y"
|
||||
#line 66 "./util/configparser.y" /* yacc.c:1909 */
|
||||
|
||||
char* str;
|
||||
|
||||
#line 629 "util/configparser.h"
|
||||
|
||||
#line 628 "util/configparser.h" /* yacc.c:1909 */
|
||||
};
|
||||
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ extern struct config_parser_state* cfg_parser;
|
|||
%token VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM
|
||||
%token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST
|
||||
%token VAR_STUB_SSL_UPSTREAM VAR_FORWARD_SSL_UPSTREAM VAR_TLS_CERT_BUNDLE
|
||||
%token VAR_HTTPS_PORT
|
||||
%token VAR_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN
|
||||
%token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE
|
||||
%token VAR_UNBLOCK_LAN_ZONES VAR_INSECURE_LAN_ZONES
|
||||
|
|
@ -235,6 +236,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
|||
server_log_queries | server_log_replies | server_tcp_upstream | server_ssl_upstream |
|
||||
server_log_local_actions |
|
||||
server_ssl_service_key | server_ssl_service_pem | server_ssl_port |
|
||||
server_https_port |
|
||||
server_minimal_responses | server_rrset_roundrobin | server_max_udp_size |
|
||||
server_so_reuseport | server_delay_close |
|
||||
server_unblock_lan_zones | server_insecure_lan_zones |
|
||||
|
|
@ -949,6 +951,15 @@ server_tls_session_ticket_keys: VAR_TLS_SESSION_TICKET_KEYS STRING_ARG
|
|||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
server_https_port: VAR_HTTPS_PORT STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_https_port:%s)\n", $2));
|
||||
if(atoi($2) == 0)
|
||||
yyerror("port number expected");
|
||||
else cfg_parser->cfg->https_port = atoi($2);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_use_systemd: VAR_USE_SYSTEMD STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_use_systemd:%s)\n", $2));
|
||||
|
|
|
|||
|
|
@ -3771,6 +3771,7 @@
|
|||
4188,
|
||||
4191,
|
||||
4192,
|
||||
4195,
|
||||
4197,
|
||||
4199,
|
||||
4300,
|
||||
|
|
|
|||
|
|
@ -58,6 +58,9 @@
|
|||
#ifdef USE_WINSOCK
|
||||
#include <wincrypt.h>
|
||||
#endif
|
||||
#ifdef HAVE_NGHTTP2_NGHTTP2_H
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#endif
|
||||
|
||||
/** max length of an IP address (the address portion) that we allow */
|
||||
#define MAX_ADDR_STRLEN 128 /* characters */
|
||||
|
|
@ -855,6 +858,21 @@ log_cert(unsigned level, const char* str, void* cert)
|
|||
}
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
#if defined(HAVE_SSL) && defined(HAVE_NGHTTP2)
|
||||
static int alpn_select_cb(SSL* ATTR_UNUSED(ssl), const unsigned char** out,
|
||||
unsigned char* outlen, const unsigned char* in, unsigned int inlen,
|
||||
void* ATTR_UNUSED(arg))
|
||||
{
|
||||
int rv = nghttp2_select_next_protocol((unsigned char **)out, outlen, in,
|
||||
inlen);
|
||||
if(rv == -1) {
|
||||
return SSL_TLSEXT_ERR_NOACK;
|
||||
}
|
||||
/* either http/1.1 or h2 selected */
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
listen_sslctx_setup(void* ctxt)
|
||||
{
|
||||
|
|
@ -913,6 +931,9 @@ listen_sslctx_setup(void* ctxt)
|
|||
#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL
|
||||
SSL_CTX_set_security_level(ctx, 0);
|
||||
#endif
|
||||
#if defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB) && defined(HAVE_NGHTTP2)
|
||||
SSL_CTX_set_alpn_select_cb(ctx, alpn_select_cb, NULL);
|
||||
#endif
|
||||
#else
|
||||
(void)ctxt;
|
||||
#endif /* HAVE_SSL */
|
||||
|
|
|
|||
535
util/netevent.c
535
util/netevent.c
|
|
@ -733,7 +733,7 @@ static void
|
|||
setup_tcp_handler(struct comm_point* c, int fd, int cur, int max)
|
||||
{
|
||||
int handler_usage;
|
||||
log_assert(c->type == comm_tcp);
|
||||
log_assert(c->type == comm_tcp || c->type == comm_http);
|
||||
log_assert(c->fd == -1);
|
||||
sldns_buffer_clear(c->buffer);
|
||||
#ifdef USE_DNSCRYPT
|
||||
|
|
@ -908,6 +908,41 @@ comm_point_tcp_win_bio_cb(struct comm_point* c, void* thessl)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NGHTTP2
|
||||
/** Create http2 session server. Per connection, after TCP accepted.*/
|
||||
static int http2_session_server_create(struct http2_session* h2_session)
|
||||
{
|
||||
log_assert(h2_session->callbacks);
|
||||
h2_session->is_drop = 0;
|
||||
if(nghttp2_session_server_new(&h2_session->session,
|
||||
h2_session->callbacks,
|
||||
h2_session) == NGHTTP2_ERR_NOMEM) {
|
||||
log_err("failed to create nghttp2 session server");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Submit http2 setting to session. Once per session. */
|
||||
static int http2_submit_settings(struct http2_session* h2_session)
|
||||
{
|
||||
int ret;
|
||||
nghttp2_settings_entry settings[1] = {
|
||||
{NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100}};
|
||||
|
||||
ret = nghttp2_submit_settings(h2_session->session, NGHTTP2_FLAG_NONE,
|
||||
settings, 1);
|
||||
if(ret) {
|
||||
verbose(VERB_QUERY, "http2: submit_settings failed, "
|
||||
"error: %s", nghttp2_strerror(ret));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif /* HAVE_NGHTTP2 */
|
||||
|
||||
|
||||
void
|
||||
comm_point_tcp_accept_callback(int fd, short event, void* arg)
|
||||
{
|
||||
|
|
@ -929,7 +964,28 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
|
|||
/* clear leftover flags from previous use, and then set the
|
||||
* correct event base for the event structure for libevent */
|
||||
ub_event_free(c_hdl->ev->ev);
|
||||
c_hdl->ev->ev = ub_event_new(c_hdl->ev->base->eb->base, -1, UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT, comm_point_tcp_handle_callback, c_hdl);
|
||||
|
||||
#ifdef HAVE_NGHTTP2
|
||||
if(c_hdl->type == comm_http && c_hdl->h2_session) {
|
||||
if(!http2_session_server_create(c_hdl->h2_session)) {
|
||||
log_warn("failed to create nghttp2");
|
||||
return;
|
||||
}
|
||||
if(!http2_submit_settings(c_hdl->h2_session)) {
|
||||
log_warn("failed to submit http2 settings");
|
||||
return;
|
||||
}
|
||||
c_hdl->ev->ev = ub_event_new(c_hdl->ev->base->eb->base, -1,
|
||||
UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT,
|
||||
comm_point_http_handle_callback, c_hdl);
|
||||
} else {
|
||||
#endif
|
||||
c_hdl->ev->ev = ub_event_new(c_hdl->ev->base->eb->base, -1,
|
||||
UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT,
|
||||
comm_point_tcp_handle_callback, c_hdl);
|
||||
#ifdef HAVE_NGHTTP2
|
||||
}
|
||||
#endif
|
||||
if(!c_hdl->ev->ev) {
|
||||
log_warn("could not ub_event_new, dropped tcp");
|
||||
return;
|
||||
|
|
@ -1163,6 +1219,18 @@ ssl_handshake(struct comm_point* c)
|
|||
c->repinfo.addrlen);
|
||||
}
|
||||
|
||||
/* check if http2 use is negotiated */
|
||||
if(c->type == comm_http && c->h2_session) {
|
||||
const unsigned char *alpn;
|
||||
unsigned int alpnlen = 0;
|
||||
SSL_get0_alpn_selected(c->ssl, &alpn, &alpnlen);
|
||||
if(alpnlen == 2 && memcmp("h2", alpn, 2) == 0) {
|
||||
/* connection upgraded to HTTP2 */
|
||||
c->tcp_do_toggle_rw = 0;
|
||||
c->alpn_h2 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* setup listen rw correctly */
|
||||
if(c->tcp_is_reading) {
|
||||
if(c->ssl_shake_state != comm_ssl_shake_read)
|
||||
|
|
@ -2180,11 +2248,210 @@ http_chunked_segment(struct comm_point* c)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_NGHTTP2
|
||||
/** Create new http2 session. Called when creating handling comm point. */
|
||||
struct http2_session* http2_session_create(struct comm_point* c)
|
||||
{
|
||||
struct http2_session* session = calloc(1, sizeof(*session));
|
||||
if(!session) {
|
||||
log_err("malloc failure while creating http2 session");
|
||||
return NULL;
|
||||
}
|
||||
session->c = c;
|
||||
|
||||
return session;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Delete http2 session. After closing connection or on error */
|
||||
void http2_session_delete(struct http2_session* h2_session)
|
||||
{
|
||||
#ifdef HAVE_NGHTTP2
|
||||
if(h2_session->callbacks)
|
||||
nghttp2_session_callbacks_del(h2_session->callbacks);
|
||||
free(h2_session);
|
||||
#else
|
||||
(void)h2_session;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_NGHTTP2
|
||||
struct http2_stream* http2_stream_create(int32_t stream_id)
|
||||
{
|
||||
struct http2_stream* h2_stream = calloc(1, sizeof(*h2_stream));
|
||||
if(!h2_stream) {
|
||||
log_err("malloc failure while creating http2 stream");
|
||||
return NULL;
|
||||
}
|
||||
h2_stream->stream_id = stream_id;
|
||||
return h2_stream;
|
||||
}
|
||||
|
||||
/** Delete http2 stream. After session delete or stream close callback */
|
||||
void http2_stream_delete(struct http2_session* h2_session,
|
||||
struct http2_stream* h2_stream)
|
||||
{
|
||||
if(h2_stream->mesh_state) {
|
||||
mesh_state_remove_reply(h2_stream->mesh, h2_stream->mesh_state,
|
||||
h2_session->c);
|
||||
}
|
||||
if(h2_stream->qbuffer)
|
||||
sldns_buffer_free(h2_stream->qbuffer);
|
||||
if(h2_stream->rbuffer)
|
||||
sldns_buffer_free(h2_stream->rbuffer);
|
||||
free(h2_stream);
|
||||
}
|
||||
#endif
|
||||
|
||||
void http2_stream_add_meshstate(struct http2_stream* h2_stream,
|
||||
struct mesh_area* mesh, struct mesh_state* m)
|
||||
{
|
||||
h2_stream->mesh = mesh;
|
||||
h2_stream->mesh_state = m;
|
||||
}
|
||||
|
||||
/** delete http2 session server. After closing connection. */
|
||||
static void http2_session_server_delete(struct http2_session* h2_session)
|
||||
{
|
||||
#ifdef HAVE_NGHTTP2
|
||||
struct http2_stream* h2_stream, *next;
|
||||
nghttp2_session_del(h2_session->session); /* NULL input is fine */
|
||||
h2_session->session = NULL;
|
||||
for(h2_stream = h2_session->first_stream; h2_stream;) {
|
||||
next = h2_stream->next;
|
||||
http2_stream_delete(h2_session, h2_stream);
|
||||
h2_stream = next;
|
||||
}
|
||||
h2_session->first_stream = NULL;
|
||||
h2_session->is_drop = 0;
|
||||
h2_session->postpone_drop = 0;
|
||||
h2_session->c->h2_stream = NULL;
|
||||
#endif
|
||||
(void)h2_session;
|
||||
}
|
||||
|
||||
#ifdef HAVE_NGHTTP2
|
||||
void http2_session_add_stream(struct http2_session* h2_session,
|
||||
struct http2_stream* h2_stream)
|
||||
{
|
||||
if(h2_session->first_stream)
|
||||
h2_session->first_stream->prev = h2_stream;
|
||||
h2_stream->next = h2_session->first_stream;
|
||||
h2_session->first_stream = h2_stream;
|
||||
}
|
||||
|
||||
/** remove stream from session linked list. After stream close callback or
|
||||
* closing connection */
|
||||
void http2_session_remove_stream(struct http2_session* h2_session,
|
||||
struct http2_stream* h2_stream)
|
||||
{
|
||||
if(h2_stream->prev)
|
||||
h2_stream->prev->next = h2_stream->next;
|
||||
else
|
||||
h2_session->first_stream = h2_stream->next;
|
||||
if(h2_stream->next)
|
||||
h2_stream->next->prev = h2_stream->prev;
|
||||
|
||||
}
|
||||
|
||||
int http2_stream_close_cb(nghttp2_session* ATTR_UNUSED(session),
|
||||
int32_t stream_id, uint32_t ATTR_UNUSED(error_code), void* cb_arg)
|
||||
{
|
||||
struct http2_stream* h2_stream;
|
||||
struct http2_session* h2_session = (struct http2_session*)cb_arg;
|
||||
if(!(h2_stream = nghttp2_session_get_stream_user_data(
|
||||
h2_session->session, stream_id))) {
|
||||
return 0;
|
||||
}
|
||||
http2_session_remove_stream(h2_session, h2_stream);
|
||||
http2_stream_delete(h2_session, h2_stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t http2_recv_cb(nghttp2_session* ATTR_UNUSED(session), uint8_t* buf,
|
||||
size_t len, int ATTR_UNUSED(flags), void* cb_arg)
|
||||
{
|
||||
#ifdef HAVE_SSL
|
||||
struct http2_session* h2_session = (struct http2_session*)cb_arg;
|
||||
int r;
|
||||
|
||||
log_assert(h2_session->c->type == comm_http);
|
||||
log_assert(h2_session->c->h2_session);
|
||||
|
||||
if(!h2_session->c->ssl)
|
||||
return 0;
|
||||
|
||||
ERR_clear_error();
|
||||
r = SSL_read(h2_session->c->ssl, buf, len);
|
||||
if(r <= 0) {
|
||||
int want = SSL_get_error(h2_session->c->ssl, r);
|
||||
if(want == SSL_ERROR_ZERO_RETURN) {
|
||||
return NGHTTP2_ERR_EOF;
|
||||
} else if(want == SSL_ERROR_WANT_READ) {
|
||||
return NGHTTP2_ERR_WOULDBLOCK;
|
||||
} else if(want == SSL_ERROR_WANT_WRITE) {
|
||||
h2_session->c->ssl_shake_state = comm_ssl_shake_hs_write;
|
||||
comm_point_listen_for_rw(h2_session->c, 0, 1);
|
||||
return NGHTTP2_ERR_WOULDBLOCK;
|
||||
} else if(want == SSL_ERROR_SYSCALL) {
|
||||
#ifdef ECONNRESET
|
||||
if(errno == ECONNRESET && verbosity < 2)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
#endif
|
||||
if(errno != 0)
|
||||
log_err("SSL_read syscall: %s",
|
||||
strerror(errno));
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
log_crypto_err("could not SSL_read");
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
return r;
|
||||
#else
|
||||
(void)buf;
|
||||
(void)len;
|
||||
(void)cb_arg;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
#endif /* HAVE_NGHTTP2 */
|
||||
|
||||
/** Handle http2 read */
|
||||
static int
|
||||
comm_point_http2_handle_read(int ATTR_UNUSED(fd), struct comm_point* c)
|
||||
{
|
||||
#ifdef HAVE_NGHTTP2
|
||||
int ret;
|
||||
log_assert(c->h2_session);
|
||||
log_assert(c->ssl);
|
||||
|
||||
/* reading until recv cb returns NGHTTP2_ERR_WOULDBLOCK */
|
||||
ret = nghttp2_session_recv(c->h2_session->session);
|
||||
if(ret) {
|
||||
if(ret != NGHTTP2_ERR_EOF) {
|
||||
verbose(VERB_QUERY, "http2: session_recv failed, "
|
||||
"error: %s", nghttp2_strerror(ret));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(nghttp2_session_want_write(c->h2_session->session)) {
|
||||
c->tcp_is_reading = 0;
|
||||
comm_point_stop_listening(c);
|
||||
comm_point_start_listening(c, -1, c->tcp_timeout_msec);
|
||||
} else if(!nghttp2_session_want_read(c->h2_session->session))
|
||||
return 0; /* connection can be closed */
|
||||
return 1;
|
||||
#else
|
||||
(void)c;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle http reading callback.
|
||||
* Handle http reading callback.
|
||||
* @param fd: file descriptor of socket.
|
||||
* @param c: comm point to read from into buffer.
|
||||
* @return: 0 on error
|
||||
* @return: 0 on error
|
||||
*/
|
||||
static int
|
||||
comm_point_http_handle_read(int fd, struct comm_point* c)
|
||||
|
|
@ -2204,6 +2471,18 @@ comm_point_http_handle_read(int fd, struct comm_point* c)
|
|||
|
||||
if(!c->tcp_is_reading)
|
||||
return 1;
|
||||
|
||||
if(c->alpn_h2) {
|
||||
return comm_point_http2_handle_read(fd, c);
|
||||
}
|
||||
|
||||
/* http version is <= http/1.1 */
|
||||
|
||||
if(c->http_min_version >= http_version_2) {
|
||||
/* HTTP/2 failed, not allowed to use lower version. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* read more data */
|
||||
if(c->ssl) {
|
||||
if(!ssl_http_read_more(c))
|
||||
|
|
@ -2214,7 +2493,9 @@ comm_point_http_handle_read(int fd, struct comm_point* c)
|
|||
}
|
||||
|
||||
sldns_buffer_flip(c->buffer);
|
||||
|
||||
while(sldns_buffer_remaining(c->buffer) > 0) {
|
||||
/* Handle HTTP/1.x data */
|
||||
/* if we are reading headers, read more headers */
|
||||
if(c->http_in_headers || c->http_in_chunk_headers) {
|
||||
/* if header is done, process the header */
|
||||
|
|
@ -2376,6 +2657,83 @@ http_write_more(int fd, struct comm_point* c)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_NGHTTP2
|
||||
ssize_t http2_send_cb(nghttp2_session* ATTR_UNUSED(session), const uint8_t* buf,
|
||||
size_t len, int ATTR_UNUSED(flags), void* cb_arg)
|
||||
{
|
||||
#ifdef HAVE_SSL
|
||||
int r;
|
||||
struct http2_session* h2_session = (struct http2_session*)cb_arg;
|
||||
log_assert(h2_session->c->type == comm_http);
|
||||
log_assert(h2_session->c->h2_session);
|
||||
|
||||
if(!h2_session->c->ssl)
|
||||
return 0;
|
||||
|
||||
ERR_clear_error();
|
||||
r = SSL_write(h2_session->c->ssl, buf, len);
|
||||
if(r <= 0) {
|
||||
int want = SSL_get_error(h2_session->c->ssl, r);
|
||||
if(want == SSL_ERROR_ZERO_RETURN) {
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
} else if(want == SSL_ERROR_WANT_READ) {
|
||||
h2_session->c->ssl_shake_state = comm_ssl_shake_hs_read;
|
||||
comm_point_listen_for_rw(h2_session->c, 1, 0);
|
||||
return NGHTTP2_ERR_WOULDBLOCK;
|
||||
} else if(want == SSL_ERROR_WANT_WRITE) {
|
||||
return NGHTTP2_ERR_WOULDBLOCK;
|
||||
} else if(want == SSL_ERROR_SYSCALL) {
|
||||
#ifdef EPIPE
|
||||
if(errno == EPIPE && verbosity < 2)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
#endif
|
||||
if(errno != 0)
|
||||
log_err("SSL_write syscall: %s",
|
||||
strerror(errno));
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
log_crypto_err("could not SSL_write");
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
return r;
|
||||
#else
|
||||
(void)buf;
|
||||
(void)len;
|
||||
(void)cb_arg;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
#endif /* HAVE_NGHTTP2 */
|
||||
|
||||
/** Handle http2 writing */
|
||||
static int
|
||||
comm_point_http2_handle_write(int ATTR_UNUSED(fd), struct comm_point* c)
|
||||
{
|
||||
#ifdef HAVE_NGHTTP2
|
||||
int ret;
|
||||
log_assert(c->h2_session);
|
||||
log_assert(c->ssl);
|
||||
|
||||
ret = nghttp2_session_send(c->h2_session->session);
|
||||
if(ret) {
|
||||
verbose(VERB_QUERY, "http2: session_send failed, "
|
||||
"error: %s", nghttp2_strerror(ret));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(nghttp2_session_want_read(c->h2_session->session)) {
|
||||
c->tcp_is_reading = 1;
|
||||
comm_point_stop_listening(c);
|
||||
comm_point_start_listening(c, -1, c->tcp_timeout_msec);
|
||||
} else if(!nghttp2_session_want_write(c->h2_session->session))
|
||||
return 0; /* connection can be closed */
|
||||
return 1;
|
||||
#else
|
||||
(void)c;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle http writing callback.
|
||||
* @param fd: file descriptor of socket.
|
||||
|
|
@ -2407,6 +2765,18 @@ comm_point_http_handle_write(int fd, struct comm_point* c)
|
|||
#endif /* HAVE_SSL */
|
||||
if(c->tcp_is_reading)
|
||||
return 1;
|
||||
|
||||
if(c->alpn_h2) {
|
||||
return comm_point_http2_handle_write(fd, c);
|
||||
}
|
||||
|
||||
/* http version is <= http/1.1 */
|
||||
|
||||
if(c->http_min_version >= http_version_2) {
|
||||
/* HTTP/2 failed, not allowed to use lower version. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if we are writing, write more */
|
||||
if(c->ssl) {
|
||||
if(!ssl_http_write_more(c))
|
||||
|
|
@ -2718,11 +3088,116 @@ comm_point_create_tcp_handler(struct comm_base *base,
|
|||
return c;
|
||||
}
|
||||
|
||||
static struct comm_point*
|
||||
comm_point_create_http_handler(struct comm_base *base,
|
||||
struct comm_point* parent, size_t bufsize, int harden_large_queries,
|
||||
comm_point_callback_type* callback, void* callback_arg)
|
||||
{
|
||||
struct comm_point* c = (struct comm_point*)calloc(1,
|
||||
sizeof(struct comm_point));
|
||||
short evbits;
|
||||
if(!c)
|
||||
return NULL;
|
||||
c->ev = (struct internal_event*)calloc(1,
|
||||
sizeof(struct internal_event));
|
||||
if(!c->ev) {
|
||||
free(c);
|
||||
return NULL;
|
||||
}
|
||||
c->ev->base = base;
|
||||
c->fd = -1;
|
||||
c->buffer = sldns_buffer_new(bufsize);
|
||||
if(!c->buffer) {
|
||||
free(c->ev);
|
||||
free(c);
|
||||
return NULL;
|
||||
}
|
||||
c->timeout = (struct timeval*)malloc(sizeof(struct timeval));
|
||||
if(!c->timeout) {
|
||||
sldns_buffer_free(c->buffer);
|
||||
free(c->ev);
|
||||
free(c);
|
||||
return NULL;
|
||||
}
|
||||
c->tcp_is_reading = 0;
|
||||
c->tcp_byte_count = 0;
|
||||
c->tcp_parent = parent;
|
||||
c->tcp_timeout_msec = parent->tcp_timeout_msec;
|
||||
c->tcp_conn_limit = parent->tcp_conn_limit;
|
||||
c->tcl_addr = NULL;
|
||||
c->tcp_keepalive = 0;
|
||||
c->max_tcp_count = 0;
|
||||
c->cur_tcp_count = 0;
|
||||
c->tcp_handlers = NULL;
|
||||
c->tcp_free = NULL;
|
||||
c->type = comm_http;
|
||||
c->tcp_do_close = 1;
|
||||
c->do_not_close = 0;
|
||||
c->tcp_do_toggle_rw = 1; /* will be set to 0 after http2 upgrade */
|
||||
c->tcp_check_nb_connect = 0;
|
||||
#ifdef USE_MSG_FASTOPEN
|
||||
c->tcp_do_fastopen = 0;
|
||||
#endif
|
||||
#ifdef USE_DNSCRYPT
|
||||
c->dnscrypt = 0;
|
||||
c->dnscrypt_buffer = NULL;
|
||||
#endif
|
||||
c->repinfo.c = c;
|
||||
c->callback = callback;
|
||||
c->cb_arg = callback_arg;
|
||||
|
||||
c->http_min_version = http_version_2;
|
||||
c->http2_max_qbuffer_size = bufsize;
|
||||
if(harden_large_queries && bufsize > 512)
|
||||
c->http2_max_qbuffer_size = 512;
|
||||
c->alpn_h2 = 0;
|
||||
#ifdef HAVE_NGHTTP2
|
||||
if(!(c->h2_session = http2_session_create(c))) {
|
||||
log_err("could not create http2 session");
|
||||
sldns_buffer_free(c->buffer);
|
||||
free(c->timeout);
|
||||
free(c->ev);
|
||||
free(c);
|
||||
return NULL;
|
||||
}
|
||||
if(!(c->h2_session->callbacks = http2_req_callbacks_create())) {
|
||||
log_err("could not create http2 callbacks");
|
||||
http2_session_delete(c->h2_session);
|
||||
sldns_buffer_free(c->buffer);
|
||||
free(c->timeout);
|
||||
free(c->ev);
|
||||
free(c);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* add to parent free list */
|
||||
c->tcp_free = parent->tcp_free;
|
||||
parent->tcp_free = c;
|
||||
/* ub_event stuff */
|
||||
evbits = UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT;
|
||||
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
|
||||
comm_point_http_handle_callback, c);
|
||||
if(c->ev->ev == NULL)
|
||||
{
|
||||
log_err("could not set http handler event");
|
||||
parent->tcp_free = c->tcp_free;
|
||||
http2_session_delete(c->h2_session);
|
||||
sldns_buffer_free(c->buffer);
|
||||
free(c->timeout);
|
||||
free(c->ev);
|
||||
free(c);
|
||||
return NULL;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
struct comm_point*
|
||||
comm_point_create_tcp(struct comm_base *base, int fd, int num,
|
||||
int idle_timeout, struct tcl_list* tcp_conn_limit, size_t bufsize,
|
||||
struct sldns_buffer* spoolbuf, comm_point_callback_type* callback,
|
||||
void* callback_arg)
|
||||
int idle_timeout, int harden_large_queries,
|
||||
struct tcl_list* tcp_conn_limit, size_t bufsize,
|
||||
struct sldns_buffer* spoolbuf, enum listen_type port_type,
|
||||
comm_point_callback_type* callback, void* callback_arg)
|
||||
{
|
||||
struct comm_point* c = (struct comm_point*)calloc(1,
|
||||
sizeof(struct comm_point));
|
||||
|
|
@ -2786,10 +3261,23 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num,
|
|||
comm_point_delete(c);
|
||||
return NULL;
|
||||
}
|
||||
/* now prealloc the tcp handlers */
|
||||
/* now prealloc the handlers */
|
||||
for(i=0; i<num; i++) {
|
||||
c->tcp_handlers[i] = comm_point_create_tcp_handler(base,
|
||||
c, bufsize, spoolbuf, callback, callback_arg);
|
||||
if(port_type == listen_type_tcp ||
|
||||
port_type == listen_type_ssl ||
|
||||
port_type == listen_type_tcp_dnscrypt) {
|
||||
c->tcp_handlers[i] = comm_point_create_tcp_handler(base,
|
||||
c, bufsize, spoolbuf, callback, callback_arg);
|
||||
} else if(port_type == listen_type_http) {
|
||||
c->tcp_handlers[i] = comm_point_create_http_handler(
|
||||
base, c, bufsize, harden_large_queries,
|
||||
callback, callback_arg);
|
||||
}
|
||||
else {
|
||||
log_err("could not create tcp handler, unknown listen "
|
||||
"type");
|
||||
return NULL;
|
||||
}
|
||||
if(!c->tcp_handlers[i]) {
|
||||
comm_point_delete(c);
|
||||
return NULL;
|
||||
|
|
@ -3073,6 +3561,9 @@ comm_point_close(struct comm_point* c)
|
|||
tcl_close_connection(c->tcl_addr);
|
||||
if(c->tcp_req_info)
|
||||
tcp_req_info_clear(c->tcp_req_info);
|
||||
if(c->h2_session)
|
||||
http2_session_server_delete(c->h2_session);
|
||||
|
||||
/* close fd after removing from event lists, or epoll.. is messed up */
|
||||
if(c->fd != -1 && !c->do_not_close) {
|
||||
if(c->type == comm_tcp || c->type == comm_http) {
|
||||
|
|
@ -3119,6 +3610,9 @@ comm_point_delete(struct comm_point* c)
|
|||
if(c->tcp_req_info) {
|
||||
tcp_req_info_delete(c->tcp_req_info);
|
||||
}
|
||||
if(c->h2_session) {
|
||||
http2_session_delete(c->h2_session);
|
||||
}
|
||||
}
|
||||
ub_event_free(c->ev->ev);
|
||||
free(c->ev);
|
||||
|
|
@ -3161,6 +3655,17 @@ comm_point_send_reply(struct comm_reply *repinfo)
|
|||
#endif
|
||||
if(repinfo->c->tcp_req_info) {
|
||||
tcp_req_info_send_reply(repinfo->c->tcp_req_info);
|
||||
} else if(repinfo->c->alpn_h2) {
|
||||
if(!http2_submit_dns_response(repinfo->c->h2_session)) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
return;
|
||||
}
|
||||
repinfo->c->h2_stream = NULL;
|
||||
repinfo->c->tcp_is_reading = 0;
|
||||
comm_point_stop_listening(repinfo->c);
|
||||
comm_point_start_listening(repinfo->c, -1,
|
||||
repinfo->c->tcp_timeout_msec);
|
||||
return;
|
||||
} else {
|
||||
comm_point_start_listening(repinfo->c, -1,
|
||||
repinfo->c->tcp_timeout_msec);
|
||||
|
|
@ -3179,6 +3684,16 @@ comm_point_drop_reply(struct comm_reply* repinfo)
|
|||
return;
|
||||
if(repinfo->c->tcp_req_info)
|
||||
repinfo->c->tcp_req_info->is_drop = 1;
|
||||
if(repinfo->c->type == comm_http) {
|
||||
if(repinfo->c->h2_session) {
|
||||
repinfo->c->h2_session->is_drop = 1;
|
||||
if(!repinfo->c->h2_session->postpone_drop)
|
||||
reclaim_http_handler(repinfo->c);
|
||||
return;
|
||||
}
|
||||
reclaim_http_handler(repinfo->c);
|
||||
return;
|
||||
}
|
||||
reclaim_tcp_handler(repinfo->c);
|
||||
}
|
||||
|
||||
|
|
|
|||
135
util/netevent.h
135
util/netevent.h
|
|
@ -61,6 +61,9 @@
|
|||
#define NET_EVENT_H
|
||||
|
||||
#include "dnscrypt/dnscrypt.h"
|
||||
#ifdef HAVE_NGHTTP2_NGHTTP2_H
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#endif
|
||||
|
||||
struct sldns_buffer;
|
||||
struct comm_point;
|
||||
|
|
@ -68,11 +71,16 @@ struct comm_reply;
|
|||
struct tcl_list;
|
||||
struct ub_event_base;
|
||||
|
||||
struct mesh_state;
|
||||
struct mesh_area;
|
||||
|
||||
/* internal event notification data storage structure. */
|
||||
struct internal_event;
|
||||
struct internal_base;
|
||||
struct internal_timer; /* A sub struct of the comm_timer super struct */
|
||||
|
||||
enum listen_type;
|
||||
|
||||
/** callback from communication point function type */
|
||||
typedef int comm_point_callback_type(struct comm_point*, void*, int,
|
||||
struct comm_reply*);
|
||||
|
|
@ -205,6 +213,13 @@ struct comm_point {
|
|||
} ssl_shake_state;
|
||||
|
||||
/* -------- HTTP ------- */
|
||||
/** Do not allow connection to use HTTP version lower than this. 0=no
|
||||
* minimum. */
|
||||
enum {
|
||||
http_version_none = 0,
|
||||
http_version_2 = 2
|
||||
} http_min_version;
|
||||
/* -------- HTTP/1.1 ------- */
|
||||
/** Currently reading in http headers */
|
||||
int http_in_headers;
|
||||
/** Currently reading in chunk headers, 0=not, 1=firstline, 2=unused
|
||||
|
|
@ -216,6 +231,15 @@ struct comm_point {
|
|||
struct sldns_buffer* http_temp;
|
||||
/** http stored content in buffer */
|
||||
size_t http_stored;
|
||||
/* -------- HTTP/2 ------- */
|
||||
/** http2 session */
|
||||
struct http2_session* h2_session;
|
||||
/** set to 1 if h2 is negatiated using alpn */
|
||||
int alpn_h2;
|
||||
/** maximum allowed query buffer size */
|
||||
size_t http2_max_qbuffer_size;
|
||||
/** stream currently being handled */
|
||||
struct http2_stream* h2_stream;
|
||||
|
||||
/* -------- dnstap ------- */
|
||||
/** the dnstap environment */
|
||||
|
|
@ -456,10 +480,13 @@ struct comm_point* comm_point_create_udp_ancil(struct comm_base* base,
|
|||
* @param num: becomes max_tcp_count, the routine allocates that
|
||||
* many tcp handler commpoints.
|
||||
* @param idle_timeout: TCP idle timeout in ms.
|
||||
* @param harden_large_queries: whether query size should be limited.
|
||||
* @param tcp_conn_limit: TCP connection limit info.
|
||||
* @param bufsize: size of buffer to create for handlers.
|
||||
* @param spoolbuf: shared spool buffer for tcp_req_info structures.
|
||||
* or NULL to not create those structures in the tcp handlers.
|
||||
* @param port_type: the type of port we are creating a TCP listener for. Used
|
||||
* to select handler type to use.
|
||||
* @param callback: callback function pointer for TCP handlers.
|
||||
* @param callback_arg: will be passed to your callback function.
|
||||
* @return: returns the TCP listener commpoint. You can find the
|
||||
|
|
@ -468,8 +495,10 @@ struct comm_point* comm_point_create_udp_ancil(struct comm_base* base,
|
|||
* Inits timeout to NULL. All handlers are on the free list.
|
||||
*/
|
||||
struct comm_point* comm_point_create_tcp(struct comm_base* base,
|
||||
int fd, int num, int idle_timeout, struct tcl_list* tcp_conn_limit,
|
||||
int fd, int num, int idle_timeout, int harden_large_queries,
|
||||
struct tcl_list* tcp_conn_limit,
|
||||
size_t bufsize, struct sldns_buffer* spoolbuf,
|
||||
enum listen_type port_type,
|
||||
comm_point_callback_type* callback, void* callback_arg);
|
||||
|
||||
/**
|
||||
|
|
@ -723,6 +752,110 @@ void comm_point_tcp_handle_callback(int fd, short event, void* arg);
|
|||
*/
|
||||
void comm_point_http_handle_callback(int fd, short event, void* arg);
|
||||
|
||||
/**
|
||||
* HTTP2 session. HTTP2 related info per comm point.
|
||||
*/
|
||||
struct http2_session {
|
||||
/** first item in list of streams */
|
||||
struct http2_stream* first_stream;
|
||||
#ifdef HAVE_NGHTTP2
|
||||
/** nghttp2 session */
|
||||
nghttp2_session *session;
|
||||
/** store nghttp2 callbacks for easy reuse */
|
||||
nghttp2_session_callbacks* callbacks;
|
||||
#endif
|
||||
/** comm point containing buffer used to build answer in worker or
|
||||
* module */
|
||||
struct comm_point* c;
|
||||
/** session is instructed to get dropped (comm port will be closed) */
|
||||
int is_drop;
|
||||
/** postpone dropping the session, can be used to prevent dropping
|
||||
* while being in a callback */
|
||||
int postpone_drop;
|
||||
};
|
||||
|
||||
/** enum of HTTP status */
|
||||
enum http_status {
|
||||
HTTP_STATUS_OK = 200,
|
||||
HTTP_STATUS_BAD_REQUEST = 400,
|
||||
HTTP_STATUS_NOT_FOUND = 404,
|
||||
HTTP_STATUS_PAYLOAD_TOO_LARGE = 413,
|
||||
HTTP_STATUS_URI_TOO_LONG = 414,
|
||||
HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE = 415,
|
||||
HTTP_STATUS_NOT_IMPLEMENTED = 501
|
||||
};
|
||||
|
||||
/**
|
||||
* HTTP stream. Part of list of HTTP2 streams per session.
|
||||
*/
|
||||
struct http2_stream {
|
||||
/** next stream in list per session */
|
||||
struct http2_stream* next;
|
||||
/** previous stream in list per session */
|
||||
struct http2_stream* prev;
|
||||
/** HTTP2 stream ID is an unsigned 31-bit integer */
|
||||
int32_t stream_id;
|
||||
/** HTTP method used for this stream */
|
||||
enum {
|
||||
HTTP_METHOD_POST = 1,
|
||||
HTTP_METHOD_GET,
|
||||
HTTP_METHOD_UNSUPPORTED
|
||||
} http_method;
|
||||
/** message contains invalid content type */
|
||||
int invalid_content_type;
|
||||
/** message body content type */
|
||||
size_t content_length;
|
||||
/** HTTP response status */
|
||||
enum http_status status;
|
||||
/** request for non existing endpoint */
|
||||
int invalid_endpoint;
|
||||
/** query in request is too large */
|
||||
int query_too_large;
|
||||
/** buffer to store query into. Can't use session shared buffer as query
|
||||
* can arrive in parts, intertwined with frames for other queries. */
|
||||
struct sldns_buffer* qbuffer;
|
||||
/** buffer to store response into. Can't use shared buffer as a next
|
||||
* query read callback can overwrite it before it is send out. */
|
||||
struct sldns_buffer* rbuffer;
|
||||
/** mesh area containing mesh state */
|
||||
struct mesh_area* mesh;
|
||||
/** mesh state for query. Used to remove mesh reply before closing
|
||||
* stream. */
|
||||
struct mesh_state* mesh_state;
|
||||
};
|
||||
|
||||
#ifdef HAVE_NGHTTP2
|
||||
/** nghttp2 receive cb. Read from SSL connection into nghttp2 buffer */
|
||||
ssize_t http2_recv_cb(nghttp2_session* session, uint8_t* buf,
|
||||
size_t len, int flags, void* cb_arg);
|
||||
/** nghttp2 send callback. Send from nghttp2 buffer to ssl socket */
|
||||
ssize_t http2_send_cb(nghttp2_session* session, const uint8_t* buf,
|
||||
size_t len, int flags, void* cb_arg);
|
||||
/** nghttp2 callback on closing stream */
|
||||
int http2_stream_close_cb(nghttp2_session* session, int32_t stream_id,
|
||||
uint32_t error_code, void* cb_arg);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Create new http2 stream
|
||||
* @param stream_id: ID for stream to create.
|
||||
* @return malloc'ed stream, NULL on error
|
||||
*/
|
||||
struct http2_stream* http2_stream_create(int32_t stream_id);
|
||||
|
||||
/**
|
||||
* Add new stream to session linked list
|
||||
* @param h2_session: http2 session to add stream to
|
||||
* @param h2_stream: stream to add to session list
|
||||
*/
|
||||
void http2_session_add_stream(struct http2_session* h2_session,
|
||||
struct http2_stream* h2_stream);
|
||||
|
||||
/** Add mesh state to stream. To be able to remove mesh reply on stream closure
|
||||
*/
|
||||
void http2_stream_add_meshstate(struct http2_stream* h2_stream,
|
||||
struct mesh_area* mesh, struct mesh_state* m);
|
||||
|
||||
/**
|
||||
* This routine is published for checks and tests, and is only used internally.
|
||||
* handle libevent callback for timer comm.
|
||||
|
|
|
|||
Loading…
Reference in a new issue