2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 05:28:00 +00:00

1879. [func] Added framework for handling multiple EDNS versions.

1878.   [func]          dig can now specify the EDNS version when making
                        a query.
This commit is contained in:
Mark Andrews 2005-06-07 00:16:01 +00:00
parent e37806ea92
commit 1fc4793844
9 changed files with 109 additions and 35 deletions

View File

@ -1,3 +1,8 @@
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

View File

@ -15,7 +15,7 @@
* 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 */
@ -192,6 +192,7 @@ help(void) {
" +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"
@ -854,6 +855,8 @@ plus_option(char *option, isc_boolean_t is_batchfile,
break;
case 'n': /* dnssec */
FULLCHECK("dnssec");
if (state && lookup->edns == -1)
lookup->edns = 0;
lookup->dnssec = state;
break;
case 'o': /* domain */
@ -869,6 +872,16 @@ plus_option(char *option, isc_boolean_t is_batchfile,
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;

View File

@ -18,7 +18,7 @@
- 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>
@ -695,15 +695,26 @@
<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>

View File

@ -15,7 +15,7 @@
* 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
@ -702,6 +702,7 @@ make_empty_lookup(void) {
#endif
#endif
looknew->udpsize = 0;
looknew->edns = -1;
looknew->recurse = ISC_TRUE;
looknew->aaonly = ISC_FALSE;
looknew->adflag = ISC_FALSE;
@ -778,6 +779,7 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
#endif
#endif
looknew->udpsize = lookold->udpsize;
looknew->edns = lookold->edns;
looknew->recurse = lookold->recurse;
looknew->aaonly = lookold->aaonly;
looknew->adflag = lookold->adflag;
@ -1085,7 +1087,9 @@ setup_libs(void) {
* 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;
@ -1104,9 +1108,9 @@ add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_boolean_t dnssec) {
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);
@ -1829,10 +1833,13 @@ setup_lookup(dig_lookup_t *lookup) {
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,

View File

@ -15,7 +15,7 @@
* 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
@ -180,6 +180,7 @@ isc_boolean_t sigchase;
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];

View File

@ -15,7 +15,7 @@
* 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>
@ -574,6 +574,7 @@ ns_client_endrequest(ns_client_t *client) {
client->udpsize = 512;
client->extflags = 0;
client->ednsversion = -1;
dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE);
if (client->recursionquota != NULL)
@ -1363,8 +1364,6 @@ client_request(isc_task_t *task, isc_event_t *event) {
*/
opt = dns_message_getopt(client->message);
if (opt != NULL) {
unsigned int version;
/*
* Set the client's UDP buffer size.
*/
@ -1382,6 +1381,19 @@ client_request(isc_task_t *task, isc_event_t *event) {
*/
client->extflags = (isc_uint16_t)(opt->ttl & 0xFFFF);
/*
* Do we understand this version of EDNS?
*
* XXXRTH need library support for this!
*/
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;
}
/*
* Create an OPT for our reply.
*/
@ -1390,17 +1402,6 @@ client_request(isc_task_t *task, isc_event_t *event) {
ns_client_error(client, result);
goto cleanup;
}
/*
* Do we understand this version of ENDS?
*
* XXXRTH need library support for this!
*/
version = (opt->ttl & 0x00FF0000) >> 16;
if (version != 0) {
ns_client_error(client, DNS_R_BADVERS);
goto cleanup;
}
}
if (client->message->rdclass == 0) {
@ -1776,6 +1777,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
client->opt = NULL;
client->udpsize = 512;
client->extflags = 0;
client->ednsversion = -1;
client->next = NULL;
client->shutdown = NULL;
client->shutdown_arg = NULL;

View File

@ -15,7 +15,7 @@
* 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
@ -116,6 +116,7 @@ struct ns_client {
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;

View File

@ -15,7 +15,7 @@
* 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
@ -91,6 +91,10 @@ typedef struct dns_fetchevent {
#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()).

View File

@ -15,7 +15,7 @@
* 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 */
@ -841,7 +841,7 @@ resquery_senddone(isc_task_t *task, isc_event_t *event) {
}
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;
@ -870,9 +870,10 @@ fctx_addopt(dns_message_t *message, dns_resolver_t *res) {
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.
@ -1233,7 +1234,14 @@ resquery_send(resquery_t *query) {
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.
@ -5277,6 +5285,28 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
* 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.