diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h index 7217c432b4..56ce33892e 100644 --- a/bin/named/include/named/server.h +++ b/bin/named/include/named/server.h @@ -50,6 +50,7 @@ struct ns_server { isc_quota_t xfroutquota; isc_quota_t tcpquota; isc_quota_t recursionquota; + isc_boolean_t provide_ixfr; /* Not really configurable, but covered by conflock. */ dns_aclenv_t aclenv; diff --git a/bin/named/server.c b/bin/named/server.c index e791688f92..334147f327 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -856,6 +856,9 @@ load_configuration(const char *filename, ns_server_t *server, configure_server_quota(configctx, dns_c_ctx_getrecursiveclients, &server->recursionquota, 100); + (void) dns_c_ctx_getprovideixfr(configctx, &server->provide_ixfr); + + /* * Configure the zone manager. */ @@ -1177,8 +1180,10 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) { result = isc_quota_init(&server->recursionquota, 100); RUNTIME_CHECK(result == ISC_R_SUCCESS); + server->provide_ixfr = ISC_TRUE; + result = dns_aclenv_init(mctx, &server->aclenv); - RUNTIME_CHECK(result == ISC_R_SUCCESS); + RUNTIME_CHECK(result == ISC_R_SUCCESS); /* Initialize server data structures. */ server->zonemgr = NULL; diff --git a/bin/named/xfrout.c b/bin/named/xfrout.c index da9590f4ae..274adad49f 100644 --- a/bin/named/xfrout.c +++ b/bin/named/xfrout.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: xfrout.c,v 1.47 2000/03/17 17:41:50 gson Exp $ */ +/* $Id: xfrout.c,v 1.48 2000/03/20 21:06:27 gson Exp $ */ #include @@ -795,6 +795,8 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) xfrout_ctx_t *xfr = NULL; isc_quota_t *quota = NULL; dns_transfer_format_t format = ns_g_server->transfer_format; + isc_netaddr_t na; + dns_peer_t *peer = NULL; switch (reqtype) { case dns_rdatatype_axfr: @@ -917,15 +919,14 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) FAILC(DNS_R_FORMERR, "attempted AXFR over UDP"); } + /* Look up the requesting server in the peer table. */ + isc_netaddr_fromsockaddr(&na, &client->peeraddr); + (void) dns_peerlist_peerbyaddr(client->view->peers, + &na, &peer); + /* Decide on the transfer format (one-answer or many-answers). */ - { - isc_netaddr_t na; - dns_peer_t *peer = NULL; - isc_netaddr_fromsockaddr(&na, &client->peeraddr); - if (dns_peerlist_peerbyaddr(client->view->peers, - &na, &peer) == ISC_R_SUCCESS) - (void) dns_peer_gettransferformat(peer, &format); - } + if (peer != NULL) + (void) dns_peer_gettransferformat(peer, &format); /* Get a dynamically allocated copy of the current SOA. */ CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, @@ -933,7 +934,18 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) if (reqtype == dns_rdatatype_ixfr) { isc_uint32_t begin_serial, current_serial; - + isc_boolean_t provide_ixfr; + + /* + * Outgoing IXFR may have been disabled for this peer + * or globally. + */ + provide_ixfr = ns_g_server->provide_ixfr; + if (peer != NULL) + (void) dns_peer_getprovideixfr(peer, &provide_ixfr); + if (provide_ixfr == ISC_FALSE) + goto axfr_fallback; + if (! have_soa) FAILC(DNS_R_FORMERR, "IXFR request missing SOA");