3. Comportamento del Server
3. Comportamento del Server
Un server, alla ricezione di una richiesta UPDATE, segnalerà NOTIMP al richiedente se l'opcode UPDATE non è riconosciuto o se è riconosciuto ma non è stato implementato. Altrimenti, l'elaborazione continua come segue.
3.1 Elaborare la Sezione Zone
3.1.1. La sezione Zone viene controllata per verificare che ci sia esattamente un RR e che il ZTYPE dell'RR sia SOA, altrimenti segnalare FORMERR al richiedente. Successivamente, ZNAME e ZCLASS vengono controllati per vedere se la zona così denominata è una delle zone di autorità di questo server, altrimenti segnalare NOTAUTH al richiedente. Se il server è uno slave di zona, la richiesta verrà inoltrata al master principale.
3.1.2 - Pseudocodice per l'Elaborazione della Sezione Zone
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)
Le sezioni da 3.2 a 3.8 descrivono il comportamento del master principale, mentre la sezione 6 descrive il comportamento di un forwarder.
3.2 Elaborare la Sezione Prerequisite
Successivamente, la sezione Prerequisite viene controllata per verificare che tutti i prerequisiti siano soddisfatti dallo stato attuale della zona. Utilizzando le definizioni espresse nella sezione 1.2, se il NAME di un RR non si trova all'interno della zona specificata nella sezione Zone, segnalare NOTZONE al richiedente.
3.2.1. Per gli RR in questa sezione il cui CLASS è ANY, testare per vedere che TTL e RDLENGTH siano entrambi zero (0), altrimenti segnalare FORMERR al richiedente. Se TYPE è ANY, testare per vedere che ci sia almeno un RR nella zona il cui NAME è lo stesso di quello dell'RR Prerequisite, altrimenti segnalare NXDOMAIN al richiedente. Se TYPE non è ANY, testare per vedere che ci sia almeno un RR nella zona il cui NAME e TYPE sono gli stessi di quelli dell'RR Prerequisite, altrimenti segnalare NXRRSET al richiedente.
3.2.2. Per gli RR in questa sezione il cui CLASS è NONE, testare per vedere che TTL e RDLENGTH siano entrambi zero (0), altrimenti segnalare FORMERR al richiedente. Se TYPE è ANY, testare per vedere che non ci siano RR nella zona il cui NAME è lo stesso di quello dell'RR Prerequisite, altrimenti segnalare YXDOMAIN al richiedente. Se TYPE non è ANY, testare per vedere che non ci siano RR nella zona il cui NAME e TYPE sono gli stessi di quelli dell'RR Prerequisite, altrimenti segnalare YXRRSET al richiedente.
3.2.3. Per gli RR in questa sezione il cui CLASS è lo stesso di ZCLASS, testare per vedere che TTL sia zero (0), altrimenti segnalare FORMERR al richiedente. Quindi, costruire un RRset per ogni <NAME,TYPE> univoco e confrontare ogni RRset risultante per l'uguaglianza dell'insieme (stessi membri, né più né meno) con gli RRset nella zona. Se un RRset Prerequisite non è completamente ed esattamente corrisposto da un RRset di zona, segnalare NXRRSET al richiedente. Se un RR in questa sezione ha un CLASS diverso da ZCLASS o NONE o ANY, segnalare FORMERR al richiedente.
3.2.4 - Tabella dei Metavalori Utilizzati nella Sezione Prerequisite
| CLASS | TYPE | RDATA | Significato |
|---|---|---|---|
| ANY | ANY | vuoto | Il nome è in uso |
| ANY | rrset | vuoto | L'RRset esiste (indipendente dal valore) |
| NONE | ANY | vuoto | Il nome non è in uso |
| NONE | rrset | vuoto | L'RRset non esiste |
| zone | rrset | rr | L'RRset esiste (dipendente dal valore) |
3.2.5 - Pseudocodice per l'Elaborazione della Sezione Prerequisite
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 Controllare i Permessi del Richiedente
3.3.1. Successivamente, il permesso del richiedente di aggiornare gli RR denominati nella sezione Update può essere testato in modo dipendente dall'implementazione o utilizzando meccanismi specificati in un successivo protocollo Secure DNS Update. Se il richiedente non ha il permesso di eseguire questi aggiornamenti, il server può scrivere un messaggio di avviso nel suo log delle operazioni e può segnalare REFUSED al richiedente o ignorare il problema di permesso e procedere con l'aggiornamento.
3.3.2. Mentre l'elaborazione esatta è definita dall'implementazione, se queste attività di verifica devono essere eseguite, questo è il punto nell'elaborazione del server dove tale prestazione dovrebbe avvenire, poiché se si verifica una condizione REFUSED dopo che un aggiornamento è stato applicato parzialmente, sarà necessario annullare l'aggiornamento parziale e ripristinare la zona al suo stato originale prima di rispondere al richiedente.
3.3.3 - Pseudocodice per il Controllo dei Permessi
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 Elaborare la Sezione Update
Successivamente, la sezione Update viene elaborata come segue.
3.4.1 - Prescan
La sezione Update viene analizzata in RR e il CLASS di ogni RR viene controllato per vedere se è ANY, NONE o lo stesso della Zone Class, altrimenti segnalare FORMERR al richiedente. Utilizzando le definizioni nella sezione 1.2, il NAME di ogni RR deve essere nella zona specificata dalla sezione Zone, altrimenti segnalare NOTZONE al richiedente.
3.4.1.2. Per gli RR il cui CLASS non è ANY, controllare TYPE e se è ANY, AXFR, MAILA, MAILB o qualsiasi altro metatipo QUERY, o qualsiasi tipo non riconosciuto, quindi segnalare FORMERR al richiedente. Per gli RR il cui CLASS è ANY o NONE, controllare TTL per vedere che sia zero (0), altrimenti segnalare FORMERR al richiedente. Per qualsiasi RR il cui CLASS è ANY, controllare RDLENGTH per assicurarsi che sia zero (0) (cioè, il campo RDATA è vuoto) e che TYPE non sia AXFR, MAILA, MAILB o qualsiasi altro metatipo QUERY oltre a ANY, o qualsiasi tipo non riconosciuto, altrimenti segnalare FORMERR al richiedente.
3.4.1.3 - Pseudocodice per il Prescan della Sezione Update
[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 - Aggiornamento
La sezione Update viene analizzata in RR e questi RR vengono elaborati in ordine.
3.4.2.1. Se si verifica un guasto del sistema (come una condizione di esaurimento della memoria o un errore hardware nello storage persistente) durante l'elaborazione di questa sezione, segnalare SERVFAIL al richiedente e annullare tutti gli aggiornamenti applicati alla zona durante questa transazione.
3.4.2.2. Qualsiasi RR Update il cui CLASS è lo stesso di ZCLASS viene aggiunto alla zona. In caso di RDATA duplicati (che per gli RR SOA è sempre il caso, e per gli RR WKS è il caso se i campi ADDRESS e PROTOCOL corrispondono entrambi), l'RR Zone viene sostituito dall'RR Update. Se TYPE è SOA e non c'è RR SOA Zone, o il nuovo SOA.SERIAL è inferiore (secondo [RFC1982]) o uguale al SOA.SERIAL dell'attuale RR SOA Zone, l'RR Update viene ignorato. Nel caso di un RR Update CNAME e un RRset Zone non-CNAME o viceversa, ignorare l'RR Update CNAME, altrimenti sostituire l'RR Zone CNAME con l'RR Update CNAME.
3.4.2.3. Per qualsiasi RR Update il cui CLASS è ANY e il cui TYPE è ANY, tutti gli RR Zone con lo stesso NAME vengono eliminati, a meno che NAME sia lo stesso di ZNAME nel qual caso vengono eliminati solo quegli RR il cui TYPE è diverso da SOA o NS. Per qualsiasi RR Update il cui CLASS è ANY e il cui TYPE non è ANY, tutti gli RR Zone con lo stesso NAME e TYPE vengono eliminati, a meno che NAME sia lo stesso di ZNAME nel qual caso né gli RR SOA né NS verranno eliminati.
3.4.2.4. Per qualsiasi RR Update la cui classe è NONE, qualsiasi RR Zone il cui NAME, TYPE, RDATA e RDLENGTH sono uguali all'RR Update viene eliminato, a meno che NAME sia lo stesso di ZNAME e o TYPE è SOA o TYPE è NS e l'RR Zone corrispondente è l'unico NS rimanente nell'RRset, nel qual caso questo RR Update viene ignorato.
3.4.2.5. Segnalare NOERROR al richiedente.
3.4.2.6 - Tabella dei Metavalori Utilizzati nella Sezione Update
| CLASS | TYPE | RDATA | Significato |
|---|---|---|---|
| ANY | ANY | vuoto | Eliminare tutti gli RRset da un nome |
| ANY | rrset | vuoto | Eliminare un RRset |
| NONE | rrset | rr | Eliminare un RR da un RRset |
| zone | rrset | rr | Aggiungere a un RRset |
3.4.2.7 - Pseudocodice per l'Elaborazione della Sezione Update
[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 Elaborare la Sezione Additional Data
L'elaborazione di Additional Data non è descritta in questo memo. Un server dovrebbe silenziosamente ignorare gli RR nella sezione Additional Data che sono correlati all'elaborazione UPDATE. Tuttavia, se la sezione Additional Data contiene RR di cui un server avrà bisogno per rendere utile l'aggiornamento (come i RR A glue per il target di un nuovo RR NS), allora questa sezione dovrebbe essere elaborata.
3.6 Aggiungere le Modifiche al Log delle Transazioni
Se la zona ha un log delle transazioni, le modifiche apportate alla zona POSSONO essere aggiunte ad esso, forse sotto forma di un messaggio UPDATE minimo. Si noti che il SOA SERIAL verrà aggiornato solo se un RR SOA faceva parte del messaggio UPDATE, o se la policy del server detta che il SOA SERIAL sia auto-incrementato.
3.7 Inviare la Risposta al Richiedente
A questo punto, il messaggio di risposta deve essere assemblato e inviato indietro al richiedente. L'intestazione non contiene opzioni speciali e la sezione Zone (sezione Question in Query) viene copiata dalla sezione corrispondente della richiesta. PRCOUNT, UPCOUNT e ADCOUNT sono tutti impostati a zero (0). Il codice di risposta è NOERROR, a meno che non si sia verificato un errore di elaborazione o di permesso, nel qual caso viene inviato l'RCODE appropriato. Una copia dell'attuale RR SOA della zona dovrebbe essere inviata nella sezione Answer della risposta (anche in caso di errore), per il beneficio dei richiedenti che utilizzano UPDATE per modificare i parametri SOA e che richiedono un feedback riguardo allo stato effettivo.
3.8 Segnalare agli Slave
Il master principale dovrebbe utilizzare un meccanismo come DNS NOTIFY (vedi [RFC1996]) per segnalare a qualsiasi slave noto che la zona è stata aggiornata. Si noti che questa notifica dovrebbe essere inviata anche se il SOA SERIAL non è stato incrementato a causa della policy o del contenuto UPDATE.