On returning SERVFAIL for too-short EDNS

Hello,

in daemon/worker.c, we have:

  if(edns.edns_present && edns.udp_size < LDNS_HEADER_SIZE) {
    verbose(VERB_ALGO, "worker request: edns is too small.");
    log_addr(VERB_CLIENT, "from", &repinfo->addr, repinfo->addrlen);
    LDNS_QR_SET(ldns_buffer_begin(c->buffer));
    LDNS_TC_SET(ldns_buffer_begin(c->buffer));
    LDNS_RCODE_SET(ldns_buffer_begin(c->buffer),
      LDNS_RCODE_SERVFAIL);
    ldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
    ldns_buffer_write_at(c->buffer, 4,
      (uint8_t*)"\0\0\0\0\0\0\0\0", 8);
    ldns_buffer_flip(c->buffer);
    return 1;
  }

This seems strange, for the following reason. The condition for this
SERVFAIL is entirely user-triggerable. Some DNS forwarders (e.g.,
dnsmasq) count the number of the received SERVFAILs for each configured
upstream server and thus judge about its health. I think (but have not
verified) that there might be unintended interaction of such bad queries
with this health check.

Indeed, SERVFAIL, according to RFC1035, is for problems with the name
server. Here the problem is with the query, not with the name server, so
wouldn't it be more logical to send FORMERR here?

* Alexander E. Patrakov:

This seems strange, for the following reason. The condition for this
SERVFAIL is entirely user-triggerable. Some DNS forwarders (e.g.,
dnsmasq) count the number of the received SERVFAILs for each configured
upstream server and thus judge about its health.

This approach is quite wrong because recursors return SERVFAIL in many
other cases, dependent on the query and upstream answers received and
mostly unrelated to general server health.