Regeln für das Zusammenfügen von TCP/IP-Segmenten
In diesem Abschnitt werden die Regeln definiert, die angeben, wann ein RSC-fähiger Miniporttreiber (Receive Segment Coalescing) ein Segment für eine bestimmte TCP-Verbindung zusammenlegen muss. Wenn eine der Regeln verletzt wird, wird eine Ausnahme generiert, und der Miniporttreiber muss die Zusammenführung des Segments abbrechen.
Der Miniporttreiber muss die IP- und TCP-Header für die single coalesced Unit (SCU) aktualisieren. Der Miniporttreiber muss die TCP- und IPv4-Prüfsummen über die SCU neu kompensieren und die TCP-Nutzlast verketten.
Das erste der beiden folgenden Flussdiagramme beschreibt die Regeln zum Zusammenfügen von Segmenten und zum Aktualisieren der TCP-Header. Dieses Flussdiagramm bezieht sich auf Mechanismen zum Unterscheiden gültiger doppelter ACKs und Fensterupdates. Das zweite Flussdiagramm beschreibt diese Mechanismen.
Diese Flussdiagramme werden als Referenz zum Verständnis der RSC-Regeln bereitgestellt. Eine Hardwareimplementierung kann das Flussdiagramm optimieren, solange die Richtigkeit beibehalten wird.
Die folgenden Begriffe werden in den Flussdiagrammen verwendet:
Begriff | BESCHREIBUNG |
---|---|
SEG. SEQ | Sequenznummer des eingehenden Segments. |
H.SEQ | Sequenznummer der aktuell nachverfolgten SCU. |
SEG. ACK | Bestätigungsnummer des eingehenden Segments. |
H.ACK | Bestätigungsnummer der aktuell nachverfolgten SCU. |
SEG. WND | Das Fenster, das vom eingehenden Segment angekündigt wird. |
H.WND | Das Fenster, das von der aktuell nachverfolgten SCU angekündigt wird. |
SEG. LEN | TCP-Nutzlastlänge des eingehenden Segments. |
H.LEN | TCP-Nutzlastlänge der derzeit nachverfolgten SCU. |
SEG. NXT | Die Summe von SEG. SEQ und SEG. LEN. |
H.NXT | Die Summe von H.SEQ und H.LEN. |
H.DupAckCount | Die Anzahl der doppelten ACKs, die in die SCU zusammengefasst wurden. Dieser Wert sollte Null sein. |
SEG. Tsval | Der Zeitstempelwert im aktuell empfangenen Segment. Das Format für diesen Wert ist in RFC 1323 definiert. |
H.Tsval | Der Zeitstempelwert in der aktuell nachverfolgten SCU. |
SEG. TSecr | Die Zeitstempel-Echoantwort im aktuell empfangenen Segment. |
H.TSecr | Die Zeitstempel-Echoantwort in der aktuell nachverfolgten SCU. |
Die Flussdiagramme zeigen, dass der Miniporttreiber Segmente mit unterschiedlichen ACK-Nummern zusammenlegen kann. Der Miniporttreiber muss jedoch die folgenden Regeln in Bezug auf ACK-Nummern befolgen, wie im ersten Flussdiagramm oben gezeigt:
Nach durchführung der Sequenznummerprüfung kann ein eingehender reiner ACK in die aktuell nachverfolgte SCU zusammengeführt werden, wenn er eine oder beide der folgenden Bedingungen erfüllt:
H.ACK == SEG. ACK.
Die Duplikat-ACK-Anzahl im zusammengeklammerten Segment, das nachverfolgt wird, ist 0. Mit anderen Worten: H.DupAckCount == 0.
Mit anderen Worten, jede reine ACK, die kein dupliziertes ACK oder ein Fensterupdate ist, löst eine Ausnahme aus und darf nicht koalesciert werden. Alle solchen reinen ACKs müssen als einzelne Segmente angegeben werden. Diese Regel stellt sicher, dass RSC das Verhalten oder die Leistung der Windows TCP-Überlastungssteuerungsalgorithmen nicht beeinflusst.
Ein eingehendes Datensegment (SEG. ACK == H.ACK) oder eine eingehende huckegebackene ACK (SEG. ACK>H.ACK) kann in die derzeit nachverfolgte SCU zusammengeführt werden, wenn beide der folgenden Bedingungen erfüllt sind:
- Das Segment ist im Sequenzraum an die SCU angrenzend. Mit anderen Worten, SEG. SEQ == H.NXT.
- Die Duplikat-ACK-Anzahl im zusammengeklammerten Segment, das nachverfolgt wird, ist 0. Mit anderen Worten: H.DupAckCount == 0.
Zusätzliche Hinweise zur duplizierten ACK-Koalescierung
Doppeltes ACK-Verhalten
Der Miniporttreiber sollte ein doppeltes ACK-Segment behandeln, das einem reinen ACK entspricht, und nicht koalesieren. In diesem Fall muss die aktuelle SCU (falls vorhanden) für die Angabe abgeschlossen und das doppelte ACK-Segment als einzelnes Segment angegeben werden. Da Windows-Clients standardmäßig selektive Bestätigungen (Selektive Bestätigungen, SACK) verwenden, generiert ein doppeltes ACK-Segment wahrscheinlich eine Ausnahme. Ein Beispiel finden Sie unter Beispiele für die Zusammenführung von Empfangssegmenten . Wenn ein Segment mit DupAckCount> 0 angegeben ist, deaktiviert NDIS RSC für die Schnittstelle.
Behandeln doppelter ACK beim Nachverfolgen einer SCU, die aus Datensegmenten besteht
Beim Nachverfolgen einer SCU mit H.LEN> 0 (d. h. einem zusammengeklungenen Segment, das Daten enthält) sollte die Nachverfolgungs-SCU wie folgt abgeschlossen werden:
Eine neue SCU sollte ab dem doppelten ACK nachverfolgt werden.
Der DupAckCount für die neue SCU sollte auf 0 festgelegt werden.
Der DupAckCount sollte erhöht werden, wenn zusätzliche doppelte ACKs empfangen werden.
In diesem Fall ist DupAckCount 1 kleiner als die Anzahl doppelter ACKs. Der Hoststapel verarbeitet die Zählung ordnungsgemäß.
Behandeln doppelter ACK beim Nachverfolgen einer SCU, die aus einer rein kumulativen ACK besteht
Beim Nachverfolgen einer SCU, die aus einer einzigen reinen kumulativen ACK besteht (Regeln verbieten das Zusammenfügen mehrerer reiner ACKs), sollte der DupAckCount für die Nachverfolgungs-SCU erhöht werden, wenn als Nächstes ein doppelter ACK eintrifft. Sie sollte auch erhöht werden, wenn zusätzliche doppelte ACKs empfangen werden. In diesem Fall entspricht DupAckCount der Anzahl der duplizierten ACKs.
Wenn das erste Segment, das in einem DPC empfangen wird, ein doppelter ACK ist
In diesem Fall kann die NIC nicht ermitteln, ob das empfangene Segment ein doppelter ACK ist, da es keinen Zustand beibehält. Daher sollte das Segment stattdessen wie folgt als reines ACK behandelt werden:
Ab diesem Segment sollte eine neue SCU nachverfolgt werden.
Der DupAckCount für die neue SCU sollte auf 0 festgelegt werden.
Der DupAckCount sollte um 1 für jeden weiteren empfangenen doppelten ACK erhöht werden.
In diesem Fall ist DupAckCount gleich 1 kleiner als die tatsächliche Anzahl doppelter ACKs. Der Hoststapel verarbeitet die Zählung ordnungsgemäß.
Doppelte ACK-Ausnahme
Der Miniporttreiber kann ein doppeltes ACK-Segment behandeln, das einem reinen ACK entspricht, und es nicht zusammenlegen. In diesem Fall muss die aktuelle SCU (falls vorhanden) für die Angabe abgeschlossen und das doppelte ACK-Segment als einzelnes Segment angegeben werden. Da Windows-Clients standardmäßig SACK verwenden, generiert ein doppeltes ACK-Segment wahrscheinlich eine Ausnahme. Ein Beispiel finden Sie unter Beispiele für Das Coalescing des Empfangssegments. Diese Ausnahme gilt nicht für Fensterupdatesegmente.
Zusammenfügen von Segmenten mit der Option "Zeitstempel"
Die TCP-Zeitstempeloption ist die einzige Option, die legal zusammengepferbt werden kann. Die Zusammenführung von Segmenten mit dieser Option bleibt eine implementierungsspezifische Entscheidung. Wenn der Miniporttreiber Segmente mit der Zeitstempeloption vereint, müssen die im folgenden Flussdiagramm beschriebenen Regeln eingehalten werden:
Hinweis
Die Überprüfung seg. TSval>= H.TSval muss mit der Modulo-232-Arithmetik ähnlich der für TCP-Sequenznummern ausgeführt werden. Siehe RFC 793, Abschnitt 3.3.
Bei der Angabe eines zusammengehörigen Segments müssen die folgenden Out-of-Band-Informationen wie folgt angegeben werden, indem das NetBufferListInfo-Element der NET_BUFFER_LIST-Struktur festgelegt wird, die das zusammengehörige Segment beschreibt:
Die Anzahl der Segmente, die zusammengeführt wurden, muss in NetBufferListInfo[TcpRecvSegCoalesceInfo] gespeichert werden. CoalescedSegCount-Element . Diese Zahl stellt nur Datensegmente dar, die zusammengehaktet wurden. Die reine ACK-Zusammenführung ist verboten, und Fensteraktualisierungssegmente dürfen nicht als Teil dieses Felds gezählt werden.
Die doppelte ACK-Anzahl muss in NetBufferListInfo[TcpRecvSegCoalesceInfo] gespeichert werden. DupAckCount-Element . Im ersten Flussdiagramm oben wird erläutert, wie dieser Wert berechnet wird.
Wenn Segmente mit der TCP-Zeitstempeloption zusammengehören, muss NetBufferListInfo[RscTcpTimestampDelta] mit dem absoluten Delta zwischen dem frühesten und dem neuesten TCP-Zeitstempelwert gefüllt werden, der in der Sequenz der zusammengeflochtenen Segmente der SCU zu sehen ist. Die SCU selbst sollte den neuesten TCP-Zeitstempelwert enthalten, der in der Sequenz der zusammengeketteten Segmente zu sehen ist.
Die Member DupAckCount und RscTcpTimestampDelta werden nur interpretiert, wenn das CoalescedSegCount-Element größer als 0 (null) ist. Wenn CoalescedSegCount null ist, wird das Segment als nicht zusammengeflechtetes Nicht-RSC-Segment behandelt.
Informationen zum Inhalt des NetBufferListInfo-Elements finden Sie unter NDIS_NET_BUFFER_LIST_INFO und NDIS_RSC_NBL_INFO.
Das PSH-Bit sollte für alle zusammengehörten Segmente nicht mehr verwendet werden. Anders ausgedrückt: Wenn das PSH-Bit in einem der einzelnen Segmente festgelegt wurde, sollte der Miniporttreiber das PSH-Bit in der SCU festlegen.
Der Abschluss einer SCU umfasst Folgendes:
Erneutes Kompensieren des TCP und ggf. der IPv4-Prüfsumme.
Aktualisieren der IP-Header wie unter Aktualisieren der IP-Header für zusammengeknipselte Segmente beschrieben.
Festlegen der ECN-Bits und ECN-Felder in den TCP- und IP-Headern auf dieselben Werte, die in den einzelnen Segmenten festgelegt wurden.
Behandeln von TCP/IP-IPsec-Segmenten
Ein Netzwerk Karte kann sowohl RSC- als auch IPsec-Aufgabenauslagerungsfunktionen melden. (Siehe Ermitteln der RSC-Funktionen eines Netzwerkadapters.) Wenn es jedoch die IPsec-Aufgabenauslagerung unterstützt, darf nicht versucht werden, Segmente zu koessieren, die durch IPsec geschützt sind.