Skip to main content

3. Server Behavior

3. Server Behavior

A server, upon receiving an UPDATE request, will signal NOTIMP to the requestor if the UPDATE opcode is not recognized or if it is recognized but has not been implemented. Otherwise, processing continues as follows.

3.1 Process Zone Section

3.1.1. The Zone Section is checked to see that there is exactly one RR therein and that the RR's ZTYPE is SOA, else signal FORMERR to the requestor. Next, the ZNAME and ZCLASS are checked to see if the zone so named is one of this server's authority zones, else signal NOTAUTH to the requestor. If the server is a zone slave, the request will be forwarded toward the primary master.

3.1.2 - Pseudocode For Zone Section Processing

if (zcount != 1 || ztype != SOA)
return (FORMERR)
if (zone_type(zname, zclass) == SLAVE)
return forward()
if (zone_type(zname, zclass) == MASTER)
return update()
return (NOTAUTH)

Sections 3.2 through 3.8 describe the primary master's behaviour, whereas Section 6 describes a forwarder's behaviour.

3.2 Process Prerequisite Section

Next, the Prerequisite Section is checked to see that all prerequisites are satisfied by the current state of the zone. Using the definitions expressed in Section 1.2, if any RR's NAME is not within the zone specified in the Zone Section, signal NOTZONE to the requestor.

3.2.1. For RRs in this section whose CLASS is ANY, test to see that TTL and RDLENGTH are both zero (0), else signal FORMERR to the requestor. If TYPE is ANY, test to see that there is at least one RR in the zone whose NAME is the same as that of the Prerequisite RR, else signal NXDOMAIN to the requestor. If TYPE is not ANY, test to see that there is at least one RR in the zone whose NAME and TYPE are the same as that of the Prerequisite RR, else signal NXRRSET to the requestor.

3.2.2. For RRs in this section whose CLASS is NONE, test to see that the TTL and RDLENGTH are both zero (0), else signal FORMERR to the requestor. If the TYPE is ANY, test to see that there are no RRs in the zone whose NAME is the same as that of the Prerequisite RR, else signal YXDOMAIN to the requestor. If the TYPE is not ANY, test to see that there are no RRs in the zone whose NAME and TYPE are the same as that of the Prerequisite RR, else signal YXRRSET to the requestor.

3.2.3. For RRs in this section whose CLASS is the same as the ZCLASS, test to see that the TTL is zero (0), else signal FORMERR to the requestor. Then, build an RRset for each unique <NAME,TYPE> and compare each resulting RRset for set equality (same members, no more, no less) with RRsets in the zone. If any Prerequisite RRset is not entirely and exactly matched by a zone RRset, signal NXRRSET to the requestor. If any RR in this section has a CLASS other than ZCLASS or NONE or ANY, signal FORMERR to the requestor.

3.2.4 - Table Of Metavalues Used In Prerequisite Section

CLASSTYPERDATAMeaning
ANYANYemptyName is in use
ANYrrsetemptyRRset exists (value independent)
NONEANYemptyName is not in use
NONErrsetemptyRRset does not exist
zonerrsetrrRRset exists (value dependent)

3.2.5 - Pseudocode for Prerequisite Section Processing

for rr in prerequisites
if (rr.ttl != 0)
return (FORMERR)
if (zone_of(rr.name) != ZNAME)
return (NOTZONE);
if (rr.class == ANY)
if (rr.rdlength != 0)
return (FORMERR)
if (rr.type == ANY)
if (!zone_name<rr.name>)
return (NXDOMAIN)
else
if (!zone_rrset<rr.name, rr.type>)
return (NXRRSET)
if (rr.class == NONE)
if (rr.rdlength != 0)
return (FORMERR)
if (rr.type == ANY)
if (zone_name<rr.name>)
return (YXDOMAIN)
else
if (zone_rrset<rr.name, rr.type>)
return (YXRRSET)
if (rr.class == zclass)
temp<rr.name, rr.type> += rr
else
return (FORMERR)

for rrset in temp
if (zone_rrset<rrset.name, rrset.type> != rrset)
return (NXRRSET)

3.3 Check Requestor's Permissions

3.3.1. Next, the requestor's permission to update the RRs named in the Update Section may be tested in an implementation dependent fashion or using mechanisms specified in a subsequent Secure DNS Update protocol. If the requestor does not have permission to perform these updates, the server may write a warning message in its operations log, and may either signal REFUSED to the requestor, or ignore the permission problem and proceed with the update.

3.3.2. While the exact processing is implementation defined, if these verification activities are to be performed, this is the point in the server's processing where such performance should take place, since if a REFUSED condition is encountered after an update has been partially applied, it will be necessary to undo the partial update and restore the zone to its original state before answering the requestor.

3.3.3 - Pseudocode for Permission Checking

if (security policy exists)
if (this update is not permitted)
if (local option)
log a message about permission problem
if (local option)
return (REFUSED)

3.4 Process Update Section

Next, the Update Section is processed as follows.

3.4.1 - Prescan

The Update Section is parsed into RRs and each RR's CLASS is checked to see if it is ANY, NONE, or the same as the Zone Class, else signal a FORMERR to the requestor. Using the definitions in Section 1.2, each RR's NAME must be in the zone specified by the Zone Section, else signal NOTZONE to the requestor.

3.4.1.2. For RRs whose CLASS is not ANY, check the TYPE and if it is ANY, AXFR, MAILA, MAILB, or any other QUERY metatype, or any unrecognized type, then signal FORMERR to the requestor. For RRs whose CLASS is ANY or NONE, check the TTL to see that it is zero (0), else signal a FORMERR to the requestor. For any RR whose CLASS is ANY, check the RDLENGTH to make sure that it is zero (0) (that is, the RDATA field is empty), and that the TYPE is not AXFR, MAILA, MAILB, or any other QUERY metatype besides ANY, or any unrecognized type, else signal FORMERR to the requestor.

3.4.1.3 - Pseudocode For Update Section Prescan

[rr] for rr in updates
if (zone_of(rr.name) != ZNAME)
return (NOTZONE);
if (rr.class == zclass)
if (rr.type & ANY|AXFR|MAILA|MAILB)
return (FORMERR)
elsif (rr.class == ANY)
if (rr.ttl != 0 || rr.rdlength != 0
|| rr.type & AXFR|MAILA|MAILB)
return (FORMERR)
elsif (rr.class == NONE)
if (rr.ttl != 0 || rr.type & ANY|AXFR|MAILA|MAILB)
return (FORMERR)
else
return (FORMERR)

3.4.2 - Update

The Update Section is parsed into RRs and these RRs are processed in order.

3.4.2.1. If any system failure (such as an out of memory condition, or a hardware error in persistent storage) occurs during the processing of this section, signal SERVFAIL to the requestor and undo all updates applied to the zone during this transaction.

3.4.2.2. Any Update RR whose CLASS is the same as ZCLASS is added to the zone. In case of duplicate RDATAs (which for SOA RRs is always the case, and for WKS RRs is the case if the ADDRESS and PROTOCOL fields both match), the Zone RR is replaced by Update RR. If the TYPE is SOA and there is no Zone SOA RR, or the new SOA.SERIAL is lower (according to [RFC1982]) than or equal to the current Zone SOA RR's SOA.SERIAL, the Update RR is ignored. In the case of a CNAME Update RR and a non-CNAME Zone RRset or vice versa, ignore the CNAME Update RR, otherwise replace the CNAME Zone RR with the CNAME Update RR.

3.4.2.3. For any Update RR whose CLASS is ANY and whose TYPE is ANY, all Zone RRs with the same NAME are deleted, unless the NAME is the same as ZNAME in which case only those RRs whose TYPE is other than SOA or NS are deleted. For any Update RR whose CLASS is ANY and whose TYPE is not ANY all Zone RRs with the same NAME and TYPE are deleted, unless the NAME is the same as ZNAME in which case neither SOA or NS RRs will be deleted.

3.4.2.4. For any Update RR whose class is NONE, any Zone RR whose NAME, TYPE, RDATA and RDLENGTH are equal to the Update RR is deleted, unless the NAME is the same as ZNAME and either the TYPE is SOA or the TYPE is NS and the matching Zone RR is the only NS remaining in the RRset, in which case this Update RR is ignored.

3.4.2.5. Signal NOERROR to the requestor.

3.4.2.6 - Table Of Metavalues Used In Update Section

CLASSTYPERDATAMeaning
ANYANYemptyDelete all RRsets from a name
ANYrrsetemptyDelete an RRset
NONErrsetrrDelete an RR from an RRset
zonerrsetrrAdd to an RRset

3.4.2.7 - Pseudocode For Update Section Processing

[rr] for rr in updates
if (rr.class == zclass)
if (rr.type == CNAME)
if (zone_rrset<rr.name, ~CNAME>)
next [rr]
elsif (zone_rrset<rr.name, CNAME>)
next [rr]
if (rr.type == SOA)
if (!zone_rrset<rr.name, SOA> ||
zone_rr<rr.name, SOA>.serial > rr.soa.serial)
zone_rr<rr.name, SOA> = rr
elsif (rr.type == WKS)
if (zone_rrset<rr.name, WKS, rr.proto, rr.address>)
zone_rr<rr.name, WKS, rr.proto, rr.address> = rr
else
zone_rrset<rr.name, WKS> += rr
else
zone_rrset<rr.name, rr.type> += rr
elsif (rr.class == ANY)
if (rr.type == ANY)
if (rr.name == zname)
zone_rrset<rr.name, ~(SOA|NS)> = Nil
else
zone_rrset<rr.name, *> = Nil
elsif (rr.name == zname &&
(rr.type == SOA || rr.type == NS))
next [rr]
else
zone_rrset<rr.name, rr.type> = Nil
elsif (rr.class == NONE)
if (rr.type == SOA)
next [rr]
if (rr.type == NS && zone_rrset<rr.name, NS> == rr)
next [rr]
zone_rr<rr.name, rr.type, rr.data> = Nil
return (NOERROR)

3.5 Process Additional Data Section

Additional Data processing is not described in this memo. A server should silently ignore RRs in the Additional Data Section which are related to UPDATE processing. However, if the Additional Data Section contains RRs which a server will need in order to make the update useful (such as glue A RRs for the target of a new NS RR), then this section should be processed.

3.6 Append Changes to Transaction Log

If the zone has a transaction log, the changes made to the zone MAY be appended to it, perhaps in the form of a minimal UPDATE message. Note that the SOA SERIAL will only be updated if an SOA RR was part of the UPDATE message, or if the server policy dictates that the SOA SERIAL be auto-incremented.

3.7 Send Response to Requestor

At this point, the response message must be assembled and sent back to the requestor. The header contains no special options and the Zone Section (Question Section in Query) is copied from the corresponding section of the request. The PRCOUNT, UPCOUNT, and ADCOUNT are all set to zero (0). The response code is NOERROR, unless some processing or permission error occurred, in which case the appropriate RCODE is sent. A copy of the zone's current SOA RR should be sent in the Answer Section of the response (even in the case of error), for the benefit of requestors who are using UPDATE to change SOA parameters and who require feedback regarding the actual status.

3.8 Signal Slaves

The primary master should use a mechanism such as DNS NOTIFY (see [RFC1996]) to signal any known slaves that the zone has been updated. Note that this notify should be sent even if the SOA SERIAL was not incremented due to policy or UPDATE content.