mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 15:05:23 +00:00
complete slave side of notify
This commit is contained in:
@@ -39,6 +39,7 @@
|
|||||||
#include <named/log.h>
|
#include <named/log.h>
|
||||||
#include <named/query.h>
|
#include <named/query.h>
|
||||||
#include <named/update.h>
|
#include <named/update.h>
|
||||||
|
#include <named/notify.h>
|
||||||
|
|
||||||
#include "../../isc/util.h" /* XXX */
|
#include "../../isc/util.h" /* XXX */
|
||||||
|
|
||||||
@@ -644,7 +645,7 @@ client_request(isc_task_t *task, isc_event_t *event) {
|
|||||||
break;
|
break;
|
||||||
case dns_opcode_notify:
|
case dns_opcode_notify:
|
||||||
CTRACE("notify");
|
CTRACE("notify");
|
||||||
ns_client_error(client, DNS_R_NOTIMP);
|
ns_notify_start(client);
|
||||||
break;
|
break;
|
||||||
case dns_opcode_iquery:
|
case dns_opcode_iquery:
|
||||||
CTRACE("iquery");
|
CTRACE("iquery");
|
||||||
|
@@ -15,10 +15,37 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef named_notify_h
|
#ifndef NAMED_NOTIFY_H
|
||||||
#define named_notify_h
|
#define NAMED_NOTIFY_H 1
|
||||||
|
|
||||||
|
#include <named/types.h>
|
||||||
|
#include <named/client.h>
|
||||||
|
|
||||||
|
/***
|
||||||
|
*** Modual Info
|
||||||
|
***/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RFC 1996
|
||||||
|
* A Mechanism for Prompt Notification of Zone Changes (DNS NOTIFY)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/***
|
||||||
|
*** Functions.
|
||||||
|
***/
|
||||||
|
|
||||||
void
|
void
|
||||||
ns_notify_start(ns_client_t *client);
|
ns_notify_start(ns_client_t *client);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Examines the incoming message to determine apporiate zone.
|
||||||
|
* Returns FORMERR if there is not exactly one question.
|
||||||
|
* Returns REFUSED if we do not server the listed zone.
|
||||||
|
* Pass the message to the zone module for processing
|
||||||
|
* and returns the return status.
|
||||||
|
*
|
||||||
|
* Requires
|
||||||
|
* client to be valid.
|
||||||
|
*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -57,7 +57,7 @@
|
|||||||
#include <named/notify.h>
|
#include <named/notify.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This module implements notify as in RFCXXXX.
|
* This module implements notify as in RFC 1996.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
@@ -136,31 +136,25 @@
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
respond(ns_client_t *client, dns_result_t result) {
|
respond(ns_client_t *client, dns_result_t result) {
|
||||||
int msg_result;
|
dns_rcode_t rcode;
|
||||||
dns_message_t *response = NULL;
|
dns_message_t *message;
|
||||||
msg_result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTRENDER,
|
isc_result_t msg_result;
|
||||||
&response);
|
|
||||||
if (msg_result != DNS_R_SUCCESS)
|
|
||||||
goto msg_failure;
|
|
||||||
|
|
||||||
response->id = client->message->id;
|
message = client->message;
|
||||||
response->rcode = (result == DNS_R_SUCCESS ?
|
if (result == DNS_R_SUCCESS)
|
||||||
dns_rcode_noerror : dns_result_torcode(result));
|
rcode = dns_rcode_noerror;
|
||||||
response->flags = client->message->flags;
|
else
|
||||||
response->flags |= DNS_MESSAGEFLAG_QR;
|
rcode = dns_result_torcode(result);
|
||||||
response->opcode = client->message->opcode;
|
|
||||||
|
|
||||||
dns_message_destroy(&client->message);
|
msg_result = dns_message_reply(message, ISC_TRUE);
|
||||||
client->message = response;
|
if (msg_result != ISC_R_SUCCESS)
|
||||||
ns_client_send(client);
|
msg_result = dns_message_reply(message, ISC_FALSE);
|
||||||
return;
|
if (msg_result != ISC_R_SUCCESS) {
|
||||||
|
ns_client_next(client, msg_result);
|
||||||
msg_failure:
|
return;
|
||||||
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_NOTIFY, NS_LOGMODULE_NOTIFY,
|
}
|
||||||
ISC_LOG_ERROR,
|
message->rcode = rcode;
|
||||||
"could not create update response message: %s",
|
ns_client_send(client);
|
||||||
isc_result_totext(msg_result));
|
|
||||||
ns_client_next(client, msg_result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -205,12 +199,10 @@ ns_notify_start(ns_client_t *client)
|
|||||||
|
|
||||||
switch(dns_zone_gettype(zone)) {
|
switch(dns_zone_gettype(zone)) {
|
||||||
case dns_zone_master:
|
case dns_zone_master:
|
||||||
FAILC(DNS_R_REFUSED,
|
|
||||||
"notify to master");
|
|
||||||
case dns_zone_slave:
|
case dns_zone_slave:
|
||||||
respond(client, dns_zone_notifyreceive(zone,
|
respond(client, dns_zone_notifyreceive(zone,
|
||||||
ns_client_getsockaddr(client), request));
|
ns_client_getsockaddr(client), request));
|
||||||
return;
|
break;
|
||||||
default:
|
default:
|
||||||
FAILC(DNS_R_REFUSED,
|
FAILC(DNS_R_REFUSED,
|
||||||
"not authoritative for update zone");
|
"not authoritative for update zone");
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: zone.c,v 1.45 1999/12/15 17:14:52 explorer Exp $ */
|
/* $Id: zone.c,v 1.46 1999/12/16 01:23:15 marka Exp $ */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -573,10 +573,7 @@ dns_zone_load(dns_zone_t *zone) {
|
|||||||
REQUIRE(DNS_ZONE_VALID(zone));
|
REQUIRE(DNS_ZONE_VALID(zone));
|
||||||
|
|
||||||
LOCK(&zone->lock);
|
LOCK(&zone->lock);
|
||||||
if (isc_stdtime_get(&now) != ISC_R_SUCCESS) {
|
isc_stdtime_get(&now);
|
||||||
result = DNS_R_UNEXPECTED;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (zone->type) {
|
switch (zone->type) {
|
||||||
case dns_zone_forward:
|
case dns_zone_forward:
|
||||||
@@ -1512,8 +1509,7 @@ dns_zone_maintenance(dns_zone_t *zone) {
|
|||||||
REQUIRE(DNS_ZONE_VALID(zone));
|
REQUIRE(DNS_ZONE_VALID(zone));
|
||||||
DNS_ENTER;
|
DNS_ENTER;
|
||||||
|
|
||||||
if (isc_stdtime_get(&now) != ISC_R_SUCCESS)
|
isc_stdtime_get(&now);
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expire check.
|
* Expire check.
|
||||||
@@ -1644,8 +1640,7 @@ dns_zone_refresh(dns_zone_t *zone) {
|
|||||||
REQUIRE(DNS_ZONE_VALID(zone));
|
REQUIRE(DNS_ZONE_VALID(zone));
|
||||||
REQUIRE(zone->masterscnt > 0);
|
REQUIRE(zone->masterscnt > 0);
|
||||||
|
|
||||||
if (isc_stdtime_get(&now) != ISC_R_SUCCESS)
|
isc_stdtime_get(&now);
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set DNS_ZONE_F_REFRESH so that there is only one refresh operation
|
* Set DNS_ZONE_F_REFRESH so that there is only one refresh operation
|
||||||
@@ -2198,7 +2193,7 @@ zone_settimer(dns_zone_t *zone, isc_stdtime_t now) {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
zone_log(zone, me, ISC_LOG_INFO, "settimer %d %d = %d seconds\n",
|
zone_log(zone, me, ISC_LOG_INFO, "settimer %d %d = %d seconds",
|
||||||
next, now, next - now);
|
next, now, next - now);
|
||||||
|
|
||||||
if (next == 0) {
|
if (next == 0) {
|
||||||
@@ -2231,8 +2226,7 @@ cancel_refresh(dns_zone_t *zone) {
|
|||||||
|
|
||||||
REQUIRE(DNS_ZONE_VALID(zone));
|
REQUIRE(DNS_ZONE_VALID(zone));
|
||||||
zone->flags &= ~DNS_ZONE_F_REFRESH;
|
zone->flags &= ~DNS_ZONE_F_REFRESH;
|
||||||
if (isc_stdtime_get(&now) != ISC_R_SUCCESS)
|
isc_stdtime_get(&now);
|
||||||
return;
|
|
||||||
if (!DNS_ZONE_FLAG(zone, DNS_ZONE_F_EXITING))
|
if (!DNS_ZONE_FLAG(zone, DNS_ZONE_F_EXITING))
|
||||||
zone_settimer(zone, now);
|
zone_settimer(zone, now);
|
||||||
}
|
}
|
||||||
@@ -2305,11 +2299,13 @@ dns_result_t
|
|||||||
dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
|
dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
|
||||||
dns_message_t *msg)
|
dns_message_t *msg)
|
||||||
{
|
{
|
||||||
|
const char me[] = "dns_zone_notifyreceive";
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
dns_rdata_soa_t soa;
|
dns_rdata_soa_t soa;
|
||||||
dns_rdataset_t *rdataset = NULL;
|
dns_rdataset_t *rdataset = NULL;
|
||||||
dns_rdata_t rdata;
|
dns_rdata_t rdata;
|
||||||
dns_result_t result;
|
dns_result_t result;
|
||||||
|
isc_stdtime_t now;
|
||||||
|
|
||||||
REQUIRE(DNS_ZONE_VALID(zone));
|
REQUIRE(DNS_ZONE_VALID(zone));
|
||||||
|
|
||||||
@@ -2337,20 +2333,35 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
|
|||||||
* We only handle NOTIFY (SOA) at the present.
|
* We only handle NOTIFY (SOA) at the present.
|
||||||
*/
|
*/
|
||||||
LOCK(&zone->lock);
|
LOCK(&zone->lock);
|
||||||
if (msg->counts[DNS_SECTION_QUESTION] != 0 ||
|
if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
|
||||||
dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
|
dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
|
||||||
dns_rdatatype_soa, dns_rdatatype_none,
|
dns_rdatatype_soa, dns_rdatatype_none,
|
||||||
NULL, NULL) != DNS_R_SUCCESS) {
|
NULL, NULL) != DNS_R_SUCCESS) {
|
||||||
UNLOCK(&zone->lock);
|
UNLOCK(&zone->lock);
|
||||||
return (DNS_R_REFUSED);
|
if (msg->counts[DNS_SECTION_QUESTION] == 0) {
|
||||||
|
zone_log(zone, me, ISC_LOG_NOTICE,
|
||||||
|
"FORMERR no question");
|
||||||
|
return (DNS_R_FORMERR);
|
||||||
|
}
|
||||||
|
zone_log(zone, me, ISC_LOG_NOTICE,
|
||||||
|
"REFUSED zone does not match");
|
||||||
|
return (DNS_R_NOTIMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we are a master zone just succeed.
|
||||||
|
*/
|
||||||
|
if (zone->type == dns_zone_master)
|
||||||
|
return (DNS_R_SUCCESS);
|
||||||
|
|
||||||
for (i = 0; i < zone->masterscnt; i++)
|
for (i = 0; i < zone->masterscnt; i++)
|
||||||
if (isc_sockaddr_equal(from, &zone->masters[i]))
|
if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (i >= zone->masterscnt) {
|
if (i >= zone->masterscnt) {
|
||||||
UNLOCK(&zone->lock);
|
UNLOCK(&zone->lock);
|
||||||
|
zone_log(zone, me, ISC_LOG_NOTICE,
|
||||||
|
"REFUSED notify from non master");
|
||||||
return (DNS_R_REFUSED);
|
return (DNS_R_REFUSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2378,8 +2389,11 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
|
|||||||
if (result == DNS_R_SUCCESS) {
|
if (result == DNS_R_SUCCESS) {
|
||||||
serial = soa.serial;
|
serial = soa.serial;
|
||||||
dns_rdata_freestruct(&soa);
|
dns_rdata_freestruct(&soa);
|
||||||
if (isc_serial_le(serial, zone->serial))
|
if (isc_serial_le(serial, zone->serial)) {
|
||||||
|
zone_log(zone, me, ISC_LOG_DEBUG(3),
|
||||||
|
"zone up to date");
|
||||||
return (DNS_R_SUCCESS);
|
return (DNS_R_SUCCESS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2393,10 +2407,16 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
|
|||||||
zone->flags |= DNS_ZONE_F_NEEDREFRESH;
|
zone->flags |= DNS_ZONE_F_NEEDREFRESH;
|
||||||
zone->notifyfrom = *from;
|
zone->notifyfrom = *from;
|
||||||
UNLOCK(&zone->lock);
|
UNLOCK(&zone->lock);
|
||||||
|
zone_log(zone, me, ISC_LOG_DEBUG(3),
|
||||||
|
"refresh in progress, refresh check queued");
|
||||||
return (DNS_R_SUCCESS);
|
return (DNS_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
isc_stdtime_get(&now);
|
||||||
|
zone->refreshtime = now;
|
||||||
|
zone->notifyfrom = *from;
|
||||||
|
zone_settimer(zone, now);
|
||||||
UNLOCK(&zone->lock);
|
UNLOCK(&zone->lock);
|
||||||
dns_zone_refresh(zone);
|
zone_log(zone, me, ISC_LOG_DEBUG(3), "immediate refresh check queued");
|
||||||
return (DNS_R_SUCCESS);
|
return (DNS_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3250,9 +3270,12 @@ xfrdone(dns_zone_t *zone, dns_result_t result) {
|
|||||||
switch (result) {
|
switch (result) {
|
||||||
case DNS_R_UPTODATE:
|
case DNS_R_UPTODATE:
|
||||||
case DNS_R_SUCCESS:
|
case DNS_R_SUCCESS:
|
||||||
if (isc_stdtime_get(&now) != ISC_R_SUCCESS)
|
isc_stdtime_get(&now);
|
||||||
return;
|
if (DNS_ZONE_FLAG(zone, DNS_ZONE_F_NEEDREFRESH)) {
|
||||||
zone->refreshtime = now + zone->refresh;
|
zone->flags &= ~DNS_ZONE_F_NEEDREFRESH;
|
||||||
|
zone->refreshtime = now;
|
||||||
|
} else
|
||||||
|
zone->refreshtime = now + zone->refresh;
|
||||||
zone_settimer(zone, now);
|
zone_settimer(zone, now);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user