Commit 6257efc3 authored by Internet Software Consortium, Inc's avatar Internet Software Consortium, Inc Committed by Lamont Jones

9.0.0b2

parent ab47e906
......@@ -50,4 +50,4 @@ kitclean: distclean
tags:
rm -f TAGS
find lib bin -name "*.[ch]" -print | etags -
find lib bin -name "*.[ch]" -print | @ETAGS@ -
......@@ -68,50 +68,34 @@ BIND 9
Stichting NLnet - NLnet Foundation
BIND 9.0.0b1
BIND 9.0.0b2
BIND 9.0.0b1 is the first public release of BIND 9 code. It will
BIND 9.0.0b2 is the second public release of BIND 9 code. It will
be most useful to advanced users working with IPv6 or DNSSEC.
BIND 9.0.0b1 is not functionally complete, and is not a release
BIND 9.0.0b2 is not functionally complete, and is not a release
candidate for BIND 9.0.0. The ISC anticipates a number of additional
beta releases between now and May, when BIND 9.0.0 is scheduled to
be released.
The ISC does not recommend using BIND 9.0.0b1 for "production"
The ISC does not recommend using BIND 9.0.0b2 for "production"
services.
We hope users of BIND 9.0.0b1 will provide feedback, bug fixes, and
We hope users of BIND 9.0.0b2 will provide feedback, bug fixes, and
enhancements. If you are not in a position to do so, it would
probably be better to wait until subsequent releases.
Much of the core technology planned for BIND 9.0.0 is in this beta
release. Some of the highlights are:
There have been many changes since beta 1; the highlights are:
IPv6
Many more config file options are now implemented. See
doc/misc/options for a summary of the current implementation
status.
Support for bitstring labels, DNAME, and A6 records.
Portability improvements. In particular, this beta should work
much better than beta 1 on FreeBSD 3.4.
IPv6-aware resolver (follows A6 chains, can use IPv6 to
talk to other nameservers).
The nameserver listens on an IPv6 socket.
DNSSEC
All new RR types supported.
The server generates DNSSEC responses for secure zones.
EDNS0
DNS messages using UDP have been limited to 512
bytes. This is too small for DNSSEC replies, whose
signature and key records can be large. EDNS0 allows
larger UDP messages to be sent.
EDNS0 is understood by the server, and used by the
resolver.
Bug fixes. Almost all bugs reported against beta 1 have been
fixed.
Some of the more significant items that will be implemented or
enhanced in a future beta are
......@@ -125,12 +109,6 @@ BIND 9.0.0b1
Notify is not yet implemented.
Configuration File
Some config file items are not yet implemented.
See doc/misc/options for a summary of the current
status.
Selective Forwarding
Documentation
......@@ -139,6 +117,9 @@ BIND 9.0.0b1
but a preliminary version of the Administrator's
Reference Manual is in the doc/arm subdirectory.
A detailed CHANGES file like that in BIND 4 and BIND 8
will be provided in future betas.
Building
......@@ -149,6 +130,7 @@ Building
AIX 4.3
COMPAQ Tru64 UNIX 4.0D
FreeBSD 3.4-STABLE
HP-UX 11
IRIX64 6.5
NetBSD current (with "unproven" pthreads)
......@@ -167,6 +149,10 @@ Building
Shared libraries will be built if "--with-libtool" is added to the
"configure" command.
If you're planning on making changes to the BIND 9 source, you
should also "make depend". If you're using Emacs, you might find
"make tags" helpful.
Building with gcc is not supported, unless gcc is the vendor's usual
compiler (e.g. the various BSD systems, Linux).
......@@ -199,7 +185,11 @@ Bug Reports and Mailing Lists
-f Run in the foreground.
-N <number_of_cpus>
-g Run in the foreground and log
to stderr, ignoring any "logging"
statement in in the config file.
-n <number_of_cpus>
-t <directory> Chroot to <directory> before running.
......@@ -218,7 +208,7 @@ Bug Reports and Mailing Lists
uses the Linux kernel's capability mechanism to drop all root
powers except the ability to bind() to a privileged port.
On systems with more than one CPU, the "-N" option should be used
On systems with more than one CPU, the "-n" option should be used
to indicate how many CPUs there are.
......
......@@ -45,7 +45,7 @@ SRCS = main.c client.c err_pkt.c \
@BIND9_MAKE_RULES@
lwresd: ${OBJS} ${UOBJS} ${DEPLIBS}
${LIBTOOL} ${CC} -o $@ ${OBJS} ${UOBJS} ${LIBS}
${LIBTOOL} ${CC} ${CFLAGS} -o $@ ${OBJS} ${UOBJS} ${LIBS}
clean distclean::
rm -f ${TARGETS}
......@@ -333,6 +333,7 @@ client_initialize(client_t *client, clientmgr_t *cmgr)
client->options = 0;
client->byaddr = NULL;
client->addrinfo = NULL;
ISC_LIST_APPEND(cmgr->idle, client, link);
}
......@@ -349,7 +350,8 @@ client_init_aliases(client_t *client)
for (i = 0 ; i < LWRES_MAX_ADDRS ; i++) {
client->addrs[i].family = 0;
client->addrs[i].length = 0;
client->addrs[i].address = NULL;
memset(client->addrs[i].address, 0, LWRES_ADDR_MAXLEN);
LWRES_LINK_INIT(&client->addrs[i], link);
}
}
......@@ -367,7 +369,7 @@ client_init_gabn(client_t *client)
client->gabn.aliases = client->aliases;
client->gabn.realnamelen = 0;
client->gabn.aliaslen = client->aliaslen;
client->gabn.addrs = client->addrs;
LWRES_LIST_INIT(client->gabn.addrs);
client->gabn.base = NULL;
client->gabn.baselen = 0;
......
......@@ -84,6 +84,7 @@ struct client_s {
dns_byaddr_t *byaddr;
unsigned int options;
isc_netaddr_t na;
dns_adbaddrinfo_t *addrinfo;
/*
* Alias and address info. This is copied up to the gabn/gnba
......
......@@ -30,10 +30,12 @@
#include <isc/task.h>
#include <isc/util.h>
#include <dns/resolver.h>
#include <dns/rootns.h>
#include <dns/log.h>
#include <lwres/lwres.h>
#include <lwres/result.h>
#include "client.h"
......@@ -57,6 +59,8 @@ isc_taskmgr_t *taskmgr;
isc_socketmgr_t *sockmgr;
isc_timermgr_t *timermgr;
isc_sockaddrlist_t forwarders;
static isc_result_t
create_view(isc_mem_t *mctx)
{
......@@ -101,8 +105,24 @@ create_view(isc_mem_t *mctx)
dns_view_sethints(view, rootdb);
dns_db_detach(&rootdb);
dns_view_freeze(view);
/*
* If we have forwarders, set them here.
*/
if (ISC_LIST_HEAD(forwarders) != NULL) {
isc_sockaddr_t *sa;
dns_resolver_setforwarders(view->resolver, &forwarders);
dns_resolver_setfwdpolicy(view->resolver, dns_fwdpolicy_only);
sa = ISC_LIST_HEAD(forwarders);
while (sa != NULL) {
ISC_LIST_UNLINK(forwarders, sa, link);
isc_mem_put(mctx, sa, sizeof (*sa));
sa = ISC_LIST_HEAD(forwarders);
}
}
dns_view_freeze(view);
return (ISC_R_SUCCESS);
......@@ -128,6 +148,65 @@ mem_free(void *arg, void *mem, size_t size)
isc_mem_put(arg, mem, size);
}
static void
parse_resolv_conf(isc_mem_t *mem)
{
lwres_context_t *lwctx;
lwres_conf_t *lwc;
int lwresult;
struct in_addr ina;
struct in6_addr ina6;
isc_sockaddr_t *sa;
int i;
lwctx = NULL;
lwresult = lwres_context_create(&lwctx, mem, mem_alloc, mem_free);
if (lwresult != LWRES_R_SUCCESS)
return;
lwresult = lwres_conf_parse(lwctx, "/etc/resolv.conf");
if (lwresult != LWRES_R_SUCCESS)
goto out;
#if 1
lwres_conf_print(lwctx, stderr);
#endif
lwc = lwres_conf_get(lwctx);
INSIST(lwc != NULL);
/*
* Run through the list of nameservers, and set them to be our
* forwarders.
*/
for (i = 0 ; i < lwc->nsnext ; i++) {
switch (lwc->nameservers[i].family) {
case AF_INET:
sa = isc_mem_get(mem, sizeof *sa);
INSIST(sa != NULL);
memcpy(&ina.s_addr, lwc->nameservers[i].address, 4);
isc_sockaddr_fromin(sa, &ina, 53);
ISC_LIST_APPEND(forwarders, sa, link);
sa = NULL;
break;
case AF_INET6:
sa = isc_mem_get(mem, sizeof *sa);
INSIST(sa != NULL);
memcpy(&ina6.s6_addr, lwc->nameservers[i].address, 16);
isc_sockaddr_fromin6(sa, &ina6, 53);
ISC_LIST_APPEND(forwarders, sa, link);
sa = NULL;
break;
default:
break;
}
}
out:
lwres_conf_clear(lwctx);
lwres_context_destroy(&lwctx);
}
int
main(int argc, char **argv)
{
......@@ -140,6 +219,7 @@ main(int argc, char **argv)
client_t *client;
isc_logdestination_t destination;
isc_log_t *lctx;
isc_logconfig_t *lcfg;
UNUSED(argc);
UNUSED(argv);
......@@ -157,21 +237,20 @@ main(int argc, char **argv)
* Set up logging.
*/
lctx = NULL;
result = isc_log_create(mem, &lctx);
INSIST(result == ISC_R_SUCCESS);
result = dns_log_init(lctx);
result = isc_log_create(mem, &lctx, &lcfg);
INSIST(result == ISC_R_SUCCESS);
dns_log_init(lctx);
destination.file.stream = stderr;
destination.file.name = NULL;
destination.file.versions = ISC_LOG_ROLLNEVER;
destination.file.maximum_size = 0;
result = isc_log_createchannel(lctx, "_default",
result = isc_log_createchannel(lcfg, "_default",
ISC_LOG_TOFILEDESC,
ISC_LOG_DYNAMIC,
&destination, ISC_LOG_PRINTTIME);
INSIST(result == ISC_R_SUCCESS);
result = isc_log_usechannel(lctx, "_default", NULL, NULL);
result = isc_log_usechannel(lcfg, "_default", NULL, NULL);
INSIST(result == ISC_R_SUCCESS);
/*
......@@ -200,10 +279,15 @@ main(int argc, char **argv)
result = isc_timermgr_create(mem, &timermgr);
INSIST(result == ISC_R_SUCCESS);
/*
* Read resolv.conf to get our forwarders.
*/
ISC_LIST_INIT(forwarders);
parse_resolv_conf(mem);
/*
* Initialize the DNS bits. Start by loading our built-in
* root hints. This should come from a file, eventually.
* XXXMLG
* root hints.
*/
result = create_view(mem);
INSIST(result == ISC_R_SUCCESS);
......
......@@ -93,13 +93,13 @@ setup_addresses(client_t *client, dns_adbfind_t *find, unsigned int at)
case AF_INET:
sin = &ai->sockaddr->type.sin;
addr->family = LWRES_ADDRTYPE_V4;
addr->address = (unsigned char *)&sin->sin_addr;
memcpy(addr->address, &sin->sin_addr, 4);
addr->length = 4;
break;
case AF_INET6:
sin6 = &ai->sockaddr->type.sin6;
addr->family = LWRES_ADDRTYPE_V6;
addr->address = (unsigned char *)&sin6->sin6_addr;
memcpy(addr->address, &sin6->sin6_addr, 16);
addr->length = 16;
break;
default:
......@@ -110,6 +110,8 @@ setup_addresses(client_t *client, dns_adbfind_t *find, unsigned int at)
addr->address, addr->family, addr->length);
client->gabn.naddrs++;
REQUIRE(!LWRES_LINK_LINKED(addr, link));
LWRES_LIST_APPEND(client->gabn.addrs, addr, link);
next:
ai = ISC_LIST_NEXT(ai, publink);
......@@ -122,10 +124,11 @@ generate_reply(client_t *client)
isc_result_t result;
int lwres;
isc_region_t r;
lwres_buffer_t b;
lwres_buffer_t lwb;
clientmgr_t *cm;
cm = client->clientmgr;
lwb.base = NULL;
DP(50, "Generating gabn reply for client %p", client);
......@@ -150,6 +153,7 @@ generate_reply(client_t *client)
* Run through the finds we have and wire them up to the gabn
* structure.
*/
LWRES_LIST_INIT(client->gabn.addrs);
if (client->v4find != NULL)
setup_addresses(client, client->v4find, DNS_ADBFIND_INET);
if (client->v6find != NULL)
......@@ -161,18 +165,22 @@ generate_reply(client_t *client)
client->pkt.recvlength = LWRES_RECVLENGTH;
client->pkt.authtype = 0; /* XXXMLG */
client->pkt.authlength = 0;
client->pkt.result = LWRES_R_SUCCESS;
lwres_buffer_init(&b, client->buffer, LWRES_RECVLENGTH);
/*
* If there are no addresses and no aliases, return failure.
*/
if (client->gabn.naddrs == 0 && client->gabn.naliases == 0)
client->pkt.result = LWRES_R_NOTFOUND;
else
client->pkt.result = LWRES_R_SUCCESS;
lwres = lwres_gabnresponse_render(cm->lwctx, &client->gabn,
&client->pkt, &b);
&client->pkt, &lwb);
if (lwres != LWRES_R_SUCCESS)
goto out;
hexdump("Sending to client", b.base, b.used);
r.base = b.base;
r.length = b.used;
r.base = lwb.base;
r.length = lwb.used;
client->sendbuf = r.base;
client->sendlength = r.length;
result = isc_socket_sendto(cm->sock, &r, cm->task, client_send, client,
......@@ -186,10 +194,16 @@ generate_reply(client_t *client)
* All done!
*/
cleanup_gabn(client);
return;
out:
cleanup_gabn(client);
if (lwb.base != NULL)
lwres_context_freemem(client->clientmgr->lwctx,
lwb.base, lwb.length);
error_pkt_send(client, LWRES_R_FAILURE);
}
......@@ -342,6 +356,7 @@ start_find(client_t *client)
*/
options = 0;
options |= DNS_ADBFIND_WANTEVENT;
options |= DNS_ADBFIND_RETURNLAME;
/*
* Set the bits up here to mark that we want this address family
......@@ -526,6 +541,4 @@ process_gabn(client_t *client, lwres_buffer_t *b)
lwres_gabnrequest_free(client->clientmgr->lwctx, &req);
error_pkt_send(client, LWRES_R_FAILURE);
return;
}
......@@ -43,6 +43,7 @@ static void
byaddr_done(isc_task_t *task, isc_event_t *event)
{
client_t *client;
clientmgr_t *cm;
dns_byaddrevent_t *bevent;
int lwres;
lwres_buffer_t lwb;
......@@ -52,10 +53,13 @@ byaddr_done(isc_task_t *task, isc_event_t *event)
isc_buffer_t b;
lwres_gnbaresponse_t *gnba;
isc_uint16_t naliases;
isc_stdtime_t now;
(void)task;
lwb.base = NULL;
client = event->arg;
cm = client->clientmgr;
INSIST(client->byaddr == event->sender);
bevent = (dns_byaddrevent_t *)event;
......@@ -64,16 +68,38 @@ byaddr_done(isc_task_t *task, isc_event_t *event)
DP(50, "byaddr event result = %s",
isc_result_totext(bevent->result));
if (bevent->result != ISC_R_SUCCESS) {
result = bevent->result;
if (result != ISC_R_SUCCESS) {
dns_byaddr_destroy(&client->byaddr);
isc_event_free(&event);
if ((client->options & DNS_BYADDROPT_IPV6NIBBLE) == 0) {
bevent = NULL;
/*
* Were we trying bitstring or nibble mode? If bitstring,
* and we got FORMERROR or SERVFAIL, set the flag to
* avoid bitstring lables for 10 minutes. If we got any
* other error (NXDOMAIN, etc) just try again without
* bitstrings, and let our cache handle the negative answer
* for bitstrings.
*/
if ((client->options & DNS_BYADDROPT_IPV6NIBBLE) != 0) {
dns_adb_freeaddrinfo(cm->view->adb, &client->addrinfo);
error_pkt_send(client, LWRES_R_FAILURE);
return;
}
client->options &= ~DNS_BYADDROPT_IPV6NIBBLE;
isc_stdtime_get(&now);
if (result == DNS_R_FORMERR ||
result == DNS_R_SERVFAIL ||
result == ISC_R_FAILURE)
dns_adb_setavoidbitstring(cm->view->adb,
client->addrinfo, now + 600);
/*
* Fall back to nibble reverse if the default of bitstrings
* fails.
*/
client->options |= DNS_BYADDROPT_IPV6NIBBLE;
start_byaddr(client);
return;
......@@ -84,28 +110,29 @@ byaddr_done(isc_task_t *task, isc_event_t *event)
b = client->recv_buffer;
result = dns_name_totext(name, ISC_TRUE, &client->recv_buffer);
if (result != ISC_R_SUCCESS)
goto out;
DP(50, "***** Found name %.*s",
client->recv_buffer.used - b.used,
(char *)(b.base) + b.used);
if (result != ISC_R_SUCCESS)
goto out;
if (gnba->realname == NULL) {
gnba->realname = (char *)(b.base) + b.used;
gnba->realnamelen = client->recv_buffer.used - b.used;
} else {
naliases = gnba->naliases;
if (naliases < LWRES_MAX_ALIASES) {
gnba->aliases[naliases] =
(char *)(b.base) + b.used;
gnba->aliaslen[naliases] =
client->recv_buffer.used - b.used;
gnba->naliases++;
}
if (naliases >= LWRES_MAX_ALIASES)
break;
gnba->aliases[naliases] = (char *)(b.base) + b.used;
gnba->aliaslen[naliases] =
client->recv_buffer.used - b.used;
gnba->naliases++;
}
name = ISC_LIST_NEXT(name, link);
name = ISC_LIST_NEXT(name, link);
}
dns_byaddr_destroy(&client->byaddr);
dns_adb_freeaddrinfo(cm->view->adb, &client->addrinfo);
isc_event_free(&event);
/*
* Render the packet.
......@@ -115,12 +142,8 @@ byaddr_done(isc_task_t *task, isc_event_t *event)
client->pkt.authlength = 0;
client->pkt.result = LWRES_R_SUCCESS;
lwres_buffer_init(&lwb, client->buffer, LWRES_RECVLENGTH);
lwres = lwres_gnbaresponse_render(client->clientmgr->lwctx,
lwres = lwres_gnbaresponse_render(cm->lwctx,
gnba, &client->pkt, &lwb);
hexdump("Sending to client", lwb.base, lwb.used);
if (lwres != LWRES_R_SUCCESS)
goto out;
......@@ -128,17 +151,25 @@ byaddr_done(isc_task_t *task, isc_event_t *event)
r.length = lwb.used;
client->sendbuf = r.base;