enum {
adns__qf_senddirect = 0x00100000,/* don't call the `query_send' type hook */
- adns__qf_nosend = 0x00200000 /* don't send the query when submitting */
+ adns__qf_nosend = 0x00200000,/* don't send the query when submitting */
+ adns__qf_addr_answer= 0x01000000,/* addr query received an answer */
+ adns__qf_addr_cnhack= 0x02000000,/* addr query found cname inconsistency */
+ adns__qf_addr_cname = 0x04000000 /* addr subquery performed on cname */
};
/* Shared data structures */
* addr_rrtypes, addr_rrsz)
*/
+/* About CNAME handling in addr queries.
+ *
+ * A user-level addr query is translated into a number of protocol-level
+ * queries, and its job is to reassemble the results. This gets tricky if
+ * the answers aren't consistent. In particular, if the answers report
+ * inconsistent indirection via CNAME records (e.g., different CNAMEs, or
+ * some indirect via a CNAME, and some don't) then we have trouble.
+ *
+ * Once we've received an answer, even if it was NODATA, we set
+ * adns__qf_addr_answer on the parent query. This will let us detect a
+ * conflict between a no-CNAME-with-NODATA reply and a subsequent CNAME.
+ *
+ * If we detect a conflict of any kind, then at least one answer came back
+ * with a CNAME record, so we pick the first such answer (somewhat
+ * arbitrarily) as being the `right' canonical name, and set this in the
+ * parent query's answer->cname slot. We discard address records from the
+ * wrong name. And finally we cancel the outstanding child queries, and
+ * resubmit address queries for the address families we don't yet have, with
+ * adns__qf_addr_cname set so that we know that we're in the fixup state.
+ */
+
static adns_status pap_addr(const parseinfo *pai, int rrty, size_t rrsz,
int *cbyte_io, int max, adns_rr_addr *storeto)
{
adns_status err;
const struct timeval *now = 0;
- /* Must handle CNAMEs correctly. This gets very hairy if the answers we
- * get are inconsistent.
- */
+ if (child->cname || parent->cname) {
+ }
if ((parent->flags & adns_qf_search) &&
cans->status == adns_s_nxdomain) {