chiark / gitweb /
Reentrancy: Avoid reentrant callbacks
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 12 Oct 2014 21:03:43 +0000 (22:03 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 19 Oct 2014 20:09:56 +0000 (21:09 +0100)
Avoid making reentrant callbacks for internal queries during other
processing.

Currently there is a theoretical reentrancy bug in
adns__submit_internal, if the internal query can itself be persuaded
to fail immediately.  The result would be a reentrant call to
callback() for the child query inside functions like typei->parse.

The possibility of such reentrancy is a bug waiting to happen - and
indeed we are going to introduce more complicated query submissions
which are more likely to fail immediately, turning this from a
theoretical to a real bug.

Solve this as follows: when an internal query completes, just put it
on a list.  Whenever we are on our way out of adns, we look through
this list and make the callbacks (until the list is empty).

This means that a fair amount of code needs to be taught that it might
encounter queries in this callback pending state.

We have to update some of the tests' expected output:

Because adns now processes the callback later, a number of the
parallel subqueries made by some of the tests end up finishing before
being cancelled - and therefore the replies to those subqueries don't
show up in the debug output as unrecognised.

Also, in case-norecurse, the deferral of the callback causes the order
of result reporting to be changed: the main query due to subqueries
finishing (`PTR(checked)') ends up later on the results queue than the
other queries dealt with in the same event loop iteration.  (The
actual answer packet to final query, `CNAME(-)', arrives later.)

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>

No differences found