Zum Hauptinhalt springen

9. Zusätzliche Überlegungen

9.1. Dienstinstanzen

Wir verwenden den Begriff "Dienstinstanz", um Software zu bezeichnen, die auf einem Host läuft und Verbindungen auf einer Menge von { IP-Adresse, Port }-Tupeln empfangen kann. Was die Software zu einer Instanz macht, ist, dass der Client unabhängig davon, welches dieser Tupel er verwendet, um sich mit ihr zu verbinden, mit derselben Software verbunden ist, die auf demselben logischen Knoten läuft (siehe Abschnitt 9.2), und dieselben Antworten und dieselben Schlüsselinformationen erhält.

Dienstinstanzen werden aus der Perspektive des Clients identifiziert. Wenn der Client mit { IP-Adresse, Port }-Tupeln konfiguriert ist, kann er nicht feststellen, ob der unter einem Tupel angebotene Dienst derselbe Server ist, der unter einem anderen Tupel lauscht. In diesem Fall behandelt der Client also jedes unterschiedliche Tupel so, als ob es auf eine andere Dienstinstanz verweist.

In einigen Fällen ist ein Client mit einem Hostnamen und einer Portnummer konfiguriert. Die Portnummer kann explizit zusammen mit dem Hostnamen angegeben werden. Die Portnummer kann weggelassen werden und es wird angenommen, dass sie einen Standardwert hat. Der Hostname und eine Portnummer können aus dem Netzwerk gelernt werden, wie im Fall von DNS-SRV-Einträgen. In diesen Fällen identifiziert das { Hostname, Port }-Tupel die Dienstinstanz eindeutig, vorbehaltlich des üblichen Vergleichs von DNS-Namen ohne Berücksichtigung der Groß-/Kleinschreibung [RFC1034].

Es ist möglich, dass zwei Hostnamen auf einige gemeinsame IP-Adressen verweisen; dies ist eine Konfigurationsanomalie, die der Client nicht erkennen muss. Die Auswirkung davon könnte sein, dass der Client, nachdem er aufgefordert wurde, die Verbindung zu trennen, möglicherweise wieder eine Verbindung zum selben Server herstellt, da dieser als eine andere Dienstinstanz dargestellt wird.

Implementierungen SOLLTEN NICHT Hostnamen auflösen und dann den Prozess des Abgleichs von IP-Adressen durchführen, um zu bewerten, ob zwei Entitäten als "dieselbe Dienstinstanz" bestimmt werden sollten.

9.2. Anycast-Überlegungen

Wenn ein Anycast-Dienst auf einer bestimmten IP-Adresse und einem bestimmten Port konfiguriert ist, muss sichergestellt sein, dass, obwohl mehr als ein physischer Server auf dieser IP-Adresse antwortet, jeder dieser Server als gleichwertig behandelt werden kann. Was wir hier mit "gleichwertig" meinen, ist, dass beide Server denselben Dienst und gegebenenfalls dieselben Authentifizierungsinformationen, wie z. B. PKI-Zertifikate, beim Aufbau von Verbindungen bereitstellen können.

Wenn eine Änderung der Netzwerktopologie dazu führt, dass Pakete in einer bestimmten TCP-Verbindung an eine Anycast-Serverinstanz gesendet werden, die nichts von der Verbindung weiß, beendet der neue Server die Verbindung automatisch mit einem TCP-Reset, da er keine Aufzeichnung der Verbindung hat, und der Client kann dann die Verbindung wiederherstellen oder die Verwendung der Verbindung beenden, je nach Bedarf.

Wenn nach dem Wiederherstellen der Verbindung die Annahme des Clients, dass er mit derselben Instanz verbunden ist, in irgendeiner Weise verletzt wird, würde dies in diesem Kontext als fehlerhaftes Verhalten angesehen werden. Es liegt jedoch außerhalb des möglichen Umfangs dieser Spezifikation, diesbezüglich spezifische Empfehlungen abzugeben; dies bliebe Folgedokumenten vorbehalten, die spezifische Verwendungen von DNS-Zustandsbehafteten Operationen beschreiben.

9.3. Verbindungsfreigabe

Wie zuvor für DNS-over-TCP [RFC7766] spezifiziert:

Um das Risiko einer unbeabsichtigten Serverüberlastung zu verringern, MÜSSEN DNS-Clients darauf achten, die Anzahl der gleichzeitigen TCP-Verbindungen zu einem einzelnen Server zu minimieren. Es wird EMPFOHLEN, dass für jede gegebene Client/Server-Interaktion nicht mehr als eine Verbindung für reguläre Abfragen, eine für Zonentransfers und eine für jedes Protokoll, das auf TCP verwendet wird (zum Beispiel, wenn der Resolver TLS verwendet), vorhanden sein SOLLTE. Es wird jedoch angemerkt, dass bestimmte Primär-/Sekundärkonfigurationen mit vielen ausgelasteten Zonen aus betrieblichen Gründen möglicherweise mehr als eine TCP-Verbindung für Zonentransfers verwenden müssen (zum Beispiel, um gleichzeitige Transfers mehrerer Zonen zu unterstützen).

Ein einzelner Server kann mehrere Dienste unterstützen, einschließlich DNS-Updates [RFC2136], DNS-Push-Benachrichtigungen [Push] und andere Dienste, für eine oder mehrere DNS-Zonen. Wenn ein Client feststellt, dass der Zielserver für mehrere verschiedene Operationen dieselbe Dienstinstanz ist (siehe Abschnitt 9.1), SOLLTE der Client eine einzelne gemeinsame DSO-Sitzung für alle diese Operationen verwenden.

Diese Anforderung hat zwei Vorteile. Erstens reduziert sie unnötige Verbindungslast auf dem DNS-Server. Zweitens vermeidet sie die Verbindungsstartzeit, die für den Aufbau jeder neuen zusätzlichen Verbindung zum selben DNS-Server aufgewendet würde.

Serverimplementierer und -betreiber sollten sich jedoch bewusst sein, dass die Verbindungsfreigabe möglicherweise nicht in allen Fällen möglich ist. Ein einzelnes Hostgerät kann mehrere unabhängige Client-Softwareinstanzen beherbergen, die sich nicht miteinander koordinieren. Ebenso erscheinen mehrere unabhängige Clientgeräte hinter demselben NAT-Gateway dem DNS-Server typischerweise als unterschiedliche Quellports auf derselben Client-IP-Adresse. Aufgrund dieser Einschränkungen MUSS ein DNS-Server darauf vorbereitet sein, mehrere Verbindungen von verschiedenen Quellports auf derselben Client-IP-Adresse zu akzeptieren.

9.4. Betriebliche Überlegungen für Middleboxes

Wo sich eine Middlebox auf Anwendungsebene (z. B. ein DNS-Proxy, Forwarder oder Session-Multiplexer) im Pfad befindet, muss darauf geachtet werden, eine Konfiguration zu vermeiden, in der DSO-Verkehr falsch behandelt wird. Der einfachste Weg, solche Probleme zu vermeiden, besteht darin, die Verwendung von Middleboxes zu vermeiden. Wenn dies nicht möglich ist, sollten Middleboxes bewertet werden, um sicherzustellen, dass sie sich korrekt verhalten.

Korrektes Verhalten für Middleboxes besteht aus einem der folgenden Punkte:

  • Die Middlebox leitet keine DSO-Nachrichten weiter und antwortet auf DSO-Nachrichten mit einem anderen Antwortcode als NOERROR oder DSOTYPENI.

  • Die Middlebox fungiert als DSO-Server und folgt dieser Spezifikation beim Aufbau von Verbindungen.

  • Es besteht eine 1:1-Entsprechung zwischen eingehenden und ausgehenden Verbindungen, so dass beim Aufbau einer Verbindung zur Middlebox garantiert wird, dass genau eine entsprechende Verbindung von der Middlebox zu einem DNS-Resolver aufgebaut wird und alle eingehenden Nachrichten ohne Änderung oder Neuordnung weitergeleitet werden. Ein Beispiel hierfür wäre ein NAT-Forwarder oder ein TCP-Verbindungsoptimierer (z. B. für eine Verbindung mit hoher Latenz wie eine geosynchrone Satellitenverbindung).

Middleboxes, die eines der oben genannten Kriterien nicht erfüllen, werden sehr wahrscheinlich auf unerwartete und schwer zu diagnostizierende Weise fehlschlagen. Beispielsweise könnte ein DNS-Load-Balancer DNS-Nachrichten aus dem eingehenden TCP-Stream entbündeln und jede Nachricht aus dem Stream an einen anderen DNS-Server weiterleiten. Wenn ein solcher Load-Balancer verwendet wird und die DNS-Server, auf die er zeigt, DSO implementieren und so konfiguriert sind, dass sie DSO aktivieren, wird der Aufbau der DSO-Sitzung erfolgreich sein, aber es wird keine kohärente Sitzung zwischen dem Client und dem Server existieren. Wenn ein solcher Load-Balancer auf einen DNS-Server zeigt, der DSO nicht implementiert oder so konfiguriert ist, dass er DSO nicht zulässt, wird kein solches Problem bestehen, aber eine solche Konfiguration birgt das Risiko eines unerwarteten Fehlers, wenn neue Serversoftware installiert wird, die DSO implementiert.

Es ist natürlich möglich, eine Middlebox zu implementieren, die DSO ordnungsgemäß unterstützt. Es ist sogar möglich, eine zu implementieren, die DSO mit langlebigen Operationen implementiert. Dies kann entweder durch Aufrechterhaltung einer 1:1-Entsprechung zwischen eingehenden und ausgehenden Verbindungen erfolgen, wie oben erwähnt, oder durch Beendigung eingehender Sitzungen an der Middlebox, aber Aufrechterhaltung des Zustands in der Middlebox über alle angeforderten langlebigen Operationen. Dies im Detail zu spezifizieren, sprengt den Rahmen dieses Dokuments.

9.5. Überlegungen zur verzögerten TCP-Bestätigung

Die meisten modernen Implementierungen des Transmission Control Protocol (TCP) enthalten eine Funktion namens "Verzögerte Bestätigung" (Delayed Acknowledgement) [RFC1122].

Ohne diese Funktion kann TCP im Netzwerk sehr verschwenderisch sein. Zur Veranschaulichung betrachten wir ein einfaches Beispiel wie die Remote-Anmeldung unter Verwendung einer sehr einfachen TCP-Implementierung, der verzögerte Acks fehlen. Wenn der Benutzer einen Tastenanschlag eingibt, wird ein Datenpaket gesendet. Wenn das Datenpaket am Server ankommt, sendet die einfache TCP-Implementierung eine sofortige Bestätigung. Nur Millisekunden später liest der Serverprozess das eine Byte der Tastenanschlagdaten, und folglich sendet die einfache TCP-Implementierung eine sofortige Fensteraktualisierung. Nur Millisekunden später generiert der Serverprozess das Zeichenecho und sendet dieses Datenpaket ebenfalls sofort. Die einfache TCP-Implementierung sendet dieses Datenpaket dann ebenfalls sofort. In diesem Fall sendet diese einfache TCP-Implementierung fast augenblicklich einen Burst von drei Paketen (Ack, Fensteraktualisierung, Daten).

Es wäre eindeutig effizienter, wenn die TCP-Implementierung die drei separaten Pakete zu einem kombinieren würde, und genau das ermöglicht die Funktion der verzögerten Bestätigung.

Mit verzögerter Bestätigung wartet die TCP-Implementierung nach dem Empfang eines Datenpakets, typischerweise 200 ms, und sendet dann ihr Ack, wenn (a) weitere Datenpakete ankommen, (b) der Empfangsprozess Antwortdaten generiert oder (c) 200 ms vergehen, ohne dass eines der oben genannten Ereignisse eintritt.

Mit verzögerter Bestätigung wird die Remote-Anmeldung viel effizienter und generiert nur ein Paket anstelle von drei für jedes Zeichenecho.

Die Logik der verzögerten Bestätigung ist, dass die 200 ms Verzögerung keinen signifikanten Schaden anrichten können. Wenn etwas am anderen Ende auf etwas wartet, sollte der Empfangsprozess die Antwort generieren, auf die das Ding am anderen Ende wartet, und TCP sendet diese Antwort dann sofort (kombiniert mit dem Ack und der Fensteraktualisierung). Und wenn der Empfangsprozess tatsächlich keine Antwort für diese spezielle Nachricht generiert, dann kann das Ding am anderen Ende per Definition auf nichts warten. Daher ist die 200 ms Verzögerung harmlos.

Diese Annahme mag zutreffen, es sei denn, der Sender verwendet den Nagle-Algorithmus, eine ähnliche Effizienzfunktion, die erstellt wurde, um das Netzwerk vor schlecht geschriebener Client-Software zu schützen, die viele schnelle kleine Schreibvorgänge hintereinander ausführt. Der Nagle-Algorithmus ermöglicht es, diese kleinen Schreibvorgänge in größere, weniger verschwenderische Pakete zusammenzufassen.

Leider können der Nagle-Algorithmus und die verzögerte Bestätigung, zwei wertvolle Effizienzfunktionen, schlecht miteinander interagieren, wenn sie zusammen verwendet werden [NagleDA].

DSO-Anforderungsnachrichten rufen Antworten hervor; unidirektionale DSO-Nachrichten und DSO-Antwortnachrichten tun dies nicht.

Für DSO-Anforderungsnachrichten, die Antworten hervorrufen, funktionieren der Nagle-Algorithmus und die verzögerte Bestätigung wie beabsichtigt.

Für DSO-Nachrichten, die keine Antworten hervorrufen, führt der Mechanismus der verzögerten Bestätigung dazu, dass das Ack um 200 ms verzögert wird. Die 200 ms Verzögerung beim Ack kann wiederum dazu führen, dass der Nagle-Algorithmus den Sender daran hindert, für 200 ms weitere Daten zu senden, bis das erwartete Ack eintrifft. Auf einem Enterprise-Gigabit-Ethernet (GigE)-Backbone mit Sub-Millisekunden-Round-Trip-Zeiten ist eine Verzögerung von 200 ms im Vergleich dazu enorm.

Wenn dieses Problem angesprochen wird, werden oft zwei Lösungen angeboten, von denen keine ideal ist:

  1. Verzögerte Bestätigung deaktivieren. Für DSO-Nachrichten, die keine Antwort hervorrufen, vermeidet das Entfernen der verzögerten Bestätigung die unnötige 200 ms Verzögerung und sendet ein sofortiges Ack zurück, das dem Nagle-Algorithmus mitteilt, dass er dem Sender sofort die Erlaubnis erteilen sollte, sein nächstes Paket zu senden. Leider entfernt das Entfernen der verzögerten Bestätigung für DSO-Nachrichten, die eine Antwort hervorrufen, die Effizienzgewinne durch die Kombination von Acks mit Daten, und der Responder sendet nun zwei oder drei Pakete anstelle von einem.

  2. Nagle-Algorithmus deaktivieren. Wenn Acks durch den Algorithmus der verzögerten Bestätigung verzögert werden, verhindert das Entfernen des Nagle-Algorithmus, dass der Sender daran gehindert wird, sein nächstes kleines Paket sofort zu senden. Leider entfernt das Entfernen des Nagle-Algorithmus in einem Netzwerk mit einer höheren Round-Trip-Zeit die Effizienzgewinne durch die Kombination mehrerer kleiner Pakete zu weniger größeren, mit dem Ziel, die Anzahl der kleinen Pakete, die sich zu einem beliebigen Zeitpunkt im Flug befinden, zu begrenzen.

Das Problem hierbei ist, dass bei DSO-Nachrichten, die keine Antwort hervorrufen, die TCP-Implementierung wartet und unsicher ist, ob eine Antwort generiert wird oder ob die TCP-Implementierung fortfahren und ein Ack und eine Fensteraktualisierung senden soll.

Die Lösung sind Netzwerk-APIs, die es dem Empfänger ermöglichen, die TCP-Implementierung darüber zu informieren, dass eine empfangene Nachricht gelesen, verarbeitet wurde und keine Antwort für diese Nachricht generiert wird. TCP kann dann aufhören, auf eine Antwort zu warten, die niemals kommen wird, und sofort fortfahren und ein Ack und eine Fensteraktualisierung senden.

Für Implementierungen von DSO wird das Deaktivieren der verzögerten Bestätigung NICHT EMPFOHLEN, da dies dem Netzwerk schaden kann.

Für Implementierungen von DSO wird das Deaktivieren des Nagle-Algorithmus NICHT EMPFOHLEN, da dies dem Netzwerk schaden kann.

Zum Zeitpunkt der Vorbereitung dieses Dokuments zur Veröffentlichung ist bekannt, dass mindestens eine TCP-Implementierung die Möglichkeit für den Empfänger einer TCP-Nachricht bietet, zu signalisieren, dass er keine Antwort senden wird, und daher der Mechanismus der verzögerten Bestätigung aufhören kann zu warten. Implementierungen auf Betriebssystemen, auf denen diese Funktion verfügbar ist, SOLLTEN sie nutzen.