From: Ian Jackson Date: Sun, 12 Oct 2014 21:03:43 +0000 (+0100) Subject: Reentrancy: Avoid reentrant callbacks X-Git-Tag: wip.ipv6.2014-10-13.compare-old~2 X-Git-Url: https://git.distorted.org.uk/~mdw/adns/commitdiff_plain/78504252c3eef8561d82837612fcd081d24122b9?hp=78504252c3eef8561d82837612fcd081d24122b9 Reentrancy: Avoid reentrant callbacks 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 ---