Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for selective enabling tcp-upstream for stub/forward zones #519

Merged
merged 1 commit into from
Aug 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions daemon/worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -1988,8 +1988,8 @@ worker_delete(struct worker* worker)
struct outbound_entry*
worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
int want_dnssec, int nocaps, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t* zone, size_t zonelen, int ssl_upstream,
char* tls_auth_name, struct module_qstate* q)
socklen_t addrlen, uint8_t* zone, size_t zonelen, int tcp_upstream,
int ssl_upstream, char* tls_auth_name, struct module_qstate* q)
{
struct worker* worker = q->env->worker;
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
Expand All @@ -1998,7 +1998,7 @@ worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
return NULL;
e->qstate = q;
e->qsent = outnet_serviced_query(worker->back, qinfo, flags, dnssec,
want_dnssec, nocaps, q->env->cfg->tcp_upstream,
want_dnssec, nocaps, tcp_upstream,
ssl_upstream, tls_auth_name, addr, addrlen, zone, zonelen, q,
worker_handle_service_reply, e, worker->back->udp_buff, q->env);
if(!e->qsent) {
Expand Down Expand Up @@ -2045,7 +2045,7 @@ struct outbound_entry* libworker_send_query(
uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec),
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen),
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream),
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
struct module_qstate* ATTR_UNUSED(q))
{
Expand Down
12 changes: 11 additions & 1 deletion doc/unbound.conf.5.in
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,9 @@ advertised timeout.
.TP
.B tcp\-upstream: \fI<yes or no>
Enable or disable whether the upstream queries use TCP only for transport.
Default is no. Useful in tunneling scenarios.
Default is no. Useful in tunneling scenarios. If set to no you can specify
TCP transport only for selected forward or stub zones using forward-tcp-upstream
or stub-tcp-upstream respectively.
.TP
.B udp\-upstream\-without\-downstream: \fI<yes or no>
Enable udp upstream even if do-udp is no. Default is no, and this does not
Expand Down Expand Up @@ -1853,6 +1855,10 @@ Default is no.
.B stub\-ssl\-upstream: \fI<yes or no>
Alternate syntax for \fBstub\-tls\-upstream\fR.
.TP
.B stub\-tcp\-upstream: \fI<yes or no>
If it is set to "yes" then upstream queries use TCP only for transport regardless of global flag tcp-upstream.
Default is no.
.TP
.B stub\-no\-cache: \fI<yes or no>
Default is no. If enabled, data inside the stub is not cached. This is
useful when you want immediate changes to be visible.
Expand Down Expand Up @@ -1905,6 +1911,10 @@ load CA certs, otherwise the connections cannot be authenticated.
.B forward\-ssl\-upstream: \fI<yes or no>
Alternate syntax for \fBforward\-tls\-upstream\fR.
.TP
.B forward\-tcp\-upstream: \fI<yes or no>
If it is set to "yes" then upstream queries use TCP only for transport regardless of global flag tcp-upstream.
Default is no.
.TP
.B forward\-no\-cache: \fI<yes or no>
Default is no. If enabled, data inside the forward is not cached. This is
useful when you want immediate changes to be visible.
Expand Down
1 change: 1 addition & 0 deletions iterator/iter_delegpt.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)
copy->bogus = dp->bogus;
copy->has_parent_side_NS = dp->has_parent_side_NS;
copy->ssl_upstream = dp->ssl_upstream;
copy->tcp_upstream = dp->tcp_upstream;
for(ns = dp->nslist; ns; ns = ns->next) {
if(!delegpt_add_ns(copy, region, ns->name, ns->lame))
return NULL;
Expand Down
2 changes: 2 additions & 0 deletions iterator/iter_delegpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ struct delegpt {
uint8_t dp_type_mlc;
/** use SSL for upstream query */
uint8_t ssl_upstream;
/** use TCP for upstream query */
uint8_t tcp_upstream;
/** delegpt from authoritative zone that is locally hosted */
uint8_t auth_dp;
/*** no cache */
Expand Down
2 changes: 2 additions & 0 deletions iterator/iter_fwd.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ read_forwards(struct iter_forwards* fwd, struct config_file* cfg)
dp->no_cache = s->no_cache;
/* use SSL for queries to this forwarder */
dp->ssl_upstream = (uint8_t)s->ssl_upstream;
/* use TCP for queries to this forwarder */
dp->tcp_upstream = (uint8_t)s->tcp_upstream;
verbose(VERB_QUERY, "Forward zone server list:");
delegpt_log(VERB_QUERY, dp);
if(!forwards_insert(fwd, LDNS_RR_CLASS_IN, dp))
Expand Down
2 changes: 2 additions & 0 deletions iterator/iter_hints.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@ read_stubs(struct iter_hints* hints, struct config_file* cfg)
dp->no_cache = s->no_cache;
/* ssl_upstream */
dp->ssl_upstream = (uint8_t)s->ssl_upstream;
/* tcp_upstream */
dp->tcp_upstream = (uint8_t)s->tcp_upstream;
delegpt_log(VERB_QUERY, dp);
if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp, !s->isprime))
return 0;
Expand Down
1 change: 1 addition & 0 deletions iterator/iterator.c
Original file line number Diff line number Diff line change
Expand Up @@ -2666,6 +2666,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
ie, iq), &target->addr, target->addrlen,
iq->dp->name, iq->dp->namelen,
(iq->dp->tcp_upstream || qstate->env->cfg->tcp_upstream),
(iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream),
target->tls_auth_name, qstate);
if(!outq) {
Expand Down
6 changes: 3 additions & 3 deletions libunbound/libworker.c
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,7 @@ void libworker_alloc_cleanup(void* arg)
struct outbound_entry* libworker_send_query(struct query_info* qinfo,
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
size_t zonelen, int ssl_upstream, char* tls_auth_name,
size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
struct module_qstate* q)
{
struct libworker* w = (struct libworker*)q->env->worker;
Expand All @@ -891,7 +891,7 @@ struct outbound_entry* libworker_send_query(struct query_info* qinfo,
return NULL;
e->qstate = q;
e->qsent = outnet_serviced_query(w->back, qinfo, flags, dnssec,
want_dnssec, nocaps, q->env->cfg->tcp_upstream, ssl_upstream,
want_dnssec, nocaps, tcp_upstream, ssl_upstream,
tls_auth_name, addr, addrlen, zone, zonelen, q,
libworker_handle_service_reply, e, w->back->udp_buff, q->env);
if(!e->qsent) {
Expand Down Expand Up @@ -975,7 +975,7 @@ struct outbound_entry* worker_send_query(struct query_info* ATTR_UNUSED(qinfo),
uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec),
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen),
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream),
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
struct module_qstate* ATTR_UNUSED(q))
{
Expand Down
4 changes: 2 additions & 2 deletions libunbound/worker.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ struct query_info;
struct outbound_entry* libworker_send_query(struct query_info* qinfo,
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
size_t zonelen, int ssl_upstream, char* tls_auth_name,
size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
struct module_qstate* q);

/** process incoming serviced query replies from the network */
Expand Down Expand Up @@ -123,7 +123,7 @@ void worker_sighandler(int sig, void* arg);
struct outbound_entry* worker_send_query(struct query_info* qinfo,
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
size_t zonelen, int ssl_upstream, char* tls_auth_name,
size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
struct module_qstate* q);

/**
Expand Down
4 changes: 2 additions & 2 deletions smallapp/worker_cb.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ struct outbound_entry* worker_send_query(
int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream),
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream),
char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q))
{
log_assert(0);
Expand Down Expand Up @@ -131,7 +131,7 @@ struct outbound_entry* libworker_send_query(
int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream),
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream),
char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q))
{
log_assert(0);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
server:
verbosity: 5
# num-threads: 1
interface: 127.0.0.1
port: @PORT@
use-syslog: no
directory: ""
pidfile: "unbound.pid"
chroot: ""
username: ""
do-not-query-localhost: no
forward-zone:
name: "tcp.example.com"
forward-addr: "127.0.0.1@@TOPORT@"
forward-tcp-upstream: "yes"
forward-zone:
name: "udp.example.com"
forward-addr: "127.0.0.1@@TOPORT@"
forward-tcp-upstream: "no"

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
BaseName: fwd_udp_with_tcp_upstream
Version: 1.0
Description: Forward an UDP packet to upstream via TCP and return reply.
CreationDate: Thu Aug 5 07:44:41 CEST 2021
Maintainer: ziollek
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: fwd_udp_with_tcp_upstream.pre
Post: fwd_udp_with_tcp_upstream.post
Test: fwd_udp_with_tcp_upstream.test
AuxFiles:
Passed:
Failure:
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# #-- fwd_udp_with_tcp_upstream.post --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# source the test var file when it's there
[ -f .tpkg.var.test ] && source .tpkg.var.test
#
# do your teardown here
. ../common.sh
kill_pid $FWD_PID
kill_pid $UNBOUND_PID
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# #-- fwd_udp_with_tcp_upstream.pre--#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test

. ../common.sh
get_random_port 2
UNBOUND_PORT=$RND_PORT
FWD_PORT=$(($RND_PORT + 1))
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test

# start forwarder
get_ldns_testns
$LDNS_TESTNS -p $FWD_PORT fwd_udp_with_tcp_upstream.testns >fwd.log 2>&1 &
FWD_PID=$!
echo "FWD_PID=$FWD_PID" >> .tpkg.var.test

# make config file
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' < fwd_udp_with_tcp_upstream.conf > ub.conf
# start unbound in the background
PRE="../.."
$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
UNBOUND_PID=$!
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test

cat .tpkg.var.test
wait_ldns_testns_up fwd.log
wait_unbound_up unbound.log

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# #-- fwd_udp_with_tcp_upstream.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test

PRE="../.."
# do the test
echo "> dig tcp.example.com."
dig @localhost -p $UNBOUND_PORT tcp.example.com. | tee outfile
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "> check answer"
if grep "10.20.30.40" outfile; then
echo "OK"
else
echo "Not OK"
exit 1
fi

echo "> dig udp.example.com."
dig @localhost -p $UNBOUND_PORT udp.example.com. | tee outfile
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "> check answer"
if grep "10.20.30.80" outfile; then
echo "OK"
else
echo "Not OK"
exit 1
fi

exit 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
; nameserver test file
$ORIGIN example.com.
$TTL 3600

ENTRY_BEGIN
MATCH opcode qtype qname
MATCH TCP
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
tcp IN A
SECTION ANSWER
tcp IN A 10.20.30.40
ENTRY_END

ENTRY_BEGIN
MATCH opcode qtype qname
MATCH UDP
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
udp IN A
SECTION ANSWER
udp IN A 10.20.30.80
ENTRY_END
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
server:
verbosity: 2
# num-threads: 1
interface: 127.0.0.1
port: @PORT@
use-syslog: no
directory: ""
pidfile: "unbound.pid"
chroot: ""
username: ""
do-not-query-localhost: no
stub-zone:
name: "tcp.example.com"
stub-addr: "127.0.0.1@@TOPORT@"
stub-tcp-upstream: "yes"
stub-zone:
name: "udp.example.com"
stub-addr: "127.0.0.1@@TOPORT@"
stub-tcp-upstream: "no"
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
BaseName: stub_udp_with_tcp_upstream
Version: 1.0
Description: Stub server contacted via UDP with tcp upstream.
CreationDate: Thu Aug 5 07:44:41 CEST 2021
Maintainer: ziollek
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: stub_udp_with_tcp_upstream.pre
Post: stub_udp_with_tcp_upstream.post
Test: stub_udp_with_tcp_upstream.test
AuxFiles:
Passed:
Failure:
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# #-- stub_udp_with_tcp_upstream.post --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# source the test var file when it's there
[ -f .tpkg.var.test ] && source .tpkg.var.test
#
# do your teardown here
. ../common.sh
kill_pid $FWD_PID
kill_pid $UNBOUND_PID
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# #-- stub_udp_with_tcp_upstream.pre--#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
. ../common.sh

get_random_port 2
UNBOUND_PORT=$RND_PORT
FWD_PORT=$(($RND_PORT + 1))
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test

# start forwarder
get_ldns_testns
$LDNS_TESTNS -p $FWD_PORT stub_udp_with_tcp_upstream.testns >fwd.log 2>&1 &
FWD_PID=$!
echo "FWD_PID=$FWD_PID" >> .tpkg.var.test

# make config file
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' < stub_udp_with_tcp_upstream.conf > ub.conf
# start unbound in the background
PRE="../.."
$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
UNBOUND_PID=$!
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test

cat .tpkg.var.test

# wait for forwarder to come up
wait_ldns_testns_up fwd.log

# wait for unbound to come up
wait_unbound_up unbound.log

Loading