9. Considerazioni Aggiuntive
9.1. Istanze di Servizio
Usiamo il termine "istanza di servizio" per riferirci al software in esecuzione su un host che può ricevere connessioni su un insieme di tuple { indirizzo IP, porta }. Ciò che rende il software un'istanza è che, indipendentemente da quale di queste tuple il client utilizzi per connettersi ad esso, il client è connesso allo stesso software, in esecuzione sullo stesso nodo logico (vedere Sezione 9.2), e riceverà le stesse risposte e le stesse informazioni sulle chiavi.
Le istanze di servizio sono identificate dal punto di vista del client. Se il client è configurato con tuple { indirizzo IP, porta }, non ha modo di sapere se il servizio offerto su una tupla è lo stesso server in ascolto su una tupla diversa. Quindi in questo caso, il client tratta ogni tupla diversa come se facesse riferimento a un'istanza di servizio diversa.
In alcuni casi, un client è configurato con un nome host e un numero di porta. Il numero di porta può essere fornito esplicitamente, insieme al nome host. Il numero di porta può essere omesso e si presume che abbia un valore predefinito. Il nome host e un numero di porta possono essere appresi dalla rete, come nel caso dei record DNS SRV. In questi casi, la tupla { nome host, porta } identifica in modo univoco l'istanza di servizio, soggetta al consueto confronto dei nomi DNS senza distinzione tra maiuscole e minuscole [RFC1034].
È possibile che due nomi host puntino ad alcuni indirizzi IP comuni; questa è un'anomalia di configurazione che il client non è obbligato a rilevare. L'effetto di ciò potrebbe essere che, dopo aver ricevuto l'ordine di disconnettersi, il client potrebbe riconnettersi allo stesso server perché è rappresentato come un'istanza di servizio diversa.
Le implementazioni NON DOVREBBERO risolvere i nomi host ed eseguire quindi il processo di corrispondenza degli indirizzi IP per valutare se due entità debbano essere determinate come la "stessa istanza di servizio".
9.2. Considerazioni su Anycast
Quando un servizio anycast è configurato su un particolare indirizzo IP e porta, deve essere il caso che, sebbene vi sia più di un server fisico che risponde su quell'indirizzo IP, ciascuno di tali server possa essere trattato come equivalente. Ciò che intendiamo per "equivalente" qui è che entrambi i server possono fornire lo stesso servizio e, ove appropriato, le stesse informazioni di autenticazione, come i certificati PKI, quando si stabiliscono le connessioni.
Se una modifica nella topologia di rete fa sì che i pacchetti in una particolare connessione TCP vengano inviati a un'istanza del server anycast che non conosce la connessione, il nuovo server terminerà automaticamente la connessione con un reset TCP, poiché non avrà alcuna registrazione della connessione, e quindi il client può riconnettersi o smettere di utilizzare la connessione come appropriato.
Se, dopo che la connessione è stata ristabilita, l'ipotesi del client di essere connesso alla stessa istanza viene violata in qualche modo, ciò sarebbe considerato un comportamento errato in questo contesto. È tuttavia al di fuori del possibile ambito di questa specifica formulare raccomandazioni specifiche al riguardo; ciò spetterebbe a documenti successivi che descrivono usi specifici delle Operazioni DNS con Stato.
9.3. Condivisione della Connessione
Come precedentemente specificato per DNS-over-TCP [RFC7766]:
Per mitigare il rischio di sovraccarico involontario del server, i client DNS DEVONO prestare attenzione a ridurre al minimo il numero di connessioni TCP simultanee effettuate verso un singolo server. Si RACCOMANDA che per ogni data interazione client/server NON CI DOVREBBE essere più di una connessione per le query regolari, una per i trasferimenti di zona e una per ogni protocollo utilizzato su TCP (ad esempio, se il risolutore utilizzava TLS). Tuttavia, si nota che alcune configurazioni primarie/secondarie con molte zone occupate potrebbero dover utilizzare più di una connessione TCP per i trasferimenti di zona per motivi operativi (ad esempio, per supportare trasferimenti simultanei di più zone).
Un singolo server può supportare più servizi, inclusi Aggiornamenti DNS [RFC2136], Notifiche Push DNS [Push] e altri servizi, per una o più zone DNS. Quando un client scopre che il server di destinazione per diverse operazioni diverse è la stessa istanza di servizio (vedere Sezione 9.1), il client DOVREBBE utilizzare una singola sessione DSO condivisa per tutte quelle operazioni.
Questo requisito ha due vantaggi. In primo luogo, riduce il carico di connessione non necessario sul server DNS. In secondo luogo, evita il tempo di avvio della connessione che verrebbe speso per stabilire ogni nuova connessione aggiuntiva allo stesso server DNS.
Tuttavia, gli implementatori e gli operatori dei server dovrebbero essere consapevoli che la condivisione della connessione potrebbe non essere possibile in tutti i casi. Un singolo dispositivo host può ospitare più istanze software client indipendenti che non si coordinano tra loro. Allo stesso modo, più dispositivi client indipendenti dietro lo stesso gateway NAT appariranno tipicamente al server DNS come porte sorgente diverse sullo stesso indirizzo IP client. A causa di questi vincoli, un server DNS DEVE essere preparato ad accettare più connessioni da diverse porte sorgente sullo stesso indirizzo IP client.
9.4. Considerazioni Operative per i Middlebox
Laddove un middlebox a livello di applicazione (ad esempio, un proxy DNS, un forwarder o un multiplexer di sessione) si trova nel percorso, è necessario prestare attenzione per evitare una configurazione in cui il traffico DSO viene gestito in modo errato. Il modo più semplice per evitare tali problemi è evitare di utilizzare i middlebox. Quando ciò non è possibile, i middlebox dovrebbero essere valutati per assicurarsi che si comportino correttamente.
Il comportamento corretto per i middlebox consiste in uno dei seguenti:
-
Il middlebox non inoltra i messaggi DSO e risponde ai messaggi DSO con un codice di risposta diverso da NOERROR o DSOTYPENI.
-
Il middlebox agisce come un server DSO e segue questa specifica nello stabilire le connessioni.
-
Esiste una corrispondenza 1:1 tra le connessioni in entrata e in uscita in modo tale che quando viene stabilita una connessione al middlebox, è garantito che verrà stabilita esattamente una connessione corrispondente dal middlebox a un risolutore DNS e tutti i messaggi in entrata verranno inoltrati senza modifiche o riordino. Un esempio di ciò sarebbe un forwarder NAT o un ottimizzatore di connessione TCP (ad esempio, per una connessione ad alta latenza come un collegamento satellitare geosincrono).
I middlebox che non soddisfano uno dei criteri di cui sopra hanno molte probabilità di fallire in modi imprevisti e difficili da diagnosticare. Ad esempio, un bilanciatore del carico DNS potrebbe disaggregare i messaggi DNS dal flusso TCP in entrata e inoltrare ogni messaggio dal flusso a un server DNS diverso. Se tale bilanciatore del carico è in uso e i server DNS a cui punta implementano DSO e sono configurati per abilitare DSO, l'istituzione della sessione DSO avrà successo, ma non esisterà alcuna sessione coerente tra il client e il server. Se tale bilanciatore del carico punta a un server DNS che non implementa DSO o è configurato per non consentire DSO, non esisterà alcun problema di questo tipo, ma tale configurazione rischia un fallimento imprevisto se viene installato un nuovo software server che implementa DSO.
È ovviamente possibile implementare un middlebox che supporti correttamente DSO. È anche possibile implementarne uno che implementi DSO con operazioni di lunga durata. Ciò può essere fatto mantenendo una corrispondenza 1:1 tra le connessioni in entrata e in uscita, come menzionato sopra, o terminando le sessioni in entrata al middlebox ma mantenendo lo stato nel middlebox su eventuali operazioni di lunga durata richieste. Specificare questo in dettaglio va oltre l'ambito di questo documento.
9.5. Considerazioni sul Riconoscimento Ritardato TCP
La maggior parte delle moderne implementazioni del Transmission Control Protocol (TCP) include una funzionalità chiamata "Riconoscimento Ritardato" (Delayed Acknowledgement) [RFC1122].
Senza questa funzionalità, TCP può essere molto dispendioso sulla rete. Per illustrare, si consideri un semplice esempio come l'accesso remoto utilizzando un'implementazione TCP molto semplice priva di ack ritardati. Quando l'utente digita un tasto, viene inviato un pacchetto dati. Quando il pacchetto dati arriva al server, l'implementazione TCP semplice invia un riconoscimento immediato. Pochi millisecondi dopo, il processo server legge il singolo byte di dati della digitazione e di conseguenza l'implementazione TCP semplice invia un aggiornamento immediato della finestra. Pochi millisecondi dopo, il processo server genera l'eco del carattere e invia immediatamente anche questo pacchetto dati. L'implementazione TCP semplice invia quindi immediatamente anche questo pacchetto dati. In questo caso, questa semplice implementazione TCP invia una raffica di tre pacchetti quasi istantaneamente (ack, aggiornamento finestra, dati).
Chiaramente sarebbe più efficiente se l'implementazione TCP combinasse i tre pacchetti separati in uno solo, ed è ciò che abilita la funzionalità di ack ritardato.
Con l'ack ritardato, l'implementazione TCP attende dopo aver ricevuto un pacchetto dati, in genere per 200 ms, e quindi invia il suo ack se (a) arrivano altri pacchetti dati, (b) il processo di ricezione genera alcuni dati di risposta, o (c) trascorrono 200 ms senza che si verifichi nessuna delle condizioni precedenti.
Con l'ack ritardato, l'accesso remoto diventa molto più efficiente, generando solo un pacchetto invece di tre per ogni eco di carattere.
La logica dell'ack ritardato è che il ritardo di 200 ms non può causare danni significativi. Se qualcosa all'altra estremità stava aspettando qualcosa, allora il processo di ricezione dovrebbe generare la risposta che la cosa all'altra estremità sta aspettando, e TCP invierà immediatamente quella risposta (combinata con l'ack e l'aggiornamento della finestra). E se il processo di ricezione non genera di fatto alcuna risposta per questo particolare messaggio, allora per definizione la cosa all'altra estremità non può aspettare nulla. Pertanto, il ritardo di 200 ms è innocuo.
Questa ipotesi può essere vera a meno che il mittente non stia utilizzando l'algoritmo di Nagle, una funzionalità di efficienza simile, creata per proteggere la rete da software client scritto male che esegue molte piccole scritture rapide in successione. L'algoritmo di Nagle consente di unire queste piccole scritture in pacchetti più grandi e meno dispendiosi.
Sfortunatamente, l'algoritmo di Nagle e l'ack ritardato, due preziose funzionalità di efficienza, possono interagire male tra loro se utilizzati insieme [NagleDA].
I messaggi di richiesta DSO sollecitano risposte; i messaggi unidirezionali DSO e i messaggi di risposta DSO no.
Per i messaggi di richiesta DSO, che sollecitano risposte, l'algoritmo di Nagle e l'ack ritardato funzionano come previsto.
Per i messaggi DSO che non sollecitano risposte, il meccanismo di ack ritardato fa sì che l'ack venga ritardato di 200 ms. Il ritardo di 200 ms sull'ack può a sua volta far sì che l'algoritmo di Nagle impedisca al mittente di inviare altri dati per 200 ms fino all'arrivo dell'ack atteso. Su una dorsale Gigabit Ethernet (GigE) aziendale con tempi di andata e ritorno inferiori al millisecondo, un ritardo di 200 ms è enorme in confronto.
Quando viene sollevato questo problema, ci sono due soluzioni che vengono spesso offerte, nessuna delle quali ideale:
-
Disabilitare l'ack ritardato. Per i messaggi DSO che non sollecitano alcuna risposta, la rimozione dell'ack ritardato evita l'inutile ritardo di 200 ms e rimanda un ack immediato che dice all'algoritmo di Nagle che dovrebbe concedere immediatamente al mittente l'autorizzazione a inviare il suo pacchetto successivo. Sfortunatamente, per i messaggi DSO che sollecitano una risposta, la rimozione dell'ack ritardato rimuove i guadagni di efficienza derivanti dalla combinazione di ack con i dati, e il risponditore invierà ora due o tre pacchetti invece di uno.
-
Disabilitare l'algoritmo di Nagle. Quando gli ack sono ritardati dall'algoritmo di ack ritardato, la rimozione dell'algoritmo di Nagle impedisce al mittente di essere bloccato dall'invio immediato del suo prossimo piccolo pacchetto. Sfortunatamente, su una rete con un tempo di andata e ritorno più elevato, la rimozione dell'algoritmo di Nagle rimuove i guadagni di efficienza derivanti dalla combinazione di più piccoli pacchetti in un minor numero di pacchetti più grandi, con l'obiettivo di limitare il numero di piccoli pacchetti in volo in qualsiasi momento.
Il problema qui è che con i messaggi DSO che non sollecitano alcuna risposta, l'implementazione TCP è bloccata in attesa, incerta se sta per essere generata una risposta o se l'implementazione TCP dovrebbe procedere e inviare un ack e un aggiornamento della finestra.
La soluzione sono le API di rete che consentono al ricevitore di informare l'implementazione TCP che un messaggio ricevuto è stato letto, elaborato e non verrà generata alcuna risposta per questo messaggio. TCP può quindi smettere di aspettare una risposta che non arriverà mai e procedere immediatamente all'invio di un ack e di un aggiornamento della finestra.
Per le implementazioni di DSO, disabilitare l'ack ritardato NON È RACCOMANDATO a causa del danno che ciò può causare alla rete.
Per le implementazioni di DSO, disabilitare l'algoritmo di Nagle NON È RACCOMANDATO a causa del danno che ciò può causare alla rete.
Nel momento in cui questo documento viene preparato per la pubblicazione, è noto che almeno un'implementazione TCP fornisce la capacità al destinatario di un messaggio TCP di segnalare che non invierà una risposta, e quindi il meccanismo di ack ritardato può smettere di aspettare. Le implementazioni su sistemi operativi in cui questa funzionalità è disponibile DOVREBBERO farne uso.