3. Serververhalten
3. Serververhalten
Ein Server signalisiert beim Empfang einer UPDATE-Anfrage NOTIMP an den Anforderer, wenn der UPDATE-Opcode nicht erkannt wird oder erkannt, aber nicht implementiert wurde. Andernfalls wird die Verarbeitung wie folgt fortgesetzt.
3.1 Zone-Abschnitt verarbeiten
3.1.1. Der Zone-Abschnitt wird überprüft, um sicherzustellen, dass dort genau ein RR vorhanden ist und dass der ZTYPE des RR SOA ist, andernfalls wird FORMERR an den Anforderer signalisiert. Als nächstes werden ZNAME und ZCLASS überprüft, um zu sehen, ob die so benannte Zone eine der Autoritätszonen dieses Servers ist, andernfalls wird NOTAUTH an den Anforderer signalisiert. Wenn der Server ein Zonenslave ist, wird die Anfrage an den primären Master weitergeleitet.
3.1.2 - Pseudocode für die Zone-Abschnittsverarbeitung
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)
Die Abschnitte 3.2 bis 3.8 beschreiben das Verhalten des primären Masters, während Abschnitt 6 das Verhalten eines Weiterleiters beschreibt.
3.2 Prerequisite-Abschnitt verarbeiten
Als nächstes wird der Prerequisite-Abschnitt überprüft, um sicherzustellen, dass alle Voraussetzungen durch den aktuellen Zustand der Zone erfüllt sind. Unter Verwendung der in Abschnitt 1.2 ausgedrückten Definitionen, wenn der NAME eines RR nicht innerhalb der im Zone-Abschnitt angegebenen Zone liegt, wird NOTZONE an den Anforderer signalisiert.
3.2.1. Für RRs in diesem Abschnitt, deren CLASS ANY ist, wird getestet, ob TTL und RDLENGTH beide null (0) sind, andernfalls wird FORMERR an den Anforderer signalisiert. Wenn TYPE ANY ist, wird getestet, ob mindestens ein RR in der Zone vorhanden ist, dessen NAME derselbe ist wie der des Prerequisite RR, andernfalls wird NXDOMAIN an den Anforderer signalisiert. Wenn TYPE nicht ANY ist, wird getestet, ob mindestens ein RR in der Zone vorhanden ist, dessen NAME und TYPE dieselben sind wie die des Prerequisite RR, andernfalls wird NXRRSET an den Anforderer signalisiert.
3.2.2. Für RRs in diesem Abschnitt, deren CLASS NONE ist, wird getestet, ob TTL und RDLENGTH beide null (0) sind, andernfalls wird FORMERR an den Anforderer signalisiert. Wenn TYPE ANY ist, wird getestet, ob keine RRs in der Zone vorhanden sind, deren NAME derselbe ist wie der des Prerequisite RR, andernfalls wird YXDOMAIN an den Anforderer signalisiert. Wenn TYPE nicht ANY ist, wird getestet, ob keine RRs in der Zone vorhanden sind, deren NAME und TYPE dieselben sind wie die des Prerequisite RR, andernfalls wird YXRRSET an den Anforderer signalisiert.
3.2.3. Für RRs in diesem Abschnitt, deren CLASS dieselbe ist wie ZCLASS, wird getestet, ob TTL null (0) ist, andernfalls wird FORMERR an den Anforderer signalisiert. Dann wird für jedes eindeutige <NAME,TYPE> ein RRset erstellt und jedes resultierende RRset auf Mengengleichheit (gleiche Mitglieder, nicht mehr, nicht weniger) mit RRsets in der Zone verglichen. Wenn ein Prerequisite RRset nicht vollständig und genau mit einem Zonen-RRset übereinstimmt, wird NXRRSET an den Anforderer signalisiert. Wenn ein RR in diesem Abschnitt eine CLASS hat, die nicht ZCLASS oder NONE oder ANY ist, wird FORMERR an den Anforderer signalisiert.
3.2.4 - Tabelle der im Prerequisite-Abschnitt verwendeten Metawerte
| CLASS | TYPE | RDATA | Bedeutung |
|---|---|---|---|
| ANY | ANY | leer | Name wird verwendet |
| ANY | rrset | leer | RRset existiert (wertunabhängig) |
| NONE | ANY | leer | Name wird nicht verwendet |
| NONE | rrset | leer | RRset existiert nicht |
| zone | rrset | rr | RRset existiert (wertabhängig) |
3.2.5 - Pseudocode für die Prerequisite-Abschnittsverarbeitung
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 Berechtigungen des Anforderers überprüfen
3.3.1. Als nächstes kann die Berechtigung des Anforderers zum Aktualisieren der im Update-Abschnitt genannten RRs auf implementierungsabhängige Weise oder unter Verwendung von Mechanismen getestet werden, die in einem nachfolgenden Secure DNS Update-Protokoll angegeben sind. Wenn der Anforderer keine Berechtigung hat, diese Updates durchzuführen, kann der Server eine Warnmeldung in sein Betriebsprotokoll schreiben und entweder REFUSED an den Anforderer signalisieren oder das Berechtigungsproblem ignorieren und mit dem Update fortfahren.
3.3.2. Während die genaue Verarbeitung implementierungsdefiniert ist, sollte dies der Punkt in der Verarbeitung des Servers sein, an dem eine solche Leistung stattfinden sollte, wenn diese Verifizierungsaktivitäten durchgeführt werden sollen, da es notwendig sein wird, das teilweise Update rückgängig zu machen und die Zone in ihren ursprünglichen Zustand zurückzuversetzen, bevor dem Anforderer geantwortet wird, wenn eine REFUSED-Bedingung auftritt, nachdem ein Update teilweise angewendet wurde.
3.3.3 - Pseudocode für die Berechtigungsüberprüfung
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 Update-Abschnitt verarbeiten
Als nächstes wird der Update-Abschnitt wie folgt verarbeitet.
3.4.1 - Vorscan
Der Update-Abschnitt wird in RRs geparst und die CLASS jedes RR wird überprüft, um zu sehen, ob sie ANY, NONE oder dieselbe wie die Zone Class ist, andernfalls wird FORMERR an den Anforderer signalisiert. Unter Verwendung der Definitionen in Abschnitt 1.2 muss der NAME jedes RR in der durch den Zone-Abschnitt angegebenen Zone liegen, andernfalls wird NOTZONE an den Anforderer signalisiert.
3.4.1.2. Für RRs, deren CLASS nicht ANY ist, wird TYPE überprüft, und wenn es ANY, AXFR, MAILA, MAILB oder ein anderer QUERY-Metatyp oder ein nicht erkannter Typ ist, wird FORMERR an den Anforderer signalisiert. Für RRs, deren CLASS ANY oder NONE ist, wird TTL überprüft, um sicherzustellen, dass es null (0) ist, andernfalls wird FORMERR an den Anforderer signalisiert. Für jeden RR, dessen CLASS ANY ist, wird RDLENGTH überprüft, um sicherzustellen, dass es null (0) ist (d.h. das RDATA-Feld leer ist), und dass TYPE nicht AXFR, MAILA, MAILB oder ein anderer QUERY-Metatyp außer ANY oder ein nicht erkannter Typ ist, andernfalls wird FORMERR an den Anforderer signalisiert.
3.4.1.3 - Pseudocode für Update-Abschnitts-Vorscan
[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
Der Update-Abschnitt wird in RRs geparst und diese RRs werden in der Reihenfolge verarbeitet.
3.4.2.1. Wenn während der Verarbeitung dieses Abschnitts ein Systemfehler auftritt (wie eine Speichermangelbedingung oder ein Hardwarefehler im persistenten Speicher), wird SERVFAIL an den Anforderer signalisiert und alle während dieser Transaktion auf die Zone angewendeten Updates werden rückgängig gemacht.
3.4.2.2. Jeder Update RR, dessen CLASS dieselbe ist wie ZCLASS, wird zur Zone hinzugefügt. Im Fall von doppelten RDATAs (was bei SOA RRs immer der Fall ist und bei WKS RRs der Fall ist, wenn die Felder ADDRESS und PROTOCOL beide übereinstimmen), wird der Zonen-RR durch Update RR ersetzt. Wenn TYPE SOA ist und kein Zonen-SOA RR vorhanden ist oder das neue SOA.SERIAL niedriger (gemäß [RFC1982]) ist als oder gleich dem SOA.SERIAL des aktuellen Zonen-SOA RR, wird der Update RR ignoriert. Im Fall eines CNAME Update RR und eines Nicht-CNAME Zonen-RRset oder umgekehrt wird der CNAME Update RR ignoriert, andernfalls wird der CNAME Zonen-RR durch den CNAME Update RR ersetzt.
3.4.2.3. Für jeden Update RR, dessen CLASS ANY ist und dessen TYPE ANY ist, werden alle Zonen-RRs mit demselben NAME gelöscht, es sei denn, der NAME ist derselbe wie ZNAME, in welchem Fall nur die RRs gelöscht werden, deren TYPE anders als SOA oder NS ist. Für jeden Update RR, dessen CLASS ANY ist und dessen TYPE nicht ANY ist, werden alle Zonen-RRs mit demselben NAME und TYPE gelöscht, es sei denn, der NAME ist derselbe wie ZNAME, in welchem Fall weder SOA noch NS RRs gelöscht werden.
3.4.2.4. Für jeden Update RR, dessen Klasse NONE ist, wird jeder Zonen-RR gelöscht, dessen NAME, TYPE, RDATA und RDLENGTH gleich dem Update RR sind, es sei denn, der NAME ist derselbe wie ZNAME und entweder der TYPE ist SOA oder der TYPE ist NS und der übereinstimmende Zonen-RR ist der einzige verbleibende NS im RRset, in welchem Fall dieser Update RR ignoriert wird.
3.4.2.5. NOERROR an den Anforderer signalisieren.
3.4.2.6 - Tabelle der im Update-Abschnitt verwendeten Metawerte
| CLASS | TYPE | RDATA | Bedeutung |
|---|---|---|---|
| ANY | ANY | leer | Alle RRsets von einem Namen löschen |
| ANY | rrset | leer | Ein RRset löschen |
| NONE | rrset | rr | Ein RR aus einem RRset löschen |
| zone | rrset | rr | Zu einem RRset hinzufügen |
3.4.2.7 - Pseudocode für die Update-Abschnittsverarbeitung
[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 Additional Data-Abschnitt verarbeiten
Die Additional Data-Verarbeitung wird in diesem Memo nicht beschrieben. Ein Server sollte RRs im Additional Data-Abschnitt, die mit der UPDATE-Verarbeitung zusammenhängen, stillschweigend ignorieren. Wenn der Additional Data-Abschnitt jedoch RRs enthält, die ein Server benötigt, um das Update nützlich zu machen (wie Glue-A-RRs für das Ziel eines neuen NS RR), sollte dieser Abschnitt verarbeitet werden.
3.6 Änderungen an Transaktionsprotokoll anhängen
Wenn die Zone über ein Transaktionsprotokoll verfügt, können die an der Zone vorgenommenen Änderungen an dieses angehängt werden, möglicherweise in Form einer minimalen UPDATE-Nachricht. Beachten Sie, dass das SOA SERIAL nur aktualisiert wird, wenn ein SOA RR Teil der UPDATE-Nachricht war oder wenn die Serverrichtlinie vorschreibt, dass das SOA SERIAL automatisch erhöht wird.
3.7 Antwort an Anforderer senden
An diesem Punkt muss die Antwortnachricht zusammengestellt und an den Anforderer zurückgesendet werden. Der Header enthält keine besonderen Optionen und der Zone-Abschnitt (Question-Abschnitt in Query) wird aus dem entsprechenden Abschnitt der Anfrage kopiert. PRCOUNT, UPCOUNT und ADCOUNT werden alle auf null (0) gesetzt. Der Antwortcode ist NOERROR, es sei denn, es ist ein Verarbeitungs- oder Berechtigungsfehler aufgetreten, in welchem Fall der entsprechende RCODE gesendet wird. Eine Kopie des aktuellen SOA RR der Zone sollte im Answer-Abschnitt der Antwort gesendet werden (auch im Fehlerfall), zum Nutzen von Anfordern, die UPDATE verwenden, um SOA-Parameter zu ändern und die Feedback bezüglich des tatsächlichen Status benötigen.
3.8 Slaves signalisieren
Der primäre Master sollte einen Mechanismus wie DNS NOTIFY (siehe [RFC1996]) verwenden, um bekannten Slaves zu signalisieren, dass die Zone aktualisiert wurde. Beachten Sie, dass diese Benachrichtigung auch dann gesendet werden sollte, wenn das SOA SERIAL aufgrund von Richtlinien- oder UPDATE-Inhalt nicht erhöht wurde.