Commit dc570b92 authored by Michael Sawyer's avatar Michael Sawyer

Add support for proposed ZONE and VIEW opt attributes. These are currently

hidden behind #ifdef's, since no OPT code number has yet to be assigned
by the IANA.  They are also not quite complete in all regards; VIEW
options are understood and ignored.  ZONE options are understood and
acted upon, though some of the error cases aren't quite right.

Remove doubled isc_mem_stats in dighost.c

Update todo list.

Change literal 255's to DNS_NAME_MAXWIRE in name.c
parent c7294f9c
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dig.c,v 1.110 2000/10/03 04:29:08 marka Exp $ */
/* $Id: dig.c,v 1.111 2000/10/11 17:44:00 mws Exp $ */
#include <config.h>
#include <stdlib.h>
......@@ -828,10 +828,33 @@ plus_option(char *option, isc_boolean_t is_batchfile,
goto invalid_option;
}
break;
case 'v': /* vc */
if (!is_batchfile)
lookup->tcp_mode = state;
case 'v':
#ifdef DNS_OPT_NEWCODES
switch (tolower(cmd[1])) {
default:
case 'c': /* vc, and default */
#endif /* DNS_OPT_NEWCODES */
if (!is_batchfile)
lookup->tcp_mode = state;
break;
#ifdef DNS_OPT_NEWCODES
case 'i': /* view */
if (value == NULL)
goto need_value;
if (!state)
goto invalid_option;
strncpy(lookup->viewname, value, MXNAME);
break;
}
break;
case 'z': /* zone */
if (value == NULL)
goto need_value;
if (!state)
goto invalid_option;
strncpy(lookup->zonename, value, MXNAME);
break;
#endif
default:
invalid_option:
need_value:
......@@ -1287,8 +1310,6 @@ main(int argc, char **argv) {
(dig_server_t *)s2, link);
isc_mem_free(mctx, s2);
}
if (isc_mem_debugging != 0)
isc_mem_stats(mctx, stderr);
isc_mem_free(mctx, default_lookup);
if (batchname != NULL) {
if (batchfp != stdin)
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dighost.c,v 1.141 2000/10/04 17:14:43 mws Exp $ */
/* $Id: dighost.c,v 1.142 2000/10/11 17:44:01 mws Exp $ */
/*
* Notice to programmers: Do not use this code as an example of how to
......@@ -36,8 +36,10 @@
extern int h_errno;
#endif
#include <dns/fixedname.h>
#include <dns/message.h>
#include <dns/name.h>
#include <dns/opt.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
#include <dns/rdatalist.h>
......@@ -46,6 +48,7 @@ extern int h_errno;
#include <dns/rdatatype.h>
#include <dns/result.h>
#include <dns/tsig.h>
#include <dst/dst.h>
#include <isc/app.h>
......@@ -317,6 +320,10 @@ make_empty_lookup(void) {
looknew->section_authority = ISC_TRUE;
looknew->section_additional = ISC_TRUE;
looknew->new_search = ISC_FALSE;
#ifdef DNS_OPT_NEWCODES
looknew->zonename[0] = 0;
looknew->viewname[0] = 0;
#endif
ISC_LIST_INIT(looknew->q);
ISC_LIST_INIT(looknew->my_server_list);
return (looknew);
......@@ -364,6 +371,10 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
looknew->section_authority = lookold->section_authority;
looknew->section_additional = lookold->section_additional;
looknew->retries = lookold->retries;
#ifdef DNS_OPT_NEWCODES
strncpy(looknew->viewname, lookold-> viewname, MXNAME);
strncpy(looknew->zonename, lookold-> zonename, MXNAME);
#endif /* DNS_OPT_NEWCODES */
if (servers)
clone_server_list(lookold->my_server_list,
......@@ -698,11 +709,18 @@ setup_libs(void) {
* option is UDP buffer size.
*/
static void
add_opt(dns_message_t *msg, isc_uint16_t udpsize) {
add_opt(dns_message_t *msg, isc_uint16_t udpsize, dns_optlist_t optlist) {
dns_rdataset_t *rdataset = NULL;
dns_rdatalist_t *rdatalist = NULL;
dns_rdata_t *rdata = NULL;
isc_result_t result;
#ifdef DNS_OPT_NEWCODES
isc_buffer_t *rdatabuf = NULL;
unsigned int i, optsize = 0;
#else /* DNS_OPT_NEWCODES */
UNUSED(optlist);
#endif /* DNS_OPT_NEWCODES */
debug("add_opt()");
result = dns_message_gettemprdataset(msg, &rdataset);
......@@ -720,6 +738,15 @@ add_opt(dns_message_t *msg, isc_uint16_t udpsize) {
rdatalist->ttl = 0;
rdata->data = NULL;
rdata->length = 0;
#ifdef DNS_OPT_NEWCODES
for (i=0; i<optlist.used; i++)
optsize += optlist.attrs[i].value.length + 4;
result = isc_buffer_allocate(mctx, &rdatabuf, optsize);
check_result(result, "isc_buffer_allocate");
result = dns_opt_add(rdata, &optlist, rdatabuf);
check_result(result, "dns_opt_add");
dns_message_takebuffer(msg, &rdatabuf);
#endif /* DNS_OPT_NEWCODES */
ISC_LIST_INIT(rdatalist->rdata);
ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
dns_rdatalist_tordataset(rdatalist, rdataset);
......@@ -1320,8 +1347,66 @@ setup_lookup(dig_lookup_t *lookup) {
isc_buffer_init(&lookup->sendbuf, lookup->sendspace, COMMSIZE);
result = dns_message_renderbegin(lookup->sendmsg, &lookup->sendbuf);
check_result(result, "dns_message_renderbegin");
if (lookup->udpsize > 0)
add_opt(lookup->sendmsg, lookup->udpsize);
#ifndef DNS_OPT_NEWCODES
if (lookup->udpsize > 0) {
#else /* DNS_OPT_NEWCODES */
if (lookup->udpsize > 0 || lookup->zonename[0] !=0 ||
lookup->viewname[0] != 0) {
dns_fixedname_t fname;
isc_buffer_t namebuf, *wirebuf = NULL;
dns_compress_t cctx;
#endif /* DNS_OPT_NEWCODES */
dns_optlist_t optlist;
dns_optattr_t optattr[2];
if (lookup->udpsize == 0)
lookup->udpsize = 2048;
optlist.size = 2;
optlist.used = 0;
optlist.next = 0;
optlist.attrs = optattr;
#ifdef DNS_OPT_NEWCODES
if (lookup->zonename[0] != 0) {
optattr[optlist.used].code = DNS_OPTCODE_ZONE;
dns_fixedname_init(&fname);
isc_buffer_init(&namebuf, lookup->zonename,
strlen(lookup->zonename));
isc_buffer_add(&namebuf, strlen(lookup->zonename));
result = dns_name_fromtext(&(fname.name), &namebuf,
dns_rootname, ISC_FALSE,
NULL);
check_result(result, "; illegal zone option");
result = dns_compress_init(&cctx, 0, mctx);
check_result(result, "dns_compress_init");
result = isc_buffer_allocate(mctx, &wirebuf,
MXNAME);
check_result(result, "isc_buffer_allocate");
result = dns_name_towire(&(fname.name), &cctx,
wirebuf);
check_result(result, "dns_name_towire");
optattr[optlist.used].value.base =
isc_buffer_base(wirebuf);
optattr[optlist.used].value.length =
isc_buffer_usedlength(wirebuf);
optlist.used++;
dns_compress_invalidate(&cctx);
}
if (lookup->viewname[0] != 0) {
optattr[optlist.used].code = DNS_OPTCODE_VIEW;
optattr[optlist.used].value.base =
lookup->viewname;
optattr[optlist.used].value.length =
strlen(lookup->viewname);
optlist.used++;
}
#endif /* DNS_OPT_NEWCODES */
add_opt(lookup->sendmsg, lookup->udpsize, optlist);
#ifdef DNS_OPT_NEWCODES
if (wirebuf != NULL)
isc_buffer_free(&wirebuf);
#endif /* DNS_OPT_NEWCODES */
}
result = dns_message_rendersection(lookup->sendmsg,
DNS_SECTION_QUESTION, 0);
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dig.h,v 1.51 2000/09/29 23:42:15 mws Exp $ */
/* $Id: dig.h,v 1.52 2000/10/11 17:44:03 mws Exp $ */
#ifndef DIG_H
#define DIG_H
......@@ -123,6 +123,10 @@ struct dig_lookup {
isc_uint32_t ixfr_serial;
isc_buffer_t rdatabuf;
char rdatastore[MXNAME];
#ifdef DNS_OPT_NEWCODES
char zonename[MXNAME];
char viewname[MXNAME];
#endif /* DNS_OPT_NEWCODES */
dst_context_t *tsigctx;
isc_buffer_t *querysig;
isc_uint32_t msgcounter;
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: client.c,v 1.117 2000/10/06 18:58:29 bwelling Exp $ */
/* $Id: client.c,v 1.118 2000/10/11 17:44:04 mws Exp $ */
#include <config.h>
......@@ -26,6 +26,7 @@
#include <isc/timer.h>
#include <isc/util.h>
#include <dns/db.h>
#include <dns/dispatch.h>
#include <dns/events.h>
#include <dns/message.h>
......@@ -238,6 +239,15 @@ client_free(ns_client_t *client) {
dns_rdataset_disassociate(client->opt);
dns_message_puttemprdataset(client->message, &client->opt);
}
#ifdef DNS_OPT_NEWCODES
if (client->opt_zone != NULL) {
isc_mem_put(client->mctx, client->opt_zone,
sizeof(*client->opt_zone));
client->opt_zone = NULL;
}
if (client->opt_view != NULL)
isc_buffer_free(&client->opt_view);
#endif /* DNS_OPT_NEWCODES */
dns_message_destroy(&client->message);
if (client->task != NULL)
isc_task_detach(&client->task);
......@@ -888,6 +898,75 @@ ns_client_error(ns_client_t *client, isc_result_t result) {
ns_client_send(client);
}
#ifdef DNS_OPT_NEWCODES
static isc_result_t
client_addoptattrs(ns_client_t *client, dns_rdata_t *rdata) {
isc_result_t result;
isc_buffer_t *zonebuf = NULL, *buf = NULL;
dns_optlist_t attrlist;
dns_optattr_t attrs[CLIENT_NUMATTRS];
dns_compress_t cctx;
int i, sizeneeded = 0;
result = dns_compress_init(&cctx, 0, client->mctx);
if (result != ISC_R_SUCCESS)
goto fail1;
dns_compress_setmethods(&cctx, DNS_COMPRESS_NONE);
attrlist.size=2;
attrlist.used=0;
attrlist.attrs=attrs;
for (i=0; i<CLIENT_NUMATTRS; i++) {
attrs[i].code = 0;
attrs[i].value.base = NULL;
attrs[i].value.length = 0;
}
if (client->opt_zone != NULL) {
result = isc_buffer_allocate(client->mctx, &zonebuf,
DNS_NAME_MAXWIRE);
if (result != ISC_R_SUCCESS)
goto fail2;
result = dns_name_towire(dns_fixedname_name(client->opt_zone),
&cctx, zonebuf);
if (result != ISC_R_SUCCESS)
goto fail2;
attrs[attrlist.used].code = DNS_OPTCODE_ZONE;
attrs[attrlist.used].value.base = isc_buffer_base(zonebuf);
attrs[attrlist.used].value.length =
isc_buffer_usedlength(zonebuf);
attrlist.used++;
sizeneeded += 4 + isc_buffer_usedlength(zonebuf);
}
if (client->opt_view != NULL) {
attrs[attrlist.used].code = DNS_OPTCODE_VIEW;
attrs[attrlist.used].value.base =
isc_buffer_base(client->opt_view);
attrs[attrlist.used].value.length =
isc_buffer_usedlength(client->opt_view);
attrlist.used++;
sizeneeded += 4 + isc_buffer_usedlength(client->opt_view);
}
if (sizeneeded == 0) {
result = ISC_R_SUCCESS;
goto fail2;
}
result = isc_buffer_allocate(client->mctx, &buf, sizeneeded+1);
if (result != ISC_R_SUCCESS)
goto fail2;
result = dns_opt_add(rdata, &attrlist, buf);
if (result != ISC_R_SUCCESS)
goto fail2;
dns_message_takebuffer(client->message, &buf);
fail2:
dns_compress_invalidate(&cctx);
fail1:
if (buf != NULL)
isc_buffer_free(&buf);
if (zonebuf != NULL)
isc_buffer_free(&zonebuf);
return (result);
}
#endif /* DNS_OPT_NEWCODES */
static inline isc_result_t
client_addopt(ns_client_t *client) {
dns_rdataset_t *rdataset;
......@@ -925,13 +1004,20 @@ client_addopt(ns_client_t *client) {
rdatalist->ttl = 0;
/*
* No ENDS options.
* No ENDS options in the default case.
*/
rdata->data = NULL;
rdata->length = 0;
rdata->rdclass = rdatalist->rdclass;
rdata->type = rdatalist->type;
#ifdef DNS_OPT_NEWCODES
/*
* Set the attributes
*/
client_addoptattrs(client, rdata);
#endif /* DNS_OPT_NEWCODES */
ISC_LIST_INIT(rdatalist->rdata);
ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
dns_rdatalist_tordataset(rdatalist, rdataset);
......@@ -941,6 +1027,81 @@ client_addopt(ns_client_t *client) {
return (ISC_R_SUCCESS);
}
#ifdef DNS_OPT_NEWCODES
static void
client_getoptattrs(ns_client_t *client, dns_rdataset_t *opt) {
dns_optlist_t optlist;
dns_optattr_t optattr;
isc_result_t result, iresult;
isc_buffer_t zonebuf;
dns_decompress_t dctx;
/* If an old set of opts are still around, free them. */
if (client->opt_zone != NULL) {
isc_mem_put(client->mctx, client->opt_zone,
sizeof(*client->opt_zone));
client->opt_zone = NULL;
}
if (client->opt_view != NULL)
isc_buffer_free(&client->opt_view);
/*
* If there are any options, extract them here
*/
optlist.size = 1;
optlist.used = 0;
optlist.next = 0;
optlist.attrs = &optattr;
do {
result = dns_opt_decodeall(&optlist, opt);
if (result == ISC_R_SUCCESS ||
result == DNS_R_MOREDATA) {
switch (optattr.code) {
case DNS_OPTCODE_ZONE:
dns_decompress_init(&dctx, 0,
ISC_FALSE);
client->opt_zone = isc_mem_get(
client->mctx,
sizeof(*client->opt_zone));
if (client->opt_zone == NULL)
goto zonefail1;
dns_fixedname_init(client->opt_zone);
isc_buffer_init(&zonebuf,
optattr.value.base,
optattr.value.length);
isc_buffer_add(&zonebuf,optattr.value.length);
isc_buffer_setactive(&zonebuf,
optattr.value.length);
iresult = dns_name_fromwire(
dns_fixedname_name(
client->opt_zone),
&zonebuf,
&dctx, ISC_FALSE,
NULL);
if (iresult != ISC_R_SUCCESS) {
dns_fixedname_invalidate(
client->opt_zone);
zonefail1:
dns_decompress_invalidate(&dctx);
}
break;
case DNS_OPTCODE_VIEW:
iresult = isc_buffer_allocate(client->mctx,
&client->opt_view,
optattr.value.length);
if (iresult != ISC_R_SUCCESS)
break;
isc_buffer_putmem(client->opt_view,
optattr.value.base,
optattr.value.length);
break;
}
}
} while (result == DNS_R_MOREDATA);
}
#endif /* DNS_OPT_NEWCODES */
/*
* Handle an incoming request event from the dispatch (UDP case)
* or tcpmsg (TCP case).
......@@ -1060,6 +1221,19 @@ client_request(isc_task_t *task, isc_event_t *event) {
* Set the client's UDP buffer size.
*/
client->udpsize = opt->rdclass;
#ifdef DNS_OPT_NEWCODES
/*
* Set up the rest of the opt stuff
*/
client_getoptattrs(client, opt);
/*
* If we're using a fixed zone option (opt_zone), set it to
* allow glue here.
*/
if (client->opt_zone != NULL)
client->query.dboptions |= DNS_DBFIND_GLUEOK;
#endif /* DNS_OPT_NEWCODES */
/*
* Create an OPT for our reply.
......@@ -1342,6 +1516,10 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp)
client->tcpbuf = NULL;
client->opt = NULL;
client->udpsize = 512;
#ifdef DNS_OPT_NEWCODES
client->opt_zone = NULL;
client->opt_view = NULL;
#endif DNS_OPT_NEWCODES
client->next = NULL;
client->shutdown = NULL;
client->shutdown_arg = NULL;
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: client.h,v 1.43 2000/09/13 01:33:26 marka Exp $ */
/* $Id: client.h,v 1.44 2000/10/11 17:44:07 mws Exp $ */
#ifndef NAMED_CLIENT_H
#define NAMED_CLIENT_H 1
......@@ -69,6 +69,10 @@
#include <dns/name.h>
#include <dns/types.h>
#include <dns/tcpmsg.h>
#ifdef DNS_OPT_NEWCODES
#include <dns/fixedname.h>
#include <dns/opt.h>
#endif /* DNS_OPT_NEWCODES */
#include <named/types.h>
#include <named/query.h>
......@@ -107,6 +111,10 @@ struct ns_client {
unsigned char * sendbuf;
dns_rdataset_t * opt;
isc_uint16_t udpsize;
#ifdef DNS_OPT_NEWCODES
dns_fixedname_t * opt_zone;
isc_buffer_t * opt_view;
#endif /* DNS_OPT_NEWCODES */
void (*next)(ns_client_t *);
void (*shutdown)(void *arg, isc_result_t result);
void *shutdown_arg;
......@@ -130,6 +138,14 @@ struct ns_client {
client_list_t *list;
};
#ifdef DNS_OPT_NEWCODES
/*
* Number of attr fields (opt_zone, opt_view) in above structure. Used in
* client_addoptattrs()
*/
#define CLIENT_NUMATTRS 2
#endif /* DNS_OPT_NEWCODES */
#define NS_CLIENT_MAGIC 0x4E534363U /* NSCc */
#define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC)
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: query.c,v 1.134 2000/10/07 00:09:16 bwelling Exp $ */
/* $Id: query.c,v 1.135 2000/10/11 17:44:05 mws Exp $ */
#include <config.h>
......@@ -690,6 +690,25 @@ query_getdb(ns_client_t *client, dns_name_t *name, unsigned int options,
{
isc_result_t result;
#ifdef DNS_OPT_NEWCODES
if (client->opt_zone != NULL) {
result = query_getzonedb(client, &(client->opt_zone->name),
options, zonep, dbp, versionp);
if (result == ISC_R_SUCCESS)
*is_zonep = ISC_TRUE;
else
result = DNS_R_REFUSED;
} else {
result = query_getzonedb(client, name, options, zonep, dbp,
versionp);
if (result == ISC_R_SUCCESS) {
*is_zonep = ISC_TRUE;
} else if (result == ISC_R_NOTFOUND) {
result = query_getcachedb(client, dbp, options);
*is_zonep = ISC_FALSE;
}
}
#else /* DNS_OPT_NEWCODES */
result = query_getzonedb(client, name, options, zonep, dbp, versionp);
if (result == ISC_R_SUCCESS) {
*is_zonep = ISC_TRUE;
......@@ -697,7 +716,7 @@ query_getdb(ns_client_t *client, dns_name_t *name, unsigned int options,
result = query_getcachedb(client, dbp, options);
*is_zonep = ISC_FALSE;
}
#endif /* DNS_OPT_NEWCODES */
return (result);
}
......@@ -2175,7 +2194,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
if (result == DNS_R_REFUSED)
QUERY_ERROR(DNS_R_REFUSED);
else
QUERY_ERROR(DNS_R_SERVFAIL);
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
......@@ -2324,6 +2343,11 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
*/
break;
case DNS_R_GLUE:
#ifdef DNS_OPT_NEWCODES
if (client->opt_zone != NULL)
break;
/* Fallthrough if we don't have opt_zone */
#endif DNS_OPT_NEWCODES
case DNS_R_ZONECUT:
/*
* These cases are handled in the main line below.
......@@ -2332,6 +2356,13 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
authoritative = ISC_FALSE;
break;
case ISC_R_NOTFOUND:
#ifdef DNS_OPT_NEWCODES
/*
* If we've passed in opt_zone, don't try anything more.
*/
if (client->opt_zone != NULL)
break;
#endif /* DNS_OPT_NEWCODES */
/*
* The cache doesn't even have the root NS. Get them from
* the hints DB.
......@@ -2357,6 +2388,14 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
*/
/* FALLTHROUGH */
case DNS_R_DELEGATION:
#ifdef DNS_OPT_NEWCODES
/*
* If we've passed in opt_zone, don't try anything more.
*/
if (client->opt_zone != NULL) {
break;
}
#endif /* DNS_OPT_NEWCODES */
authoritative = ISC_FALSE;
if (is_zone) {
/*
......
......@@ -31,3 +31,24 @@ Fix wpk's build/tests scripts to
- not run if the previous test failed (to keep logs and cores around)
- display the date and time of the last run
Big todo list for dig, from code walkthrough with Brian:
strncpy -> isc_mem_strdup
oname in setup_lookup can be on the stack instead of allocated
Move INSIST in insert_lookup up
Fix -b option in UDP mode (make sure server and bind address are
compatible)
Use symbolic names for exit codes
l->retries-- can be moved out of if/else
+tcp/vc no longer needs to be prohibited in batchfiles
digrc filename print length shouldn't be 132
bargc should be more than 14
Split up launch_next_query
0 should be dns_rcode_noerror
How is data in additional section printer in *XFR
What happens if additional data is after the end of an *XFR
Legality of serial 0
query point in clear_query should be **
Opcode 100 spelled wrong in host.c