Queries and responses "serialized" when using forwarder

Hi,

I've noticed that when I set forwarder in unbound or libunbound (via
forward-zone or ub_ctx_resolvconf, respectively), the resolution seems
to be always serialized, no matter what settings of *-slabs, threads or
target-fetch-policy is (i.e. "nicely" alternating query-response).
Without forwarder, requests seem to be parallelized, at least to some
extent.

I couldn't find any explanation for this behavior in documentation, RFCs
or googling.

For example, resolving A record of addons.mozilla.org using forwarder
looks like (latest unbound 1.4.16, empty cache):

No. Time Info
   5 0.731801 Standard query A addons.mozilla.org
   6 0.921957 Standard query response A 63.245.217.112 RRSIG
   7 0.922192 Standard query DNSKEY <Root>
   8 0.922689 Standard query response DNSKEY DNSKEY RRSIG
   9 0.923067 Standard query DS org
  10 0.956492 Standard query response DS DS RRSIG
  11 0.957263 Standard query DNSKEY org
  12 0.957761 Standard query response DNSKEY DNSKEY DNSKEY DNSKEY RRSIG
RRSIG
  13 0.957945 Standard query DS mozilla.org
  14 0.958194 Standard query response DS RRSIG
  15 0.958298 Standard query DNSKEY mozilla.org
  16 1.045979 Standard query response DNSKEY DNSKEY DNSKEY RRSIG RRSIG

For example, after retrieving response for "IN A addons.mozilla.org" we
know which zone to ask for DS and DNSKEY and could ask for DS and DNSKEY
for root, org and mozilla.org in parallel. Would that be against some
RFC, best practices or it's just not implemented for some other reason
(like me overlooking a reason why it wouldn't work in a general case)?

Why I am asking: on a slow line (e.g. mobile phone, Tor) the number of
necessary round-trips makes quite a difference.

Related question:
Suppose I'd want to work around this by hacking libunbound a bit -
client sends "IN A addons.mozilla.org" and receives all the necessary
packets for validation in the usual DNS format as if client's cache was
empty (DS a DNSKEY for root, org, mozilla.org).

One obvious issue is size: with a CDN that chains via CNAME/DNAME
through multiple zones, the response can be rather big.

Size aside, is there other issue that can make the implementation
difficult to do correctly? I've seen Adam Langley's DNSSEC-stapling
draft, but that's more complex since it tries to adress more issues at once.

Ondrej

Hi Ondrej,

Unbound is capable of working on multiple queries at the same time.
There is no real limit from the software point, but there is CPU load
and number of network sockets to consider. This is like a couple
thousand for an ISP-resolver. A local resolver, more like tens or
hundred, from a practical perspective.

Hi,

I've noticed that when I set forwarder in unbound or libunbound
(via forward-zone or ub_ctx_resolvconf, respectively), the
resolution seems to be always serialized, no matter what settings
of *-slabs, threads or target-fetch-policy is (i.e. "nicely"
alternating query-response). Without forwarder, requests seem to be
parallelized, at least to some extent.

There must be something else going on, that make it serialized.

I couldn't find any explanation for this behavior in documentation,
RFCs or googling.

That is because it is explicitly supported, you need no special
config, on thread is enough, all defaults would work. Just perform
multiple queries via the asynchronous interface. And they are done at
the same time. (you can do the config you talk about, this just
increases the resources that unbound has).

For example, resolving A record of addons.mozilla.org using
forwarder looks like (latest unbound 1.4.16, empty cache):

No. Time Info 5 0.731801 Standard query A addons.mozilla.org
6 0.921957 Standard query response A 63.245.217.112 RRSIG 7
0.922192 Standard query DNSKEY <Root> 8 0.922689 Standard query
response DNSKEY DNSKEY RRSIG 9 0.923067 Standard query DS org 10
0.956492 Standard query response DS DS RRSIG 11 0.957263 Standard
query DNSKEY org 12 0.957761 Standard query response DNSKEY DNSKEY
DNSKEY DNSKEY RRSIG RRSIG 13 0.957945 Standard query DS
mozilla.org 14 0.958194 Standard query response DS RRSIG 15
0.958298 Standard query DNSKEY mozilla.org 16 1.045979 Standard
query response DNSKEY DNSKEY DNSKEY RRSIG RRSIG

For example, after retrieving response for "IN A
addons.mozilla.org" we know which zone to ask for DS and DNSKEY and
could ask for DS and DNSKEY for root, org and mozilla.org in
parallel. Would that be against some RFC, best practices or it's
just not implemented for some other reason (like me overlooking a
reason why it wouldn't work in a general case)?

Well, is your code perhaps waiting for the first answer before it asks
the second question (via the libunbound API) ?

Why I am asking: on a slow line (e.g. mobile phone, Tor) the number
of necessary round-trips makes quite a difference.

Related question: Suppose I'd want to work around this by hacking
libunbound a bit - client sends "IN A addons.mozilla.org" and
receives all the necessary packets for validation in the usual DNS
format as if client's cache was empty (DS a DNSKEY for root, org,
mozilla.org).

One obvious issue is size: with a CDN that chains via CNAME/DNAME
through multiple zones, the response can be rather big.

Size aside, is there other issue that can make the implementation
difficult to do correctly? I've seen Adam Langley's
DNSSEC-stapling draft, but that's more complex since it tries to
adress more issues at once.

The things you need to include (also for insecure stuff that has a
chain of trust ending in an NSEC (or NSEC3)), is very complicated.
And the algorithm used by the sender, bottom-up or top-down, can make
it request different items. This for empty-nonterminals in reverse zones.

So this is very difficult. And if you want to validate it you might
need to rewrite the validation routine to a new paradigm.

Best regards,
   Wouter