mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
complete slave side of notify
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
#include <named/log.h>
|
||||
#include <named/query.h>
|
||||
#include <named/update.h>
|
||||
#include <named/notify.h>
|
||||
|
||||
#include "../../isc/util.h" /* XXX */
|
||||
|
||||
@@ -644,7 +645,7 @@ client_request(isc_task_t *task, isc_event_t *event) {
|
||||
break;
|
||||
case dns_opcode_notify:
|
||||
CTRACE("notify");
|
||||
ns_client_error(client, DNS_R_NOTIMP);
|
||||
ns_notify_start(client);
|
||||
break;
|
||||
case dns_opcode_iquery:
|
||||
CTRACE("iquery");
|
||||
|
@@ -15,10 +15,37 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef named_notify_h
|
||||
#define named_notify_h
|
||||
#ifndef 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
|
||||
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
|
||||
|
@@ -57,7 +57,7 @@
|
||||
#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
|
||||
respond(ns_client_t *client, dns_result_t result) {
|
||||
int msg_result;
|
||||
dns_message_t *response = NULL;
|
||||
msg_result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTRENDER,
|
||||
&response);
|
||||
if (msg_result != DNS_R_SUCCESS)
|
||||
goto msg_failure;
|
||||
dns_rcode_t rcode;
|
||||
dns_message_t *message;
|
||||
isc_result_t msg_result;
|
||||
|
||||
response->id = client->message->id;
|
||||
response->rcode = (result == DNS_R_SUCCESS ?
|
||||
dns_rcode_noerror : dns_result_torcode(result));
|
||||
response->flags = client->message->flags;
|
||||
response->flags |= DNS_MESSAGEFLAG_QR;
|
||||
response->opcode = client->message->opcode;
|
||||
message = client->message;
|
||||
if (result == DNS_R_SUCCESS)
|
||||
rcode = dns_rcode_noerror;
|
||||
else
|
||||
rcode = dns_result_torcode(result);
|
||||
|
||||
dns_message_destroy(&client->message);
|
||||
client->message = response;
|
||||
ns_client_send(client);
|
||||
return;
|
||||
|
||||
msg_failure:
|
||||
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_NOTIFY, NS_LOGMODULE_NOTIFY,
|
||||
ISC_LOG_ERROR,
|
||||
"could not create update response message: %s",
|
||||
isc_result_totext(msg_result));
|
||||
ns_client_next(client, msg_result);
|
||||
msg_result = dns_message_reply(message, ISC_TRUE);
|
||||
if (msg_result != ISC_R_SUCCESS)
|
||||
msg_result = dns_message_reply(message, ISC_FALSE);
|
||||
if (msg_result != ISC_R_SUCCESS) {
|
||||
ns_client_next(client, msg_result);
|
||||
return;
|
||||
}
|
||||
message->rcode = rcode;
|
||||
ns_client_send(client);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -205,12 +199,10 @@ ns_notify_start(ns_client_t *client)
|
||||
|
||||
switch(dns_zone_gettype(zone)) {
|
||||
case dns_zone_master:
|
||||
FAILC(DNS_R_REFUSED,
|
||||
"notify to master");
|
||||
case dns_zone_slave:
|
||||
respond(client, dns_zone_notifyreceive(zone,
|
||||
ns_client_getsockaddr(client), request));
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
FAILC(DNS_R_REFUSED,
|
||||
"not authoritative for update zone");
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* 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>
|
||||
|
||||
@@ -573,10 +573,7 @@ dns_zone_load(dns_zone_t *zone) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
LOCK(&zone->lock);
|
||||
if (isc_stdtime_get(&now) != ISC_R_SUCCESS) {
|
||||
result = DNS_R_UNEXPECTED;
|
||||
goto cleanup;
|
||||
}
|
||||
isc_stdtime_get(&now);
|
||||
|
||||
switch (zone->type) {
|
||||
case dns_zone_forward:
|
||||
@@ -1512,8 +1509,7 @@ dns_zone_maintenance(dns_zone_t *zone) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
DNS_ENTER;
|
||||
|
||||
if (isc_stdtime_get(&now) != ISC_R_SUCCESS)
|
||||
return;
|
||||
isc_stdtime_get(&now);
|
||||
|
||||
/*
|
||||
* Expire check.
|
||||
@@ -1644,8 +1640,7 @@ dns_zone_refresh(dns_zone_t *zone) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
REQUIRE(zone->masterscnt > 0);
|
||||
|
||||
if (isc_stdtime_get(&now) != ISC_R_SUCCESS)
|
||||
return;
|
||||
isc_stdtime_get(&now);
|
||||
|
||||
/*
|
||||
* 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:
|
||||
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);
|
||||
|
||||
if (next == 0) {
|
||||
@@ -2231,8 +2226,7 @@ cancel_refresh(dns_zone_t *zone) {
|
||||
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
zone->flags &= ~DNS_ZONE_F_REFRESH;
|
||||
if (isc_stdtime_get(&now) != ISC_R_SUCCESS)
|
||||
return;
|
||||
isc_stdtime_get(&now);
|
||||
if (!DNS_ZONE_FLAG(zone, DNS_ZONE_F_EXITING))
|
||||
zone_settimer(zone, now);
|
||||
}
|
||||
@@ -2305,11 +2299,13 @@ dns_result_t
|
||||
dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
|
||||
dns_message_t *msg)
|
||||
{
|
||||
const char me[] = "dns_zone_notifyreceive";
|
||||
unsigned int i;
|
||||
dns_rdata_soa_t soa;
|
||||
dns_rdataset_t *rdataset = NULL;
|
||||
dns_rdata_t rdata;
|
||||
dns_result_t result;
|
||||
isc_stdtime_t now;
|
||||
|
||||
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.
|
||||
*/
|
||||
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_rdatatype_soa, dns_rdatatype_none,
|
||||
NULL, NULL) != DNS_R_SUCCESS) {
|
||||
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++)
|
||||
if (isc_sockaddr_equal(from, &zone->masters[i]))
|
||||
if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
|
||||
break;
|
||||
|
||||
if (i >= zone->masterscnt) {
|
||||
UNLOCK(&zone->lock);
|
||||
zone_log(zone, me, ISC_LOG_NOTICE,
|
||||
"REFUSED notify from non master");
|
||||
return (DNS_R_REFUSED);
|
||||
}
|
||||
|
||||
@@ -2378,8 +2389,11 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
|
||||
if (result == DNS_R_SUCCESS) {
|
||||
serial = soa.serial;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2393,10 +2407,16 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
|
||||
zone->flags |= DNS_ZONE_F_NEEDREFRESH;
|
||||
zone->notifyfrom = *from;
|
||||
UNLOCK(&zone->lock);
|
||||
zone_log(zone, me, ISC_LOG_DEBUG(3),
|
||||
"refresh in progress, refresh check queued");
|
||||
return (DNS_R_SUCCESS);
|
||||
}
|
||||
isc_stdtime_get(&now);
|
||||
zone->refreshtime = now;
|
||||
zone->notifyfrom = *from;
|
||||
zone_settimer(zone, now);
|
||||
UNLOCK(&zone->lock);
|
||||
dns_zone_refresh(zone);
|
||||
zone_log(zone, me, ISC_LOG_DEBUG(3), "immediate refresh check queued");
|
||||
return (DNS_R_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -3250,9 +3270,12 @@ xfrdone(dns_zone_t *zone, dns_result_t result) {
|
||||
switch (result) {
|
||||
case DNS_R_UPTODATE:
|
||||
case DNS_R_SUCCESS:
|
||||
if (isc_stdtime_get(&now) != ISC_R_SUCCESS)
|
||||
return;
|
||||
zone->refreshtime = now + zone->refresh;
|
||||
isc_stdtime_get(&now);
|
||||
if (DNS_ZONE_FLAG(zone, DNS_ZONE_F_NEEDREFRESH)) {
|
||||
zone->flags &= ~DNS_ZONE_F_NEEDREFRESH;
|
||||
zone->refreshtime = now;
|
||||
} else
|
||||
zone->refreshtime = now + zone->refresh;
|
||||
zone_settimer(zone, now);
|
||||
break;
|
||||
|
||||
|
Reference in New Issue
Block a user