+1879. [func] Added framework for handling multiple EDNS versions.
+
+1878. [func] dig can now specify the EDNS version when making
+ a query.
+
1868. [placeholder] rt14851
1867. [placeholder] rt14846
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dig.c,v 1.203 2005/04/27 04:55:44 sra Exp $ */
+/* $Id: dig.c,v 1.204 2005/06/07 00:15:58 marka Exp $ */
/*! \file */
" +domain=### (Set default domainname)\n"
" +bufsize=### (Set EDNS0 Max UDP packet size)\n"
" +ndots=### (Set NDOTS value)\n"
+" +edns=### (Set EDNS version)\n"
" +[no]search (Set whether to use searchlist)\n"
" +[no]defname (Ditto)\n"
" +[no]recurse (Recursive mode)\n"
break;
case 'n': /* dnssec */
FULLCHECK("dnssec");
+ if (state && lookup->edns == -1)
+ lookup->edns = 0;
lookup->dnssec = state;
break;
case 'o': /* domain */
goto invalid_option;
}
break;
+ case 'e':
+ FULLCHECK("edns");
+ if (!state) {
+ lookup->edns = -1;
+ break;
+ }
+ if (value == NULL)
+ goto need_value;
+ lookup->edns = (isc_int16_t) parse_uint(value, "edns", 255);
+ break;
case 'f': /* fail */
FULLCHECK("fail");
lookup->servfail_stops = state;
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dig.docbook,v 1.22 2005/05/13 01:35:38 marka Exp $ -->
+<!-- $Id: dig.docbook,v 1.23 2005/06/07 00:15:58 marka Exp $ -->
<refentry>
<refentryinfo>
<listitem>
<para>
Set the UDP message buffer size advertised using EDNS0 to
- <parameter>B</parameter> bytes. The maximum and
- minimum sizes of this
- buffer are 65535 and 0 respectively. Values outside this range
- are
- rounded up or down appropriately.
+ <parameter>B</parameter> bytes. The maximum and minimum sizes
+ of this buffer are 65535 and 0 respectively. Values outside
+ this range are rounded up or down appropriately.
+ Values other than zero will cause a EDNS query to be sent.
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>+edns=#</option></term>
+ <listitem>
+ <para>
+ Specify the EDNS version to query with. Valid values
+ are 0 to 255. Setting the EDNS version will cause a
+ EDNS query to be sent. <option>+noedns</option> clears the
+ remembered EDNS version.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>+[no]multiline</option></term>
<listitem>
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dighost.c,v 1.276 2005/06/01 01:56:49 marka Exp $ */
+/* $Id: dighost.c,v 1.277 2005/06/07 00:15:58 marka Exp $ */
/*! \file
* \note
#endif
#endif
looknew->udpsize = 0;
+ looknew->edns = -1;
looknew->recurse = ISC_TRUE;
looknew->aaonly = ISC_FALSE;
looknew->adflag = ISC_FALSE;
#endif
#endif
looknew->udpsize = lookold->udpsize;
+ looknew->edns = lookold->edns;
looknew->recurse = lookold->recurse;
looknew->aaonly = lookold->aaonly;
looknew->adflag = lookold->adflag;
* options are UDP buffer size and the DO bit.
*/
static void
-add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_boolean_t dnssec) {
+add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_uint16_t edns,
+ isc_boolean_t dnssec)
+{
dns_rdataset_t *rdataset = NULL;
dns_rdatalist_t *rdatalist = NULL;
dns_rdata_t *rdata = NULL;
rdatalist->type = dns_rdatatype_opt;
rdatalist->covers = 0;
rdatalist->rdclass = udpsize;
- rdatalist->ttl = 0;
+ rdatalist->ttl = edns << 16;
if (dnssec)
- rdatalist->ttl = DNS_MESSAGEEXTFLAG_DO;
+ rdatalist->ttl |= DNS_MESSAGEEXTFLAG_DO;
rdata->data = NULL;
rdata->length = 0;
ISC_LIST_INIT(rdatalist->rdata);
result = dns_message_renderbegin(lookup->sendmsg, &cctx,
&lookup->sendbuf);
check_result(result, "dns_message_renderbegin");
- if (lookup->udpsize > 0 || lookup->dnssec) {
+ if (lookup->udpsize > 0 || lookup->dnssec || lookup->edns > -1) {
if (lookup->udpsize == 0)
lookup->udpsize = 2048;
- add_opt(lookup->sendmsg, lookup->udpsize, lookup->dnssec);
+ if (lookup->edns < 0)
+ lookup->edns = 0;
+ add_opt(lookup->sendmsg, lookup->udpsize,
+ lookup->edns, lookup->dnssec);
}
result = dns_message_rendersection(lookup->sendmsg,
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dig.h,v 1.91 2005/04/27 04:55:45 sra Exp $ */
+/* $Id: dig.h,v 1.92 2005/06/07 00:15:59 marka Exp $ */
#ifndef DIG_H
#define DIG_H
isc_uint32_t retries;
int nsfound;
isc_uint16_t udpsize;
+ isc_int16_t edns;
isc_uint32_t ixfr_serial;
isc_buffer_t rdatabuf;
char rdatastore[MXNAME];
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: client.c,v 1.227 2005/06/04 05:32:46 jinmei Exp $ */
+/* $Id: client.c,v 1.228 2005/06/07 00:15:59 marka Exp $ */
#include <config.h>
client->udpsize = 512;
client->extflags = 0;
+ client->ednsversion = -1;
dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE);
if (client->recursionquota != NULL)
*/
opt = dns_message_getopt(client->message);
if (opt != NULL) {
- unsigned int version;
-
/*
* Set the client's UDP buffer size.
*/
client->extflags = (isc_uint16_t)(opt->ttl & 0xFFFF);
/*
- * Create an OPT for our reply.
+ * Do we understand this version of EDNS?
+ *
+ * XXXRTH need library support for this!
*/
- result = client_addopt(client);
- if (result != ISC_R_SUCCESS) {
+ client->ednsversion = (opt->ttl & 0x00FF0000) >> 16;
+ if (client->ednsversion > 0) {
+ result = client_addopt(client);
+ if (result == ISC_R_SUCCESS)
+ result = DNS_R_BADVERS;
ns_client_error(client, result);
goto cleanup;
}
-
/*
- * Do we understand this version of ENDS?
- *
- * XXXRTH need library support for this!
+ * Create an OPT for our reply.
*/
- version = (opt->ttl & 0x00FF0000) >> 16;
- if (version != 0) {
- ns_client_error(client, DNS_R_BADVERS);
+ result = client_addopt(client);
+ if (result != ISC_R_SUCCESS) {
+ ns_client_error(client, result);
goto cleanup;
}
}
client->opt = NULL;
client->udpsize = 512;
client->extflags = 0;
+ client->ednsversion = -1;
client->next = NULL;
client->shutdown = NULL;
client->shutdown_arg = NULL;
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: client.h,v 1.73 2005/04/27 04:55:56 sra Exp $ */
+/* $Id: client.h,v 1.74 2005/06/07 00:16:00 marka Exp $ */
#ifndef NAMED_CLIENT_H
#define NAMED_CLIENT_H 1
dns_rdataset_t * opt;
isc_uint16_t udpsize;
isc_uint16_t extflags;
+ isc_int16_t ednsversion; /* -1 noedns */
void (*next)(ns_client_t *);
void (*shutdown)(void *arg, isc_result_t result);
void *shutdown_arg;
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.h,v 1.44 2005/04/27 04:56:59 sra Exp $ */
+/* $Id: resolver.h,v 1.45 2005/06/07 00:16:01 marka Exp $ */
#ifndef DNS_RESOLVER_H
#define DNS_RESOLVER_H 1
#define DNS_FETCHOPT_FORWARDONLY 0x10 /*%< Only use forwarders. */
#define DNS_FETCHOPT_NOVALIDATE 0x20 /*%< Disable validation. */
+#define DNS_FETCHOPT_EDNSVERSIONSET 0x00800000
+#define DNS_FETCHOPT_EDNSVERSIONMASK 0xff000000
+#define DNS_FETCHOPT_EDNSVERSIONSHIFT 24
+
/*
* XXXRTH Should this API be made semi-private? (I.e.
* _dns_resolver_create()).
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.c,v 1.308 2005/06/04 05:32:47 jinmei Exp $ */
+/* $Id: resolver.c,v 1.309 2005/06/07 00:16:00 marka Exp $ */
/*! \file */
}
static inline isc_result_t
-fctx_addopt(dns_message_t *message, dns_resolver_t *res) {
+fctx_addopt(dns_message_t *message, unsigned int version, dns_resolver_t *res) {
dns_rdataset_t *rdataset;
dns_rdatalist_t *rdatalist;
dns_rdata_t *rdata;
rdatalist->rdclass = res->udpsize;
/*
- * Set EXTENDED-RCODE, VERSION, and Z to 0, and the DO bit to 1.
+ * Set EXTENDED-RCODE and Z to 0, DO to 1.
*/
- rdatalist->ttl = DNS_MESSAGEEXTFLAG_DO;
+ rdatalist->ttl = (version << 16);
+ rdatalist->ttl |= DNS_MESSAGEEXTFLAG_DO;
/*
* No EDNS options.
if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0) {
- result = fctx_addopt(fctx->qmessage, res);
+ unsigned int version = 0; /* Default version. */
+ unsigned int flags;
+ flags = query->addrinfo->flags;
+ if ((flags & DNS_FETCHOPT_EDNSVERSIONSET) != 0) {
+ version = flags & DNS_FETCHOPT_EDNSVERSIONMASK;
+ version >>= DNS_FETCHOPT_EDNSVERSIONSHIFT;
+ }
+ result = fctx_addopt(fctx->qmessage, version, res);
if (result != ISC_R_SUCCESS) {
/*
* We couldn't add the OPT, but we'll press on.
* for this fetch.
*/
result = DNS_R_YXDOMAIN;
+ } else if (message->rcode == dns_rcode_badvers) {
+ dns_rdataset_t *opt;
+ unsigned int flags, mask;
+ unsigned int version;
+
+ resend = ISC_TRUE;
+ opt = dns_message_getopt(message);
+ version = (opt->ttl >> 16) & 0xff;
+ flags = (version << DNS_FETCHOPT_EDNSVERSIONSHIFT) |
+ DNS_FETCHOPT_EDNSVERSIONSET;
+ mask = DNS_FETCHOPT_EDNSVERSIONMASK |
+ DNS_FETCHOPT_EDNSVERSIONSET;
+ switch (version) {
+ case 0:
+ dns_adb_changeflags(fctx->adb, query->addrinfo,
+ flags, mask);
+ break;
+ default:
+ broken_server = DNS_R_BADVERS;
+ keep_trying = ISC_TRUE;
+ break;
+ }
} else {
/*
* XXXRTH log.