Transmission Control Protocol

Aus Foxwiki
Version vom 20. Dezember 2022, 10:12 Uhr von Dirkwagner (Diskussion | Beiträge) (Textersetzung - „Kategorie:OSI:04“ durch „Kategorie:OSI 4 Transport“)

TCP (Transmission Control Protocol) ist ein Netzwerkprotokoll, das definiert, auf welche Art und Weise Daten zwischen Netzwerkkomponenten ausgetauscht werden sollen.

Beschreibung

  • Ist ein zuverlässiges, verbindungsorientiertes, paketvermitteltes (nicht paketvermittelnd) Transportprotokoll.
  • TCP ermöglicht die Übertragung eines Datenstroms.
  • Im Unterschied zum verbindungslosen User Datagram Protokoll (UDP) stellt TCP eine Verbindung zwischen zwei Endpunkten (Sockets) einer Netzverbindung her.
  • Auf dieser Verbindung können in beide Richtungen Daten übertragen werden.

Vorteile

  • Netzwerküberlastungskontrolle.
  • Zuverlässige Datenübertragung:
    • erkennt verlorene, doppelte und fehlerhafte Segmente.

Allgemeines

  • TCP ist im Prinzip eine Ende-zu-Ende-Verbindung in Vollduplex.
  • Kann auch als zwei Halbduplexverbindungen betrachtet werden (Informationsfluss in beide Richtungen (allerdings nicht gleichzeitig)).
  • Die Daten in Gegenrichtung können zusätzliche Steuerungsinformationen enthalten.
  • Anwendungen, die TCP häufig nutzen, sind zum Beispiel Webbrowser und Webserver.

TCP-Software

  • Übernimmt Verbindungsverwaltung sowie die Datenübertragung.
  • Netz-Protokollstack des Betriebssystems.
  • Anwendungsprogramme nutzen Sockets.

Entwicklung

  • Entwickelt von Robert E. Kahn und Vinton G. Cerf als Forschungsarbeit.
  • Beginn 1973, erste Standardisierung 1981 als RFC 793.
  • Danach gab es viele Erweiterungen, diese werden bis heute in RFCs spezifiziert.
  • Das Transmission Control Protocol arbeitet auf dem OSI-04
  • TCP verwendet 16-Bit Portnummern zur Adressierung
  • Zusätzlich zur Adressierung übernimmt es weitere Aufgaben
  • Verbindungsmanagement (Three-Way-Handshake)
  • Verbindungsaufbau/-abbau
  • Fehlerkontrolle (-korrektur)
  • Flußkontrolle (engl. Flow Control)
  • verhindert, dass der Empfänger von einem Sender schneller Daten erhält, als er entgegennehmen kann
  • Netzwerk-Überlastkontrolle (engl. Congestion Control)
  • verhindert, dass es zu einer Überlastsituation im Netz kommt, die zum vollständigen Zusammenbruch des Netzes führen könnte (congestion collapse)
  • bei Erkennen einer Überlastsituation (Paketverlust!) wird vom Sender die Datenrate gedrosselt
  • transparente Übertragung von byte streams
  • Anwendungen, die TCP benutzen, sollen nicht merken, dass die Daten in Form von Paketen übertragen werden.
  • Mutliplexing
  • Mehrfachnutzung einer Verbindung
  • Verbindungsorientiertes Protokoll
  • Beinhaltet verschiedene Algorithmen zur Fehlererkennung und -behandlung
  • Sequenznummern
  • Quittungsnummern
  • Anzeigen (Flags)
  • Die richtige Reihenfolge der Daten ist garantiert
  • Bietet der Anwendungsschicht einen zuverlässigen Transportdienst
  • RFC 793. J. Postel. Transmission Control Protocol. 1981.
  • setzt direkt auf dem Internet Protokoll (IP) auf
  • IP Protokoll Nr.: 06
  • Theoretisch ist es möglich TCP mit einem beliebigen Protokoll der Schicht 3 zu kombinieren
  • Praktisch wird TCP allerdings immer in IP gekapselt
  • garantiert eine fehlergesicherte, zuverlässige Transportverbindung zwischen zwei Rechnersystemen (Ende zu Ende Kontrolle)

TCP im DoD-Modell

  • Rolle von TCP im OSI-Referenzmodell

Eigenschaften von TCP

  • Vollduplex-Verbindung
  • stellt eine “byte pipe” zur Verfügung - unstrukturierter Datenstrom
  • Folgenummern sind Bytenummern
  • Sliding Window-Protokoll
  • Variable Grösse des Sendefensters bestimmt durch das Maximum von:
  • Angabe des Empfängers (receiver window size)
  • Congestion window size, abhängig von einer lokalen Schätzung der Netzbelastung -> “Slow Start” Algorithmus

Basismechanismen

  • Unterteilt den byte stream in Einheiten
  • die jeweils in einem IP Paket übertragen werden, diese Einheiten heißen Segmente
  • Segmente haben eine variable Länge
  • Die maximale Segmentgrösse wird bei der Verbindungserstellung festgelegt
  • Jedes Segment hat eine Folgenummer, die seine Position im Datenstrom in Bytes spezifiziert.
  • Abgesendete Segmente müssen innerhalb einer bestimmten Zeit bestätigt werden (adaptiv geschätzte Round Trip Time).
  • Bestätigungen werden verzögert gesendet (ca. 200 ms)
  • Wenn keine Bestätigung über den erfolgreichen Empfang dieses Paketes innerhalb der Timer-Laufzeit eintrifft, wird die Übertragung wiederholt.
  • Jedes Segment hat eine Ende-zu-Ende-Prüfsumme
  • Fehlerhaft empfangene Segmente werden ignoriert.
  • Empfänger ordnet empfangene Segmente entsprechend ihrer Folgenummer
  • Duplikate werden ignoriert.

Socket-Schnittstelle

  • De-facto-Standard für TCP/IP Programmierschnittstelle
  • Zugang zu TCP, UDP und (eingeschränkt) IP
  • Unterstützung verschiedener Protokolle
  • Protocol familiy
  • Address familiy
  • Abstraktion für Kommunikationsendpunkte
  • sockets

… mit verschiedenen Kommunikationseigenschaften

  • socket types (stream socket, datagram socket)
  • Benennung/Adressierung von Kommunikations-endpunkten
  • name binding
  • Können benutzt werden wie Dateideskriptoren

Verbindungen und Verbindungsendpunkte

  • Eine TCP-Verbindung wird durch ein Paar von Adressen und Port-Nummern identifiziert (Verbindungsendpunkte):
  • IP-Adresse und Port-Nummer Host A
  • IP-Adresse und Port-Nummer Host B
  • Jede Verbindung wird durch ein Paar von Verbindungsendpunkten eindeutig identifiziert
  • mehrere Verbindung zwischen den gleichen Hosts sind dadurch gleichzeitig möglich.

Segmente, Datenströme und Sequenznummern

  • Erhaltung der Reihenfolge
  • Nummerierung:
  • Zufallszahl auf beiden Seiten (32 Bit)
  • Seq.nr. := Initiale Seq.nr. + Byte-Position im Datenstrom
  • TCP betrachtet einen Datenstrom als Sequenz von Bytes, die für die Übertragung in TCP-Segmente eingeteilt werden.
  • Jedes Segment wird dann in der Regel auf ein IP-Paket abgebildet.
  • Größe eines Segmentes bei lokaler Übertragung gemäß physikalischem Netz (MTU)
  • Ist diese nicht angegeben oder kann sie nicht ermittelt werden, dann wird ein Standartwert von 536 Bytes verwandt

Header

Ein TCP-Segment besteht aus zwei Teilen
  • Header
  • Nutzlast
Header
  • enthält für die Steuerung der Kommunikation erforderliche Daten.
  • Da das Options-Feld in der Regel nicht genutzt wird, hat ein typischer Header eine Größe von 20 Byte.
Nutzlast
  • enthält die zu übertragenden Daten.
  • Die wiederum Protokollinformationen der Anwendungsschicht, wie HTTP oder FTP, entsprechen können.
Aufbau des Headers
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Source Port Destinations Port H
e
a
d
e
r
Sequence Number
Acknowledgement Number
Data Offset Reserved Flags Window
Checksum Urgent Pointer
Optionen Padding

Payload

Felder des TCP-Header

Feld Funktion Größe
Source Port (Quellport) Gibt die Portnummer auf der Senderseite an 2 Byte
Destinations Port (Zielport) Gibt die Portnummer auf der Empfängerseite an. 2 Byte
Sequence Number Sequenznummer des ersten Daten-Oktett dieses TCP-Segments, dient zur Sortierung Oder die Initialisierungs-Sequenznummer falls das SYN-Flag gesetzt ist 4 Byte
Acknowledgement Number Gibt die Sequenznummer an, die der Absender dieses TCP-Segments als Nächstes erwartet Sie ist nur gültig, falls das ACK-Flag gesetzt ist. 4 Byte
Data Offset Gibt die Länge des TCP-Headers in 32-Bit-Blöcken an (ohne Nutzdaten).
  • Hiermit wird die Startadresse der Nutzdaten angezeigt.
4 Bit
Reserved Ist für zukünftige Verwendungen reserviert.
  • Alle Bits müssen null sein.
4 Bit
Control-Flags Zweiwertige Variablen mit den Zuständen gesetzt und nicht gesetzt.
  • Kennzeichnung für die wichtigen Zustände der Kommunikation und Weiterverarbeitung der Daten.
8 Bit
(Receive) Window Ist die Anzahl der Bytes die der Sender dieses TCP-Segments bereit ist zu empfangen.
  • Beginnend bei dem durch das Acknowledgementfeld indizierten Daten-Oktett.
2 Byte
Checksum Dient zur Erkennung von Übertragungsfehlern.
  • Wird über den TCP-Header, die Daten und einen Pseudo-Header berechnet.
  • Der Header besteht aus Ziel-IP, Quell-IP, TCP-Protokollkennung (0x0006) und der Länge des TCP-Headers inkl. Nutzdaten (in Bytes).
2 Byte
Urgent Pointer Nur gültig, wenn das URG-Flag gesetzt ist.
  • Die Urgent-Daten beginnen sofort nach dem Header
  • Zusammen mit der Sequenz-Nummer gibt dieser Wert die Position des ersten Bytes nach den Urgent-Daten an.
2 Byte
Options Unterschiedlich groß und enthält Zusatzinformationen.
  • Müssen ein Vielfaches von 32 Bit lang sein, ansonsten muss mit Nullbits aufefüllt werden (Padding).
  • Ermöglicht Verbindungsdaten auszuhandeln, die nicht im TCP-Header enthalten sind, wie z.B. die Maximalgröße des Nutzdatenfeldes.
0–40 Byte

TCP-Flags

Feld Funktion Größe
ECE-Flag (ECN-Echo) Teilt dem Sender mit, dass das Netzwerk überlastet ist und die Senderate reduziert werden muss.
  • Wird für Explicit Congestion Notification (ECN) benötigt
1 Bit
CRW-Flag (Congestion Window Reduced) Teilt dem Empfänger mit das die Senderate reduziert wurde.
  • Wird für Explicit Congestion Notification (ECN) benötigt
1 Bit
URG-Flag (Urgent)
  • Die Daten nach dem Header werden sofort von der Anwendung bearbeitet.
  • Anwendung unterbricht die Datenverarbeitung des aktuellen TCP-Segments und liest alle Bytes nach dem Header bis zu dem Byte, auf das das Urgent-Pointer -Feld zeigt, aus.
  • Kann verwendet werden, um eine Anwendung auf dem Empfänger abzubrechen.
  • In der Regel wird dieses Flag nicht ausgewertet.
1 Bit
ACK-Flag (Acknowledgment) Hat in Verbindung mit der Acknowledgment-Nummer die Aufgabe, den Empfang von TCP-Segmenten bestätigen.
  • Die Acknowledgment-Nummer ist nur gültig, wenn das Flag gesetzt ist.
1 Bit
PSH-Flag (Push) Sowohl der ausgehende, als auch der eingehende Puffer wird übergangen.
  • Hilft den Datenstrom von TCP effizienter zu verarbeiten, indem die empfangende Applikation gezielter aufgeweckt werden kann.
  • RFC 1122 & RFC 793
1 Bit
RST-Flag (Reset) Wird verwendet, wenn eine Verbindung abgebrochen werden soll.
  • z.B. bei technischen Problemen oder zur Abweisung unerwünschter Verbindungen
  • Oder bei nicht geöffneten Ports, es wird kein ICMP-Paket mit „Port Unreachable“ verschickt.
1 Bit
SYN-Flag (Synchronize) Pakete mit diesem Flag initiieren eine Verbindung.
  • Dient der Synchronisation von Sequenznummern beim Verbindungsaufbau.
  • Server antwortet normalerweise mit SYN+ACK oder RST.
1 Bit
FIN-Flag (Finish) Schlussflag, dient zur Freigabe der Verbindung, zeigt an, dass keine Daten vom Sender kommen.
  • FIN- und SYN-Flags haben Sequenznummern, damit diese in der richtigen Reihenfolge abgearbeitet werden.
1 Bit

Der TCP-Header im Detail

  • Sender-Port

16-Bit-Adresse des Quell-Sockets

  • Empfänger-Port

16-Bit-Adresse des Ziels (Service)  Endpunkte der TCP-Verbindung 

  • Sequenznummer

32-Bit-Zahl zur Indentifizierung gesendeter Datensegmente

  • Quittungsnummer (Achnowledgment Number)
  • Gibt an bis zu welchem Byte Daten korrekt empfangen wurden, indem der Empfänger übermittelt, welche Byte als nächstes erwartet wird
  • Länge (Data Offset/Header Length)
  • Länge des TCP-Kopfes in 32Bit-Worten
  • Wegen der variablen Länge des Optionsfeldes notwendig
  • Fenstergröße
  • Fenstergröße in Byte ab dem bereits bestätigtem Byte
  • Flusssteuerung
  • wird vom Host je nach Belastung dynamisch festgelegt
  • Prüfsumme über
  • TCP-Paketkopf
  • Daten
  • Teile des IP-Paketkopfes (Pseudo-Header)
  • IP-Quell- und Ziel-Adresse
  • Protokollnummer (06)
  • TCP-Segmentlänge
  • Die Einbeziehung des Pseudo-Headers in die Prüfsumme hilft durch IP falsch zugeteilte Pakete zu erkennen
  • Der TCP-Header im Detail 4
  • Urgent-Zeiger
  • Ergibt zusammen mit der Sequenznummer einen Zeiger auf das Ende von dringenden Daten, die vor den eigentlichen Nutzdaten stehen
  • Wird nur bei gesetztem URG-Flag gelesen
  • Optionen
  • No-Option
  • Maximum Segment Size (MSS)
  • Maximale Anzahl von Nutzdaten die ein Host annehmen will oder kann
  • Wird bei beim Verbindungsaufbau ausgetauscht
  • Der kleinere Wert wird verwandt
  • Default ist 536 Byte
  • End of Option List
  • Füllzeichen
  • auf die nächste 32-Bit-Grenze wird mit Nullen aufgefüllt
  • Nutzdaten
  • Daten höherer Protokolle (z.B. http)

Flags

  • Sechs 1-Bit-Felder zur Steuerung der Verbindung
  • URG
  • Urgent: Der Urgent-Pointer wird verwand
  • ACK
  • Achnowledgement: Die Bestätigung ist gültig
  • PSH
  • Push: Daten werden beim Empfänger nicht gepuffert
  • RST
  • Reset: Verbindung wird zurückgesetzt (Ungültiges Segment, Hostabsturz oder Verbindungsablehnung)
  • SYN
  • Synchronise Sequenze Number: Verbindungsaufbau
  • FIN
  • Finish: Verbindungsabbau

Ports

siehe Port

Verbindungsverwaltung

Ein Server, der seinen Dienst anbietet, erzeugt einen Endpunkt (Socket) mit der Portnummer und seiner IP-Adresse.

  • Bezeichnet als "passive open" oder "listen".

Ein Client, der eine Verbindung aufbauen will, erzeugt einen Endpunkt (Socket) mit seiner IP-Adresse und einer eigenen, noch freien Portnummer.

  • Mit der Adresse des Servers und dem Port kann dann eine Verbindung aufgebaut werden.

Während der Datenübertragungsphase sind die Rollen von Client und Server (aus TCP-Sicht) vollkommen symmetrisch.

  • Bezeichnet als "active open"

Jeder der beiden beteiligten Rechner einen Verbindungsabbau einleiten.

TCP-Verbindungsmanagement

  • Das TCP-Verbindungsmanagement ist notwendig, weil die tieferen Netzwerkschichten keinen zuverlässigen Transport der Daten gewährleisten
  • Daten können beim Transport
  • verloren gehen
  • verfälscht werden (defekte Pakete)
  • durcheinander gebracht werden (falsche Reihenfolge)
  • verzögert werden
  • dupliziert werden
Phasen
  1. Verbindungsaufbau
  2. Datenaustausch
  3. Verbindungsabbau

Verbindungsaufbau

  • Verbindungswunsch
Bestätigung durch beide Seiten
  • TCP-Verbindungsaufbau Beispiel

Verbindungsaufbau

TCP-Handshake

  1. Der Client sendet dem Server ein SYN-Paket mit einer Sequenznummer x.
    • Die Sequenznummern sind für die Sicherstellung einer vollständigen Übertragung in der richtigen Reihenfolge und ohne Duplikate wichtig.
    • Ein Paket, dessen SYN-Bit im Header gesetzt ist.
    • Die Start-Sequenznummer ist eine beliebige zufällige Zahl, abhängig von der TCP-Implementierung.
  2. Der Server empfängt das Paket und antwortet.
    • Port geschlossen, antwortet er mit einem TCP-RST, ein Signal, dass keine Verbindung aufgebaut werden kann.
    • Port geöffnet, bestätigt er den Erhalt des ersten SYN-Pakets und stimmt dem Verbindungsaufbau zu, indem er ein SYN/ACK-Paket zurückschickt.
      • Ein Paket, mit ACK-Flag im TCP-Header, welche die Sequenznummer x+1 des SYN-Pakets im Header enthält.
      • Der Server sendet im Gegenzug seine Start-Sequenznummer y, diese ist unabhängig von der Start-Sequenznummer des Clients.
  3. Der Client bestätigt den Erhalt des SYN/ACK-Pakets durch ein eigenes ACK-Pakets mit der Sequenznummer x+1.
    • Wird auch als „Forward Acknowledgement“ bezeichnet.
    • Aus Sicherheitsgründen sendet der Client die Sequenznummer des Servers + 1 im ACK-Segment zurück.
  4. Die Verbindung ist damit aufgebaut.

Verbindungsaufbau Beispiel

1. SYN-SENT <SEQ=100><CTL=SYN> SYN-RECEIVED
2. SYN/ACK-RECEIVED <SEQ=300><ACK=101><CTL=SYN,ACK> SYN/ACK-SENT
3. ACK-SENT <SEQ=101><ACK=301><CTL=ACK> ESTABLISHED
  • Nach Aufbau ist die Verbindung für beide Kommunikationspartner gleichberechtigt
  • Man kann einer bestehenden Verbindung auf TCP-Ebene nicht ansehen, wer der Server und wer der Client ist.
  • Eine Unterscheidung dieser beiden Rollen in der weiteren Betrachtung keine Bedeutung mehr.

Verbindungsabbau

TCP-Teardown

  • Der Verbindungsabbau kann beidseitig oder schrittweise einseitig erfolgen.
  • Der geregelte Verbindungsabbau erfolgt dem Verbindungsaufbau ähnlich.
    1. Statt dem SYN-Bits kommt das FIN-Bit zum Einsatz, welches anzeigt, dass keine Daten mehr vom Sender kommen werden.
    2. Der Erhalt des Pakets wird mit ACK bestätigt und der Empfänger des FIN-Pakets sendet zuletzt seinerseits ein FIN-Paket.
    3. Dieses FIN-Paket wird ihm zuletzt bestätigt.
  • Ein verkürztes ist Verfahren möglich, bei dem FIN und ACK genau wie beim Verbindungsaufbau im selben Paket untergebracht werden.

Halb geschlossene Verbindungen

  • Der Verbindungsabbau erfolgt schrittweise einseitig.
  • Erlaubt der Gegenseite nach der einseitigen Trennung noch Daten zu übertragen.

Halb offene Verbindungen

  • wenn eine Seite abstürzt, ohne dass die verbleibende Seite dies erfährt.
  • Effekt: Betriebssystemressourcen werden nicht freigegeben.
  • Ursprung: TCP-Verbindungen von der Protokollseite bestehen, bis sie abgebaut werden.
Maximum segment lifetime (MSL)
  • Die maximale Zeit, die ein Segment im Netzwerk verbringen kann, bevor es verworfen wird.
  • Nach dem Senden des letzten ACKs wechselt der Client in einen zwei MSL andauernden Wartezustand (wait state), in dem alle verspäteten Segmente verworfen werden.
    • Dadurch wird sichergestellt, dass keine verspäteten Segmente als Teil einer neuen Verbindung fehlinterpretiert werden können.
    • Außerdem wird eine korrekte Verbindungsterminierung sichergestellt.
  • Geht ACK y+1 verloren, läuft beim Server der Timer ab, und das LAST_ACK-Segment wird erneut übertragen.

Puffer

  • Beim Datenversand über TCP werden zwei Puffer verwendet.
  1. Senderseitig übermittelt die Applikation die Sendedaten an TCP und dieses puffert die Daten.
  2. Effizient werden mehrere kleine Übertragungen in Form einer einzigen großen gesendet.
  3. Empfängerseitig landen die empfangenen Daten im Puffer, dieser verfolgt ähnliche Ziele.
  • Wenn von TCP mehrere einzelne Pakete empfangen wurden, ist es besser, diese zusammengefügt an die Applikation weiterzugeben.

Drei-Wege-Handschlag

  • Typisch werden Antworten auf das erste SYN- bzw. FIN-Paket zu einem einzelnen Paket zusammengefasst (SYN/ACK bzw. FIN/ACK).
    • Theoretisch wäre auch das Versenden zweier separater Pakete denkbar.
  • In diesem Fall müssen nur noch drei Pakete versendet werden, man spricht vom Drei-Wege-Handschlag.
  • Das Zusammenfassen des FIN-Pakets und ACK-Pakets ist problematisch.
    • Das Fin-Paket signalisiert „keine weiteren Daten“.
  • Allerdings kann der Sender des FIN-Pakets weiterhin Daten empfangen wollen (halb geschlossenen Verbindung).
Überlegung
  1. Den Beginn einer HTTP-Anfrage im SYN-Paket mitschicken, weitere Daten nach Verbindungsaufbau.
  2. Im letzten HTTP-Request-Paket die Verbindung mittels FIN schließen.
  • In der Praxis nicht angewendet da:
    • Wenn der Browser die Verbindung auf diese Art schließt, würde möglicherweise der Server die Verbindung schließen, anstatt die Anfrage vollständig zu beantworten.
Timeout bei Verbindungsaufbau
  • Was passiert, wenn der Kommunikationspartner nicht antwortet?
  • die Übertragung des Paketes wird wiederholt, TCP betrachtet dies als gewöhnlichen Paketverlust
  • nach einer festen Zeit (timeout) wird der Verbindungsversuch abgebrochen und die Anwendung informiert
Verbindungsaufbau
  • Aktives Öffnen einer Verbindung (SYN)
  • Passive Seite nimmt eine Verbindung auf einer bestimmten Port-Nummer entgegen
  • Die initialen Sequenznummern werden auf jeder Seite zufällig gewählt und bestätigt.
  • 3-fach-Handshake (nötig wegen des unzuverlässigen Dienstes von IP)

Datenübertragung

Segmentierung der Nutzdaten

TCP-/IP-Segment-Größe

  • Typischerweise eine Größe von maximal 1500 Byte
  • Muss in die darunter liegende Übertragungsschicht passen, das Internetprotokoll (IP).
  • IP-Pakete sind zwar bis 65.535Bytes (64KiB) spezifiziert, werden aber meist über Ethernet übertragen.
    • Bei Ethernet ist die Größe der (Layer-3-)Nutzdaten auf 64 bis 1500Bytes festgelegt (bei Jumbo Frames höher).
  • TCP- und IP-Protokoll definieren jeweils einen Header von 20Bytes Größe.
  • Für die (Applikations-)Nutzdaten bleiben in einem TCP/IP-Paket also 1460Bytes übrig.
  • Da die meisten Internet-Anschlüsse DSL verwenden, kommt zusätzlich das Point-to-Point Protocol (PPP) zwischen IP und Ethernet zur Anwendung (8Bytes).

Die Nutzdaten reduzieren sich also auf insgesamt 1500− 20− 20− 8 =1452Bytes Maximum Segment Size (MSS).

  • Dies entspricht einer maximalen Nutzdatenrate von 96,8 %.

Aufteilen der Anwendungsdaten auf TCP-/IP-Segmente

  1. Empfänger und Sender einigen sich vor dem Datenaustausch über das Options-Feld auf die Größe der Maximum Segment Size (MSS).
  2. Als Beispiel legt ein Webserver einen 7Kilobyte großen Datenblock im Puffer ab.
    • Um mit einem 1460Byte großen Nutzdatenfeld 7Kilobyte Daten zu versenden:
      1. Teilt die TCP-Software die Daten auf mehrere Pakete auf
      2. Fügt einen TCP-Header hinzu und versendet die TCP-Segmente.
    • Dieser Vorgang wird Segmentierung genannt.
  3. Der Datenblock im Puffer wird in fünf Segmente aufgeteilt, diese werden nacheinander abgeschickt.
    1. Jedes Segment erhält durch die TCP-Software einen TCP-Header.
  4. Segmente kommen nicht zwingend in richtiger Reihenfolge an.
  5. Um die Segmente wieder zu sortieren, ist jedes Segment nummeriert.
    • Bei der Zuordnung der Segmente im Empfänger wird die Sequenznummer herangezogen.
  6. Die TCP-Software des Empfängers bestätigt die einwandfrei angekommenen TCP-Segmente.
    • Andernfalls werden die Pakete neu angefordert.

TCP-/IP-Datenübertragung

Beispiel eines Datentransfers

  1. Der Sender schickt sein erstes TCP-Segment mit einer Sequenznummer SEQ=1 und einer Nutzdatenlänge von 1460Bytes an den Empfänger.
  2. Der Empfänger bestätigt es mit einem TCP-Header, ohne Daten, mit ACK=1461 und fordert das zweite TCP-Segment ab dem Byte Nummer 1461 an.
  3. Sender schickt es dann mit einem TCP-Segment und SEQ=1461 an den Empfänger.
  4. Empfäner bestätigt es wieder mit einem ACK=2921.
  • Der Empfänger braucht nicht jedes TCP-Segment zu bestätigen, wenn diese zusammenhängend sind.
  • Empfängt er die TCP-Segmente 1–5, so braucht er nur das letzte TCP-Segment zu bestätigen.
  • Fehlt zum Beispiel das 3. Segment, kann er nur die 1 und die 2 bestätigen, 4 und 5 jedoch noch nicht.
    • Da der Sender keine Bestätigung für die 3 bekommt, läuft sein Timer ab, und er verschickt die 3 noch einmal.
    • Kommt die 3 beim Empfänger an, so bestätigt er alle fünf TCP-Segmente, wenn beide die TCP-Option Selective ACK (SACK) unterstützen.
  • Der Sender startet für jedes TCP-Segment, welches er auf die Reise schickt, einen Retransmission Timer.

Retransmission Timer

  • Zur Feststellung, wann ein Paket im Netzwerk verloren gegangen ist, wird vom Sender ein Timeout verwendet, bis zu dem das ACK der Gegenseite eingetroffen sein muss.
    • Timeout zu niedrig, Pakete werden doppelt geschickt.
    • Timeout zu hoch, velorene Pakete werden zu spät neu geschickt.
  • Aufgrund unterschiedlicher Laufzeiten der IP-Pakete ist nur ein dynamischer Timer sinnvoll.

Flusssteuerung und Staukontrolle

In den folgenden zwei Abschnitten werden die TCP-Konzepte zur Flusssteuerung und Staukontrolle (oder Überlaststeuerung) erläutert.

  • Dabei werden das Sliding Window und das Congestion Window eingeführt.
  • Der Sender wählt als tatsächliche Sendefenstergröße das Minimum aus beiden Fenstern.
  • Es werden ARQ-Protokolle (Automatic Repeat reQuest) für eine zuverlässige Datenübertragung eingesetzt.

Flusssteuerung

Sliding Window

Da Daten aus dem Puffer gelesen werden, ändert sich der Füllstand des Puffers ständig.

  • Deshalb ist es notwendig, den Datenfluss dem Füllstand entsprechend zu steuern.
    • Dies geschieht mit dem Sliding Window und dessen Größe.
  • Der Puffer des Senders wird auf auf 10 Segmente erweitert.


Im Sliding Window (a) werden gerade die Segmente 1–5 übertragen.
  1. Obwohl der Puffer voll ist, werden die nächsten Daten (ab Byte 7301) mit ACK=7301 angefordert.
    • Das nächste Segment kann nicht mehr verarbeitet werden.
    • Mit dem Window-Feld (=0) teilt er dem Sender mit, dass keine Daten mehr verschickt werden sollen.
  2. Die Anwendung liest die Segmente 1–5 aus dem Puffer, es werden 7300Byte frei.
  3. Er kann die restlichen Segmente 6–10 mit einem TCP-Header (SEQ=1, ACK=7301, Window=7300), beim Sender anfordern.
  4. Der Sender weiß nun, dass er maximal fünf Segmente schicken kann, und verschiebt das Window um fünf Segmente nach rechts (Sliding Window (b)).
  5. Die Segmente 6–10 werden nun alle zusammen als Burst verschickt.
  6. Beim Ankommen aller TCP-Segmente beim Empfänger, quittiert er sie (SEQ=1 und ACK=14601) und fordert die nächsten Daten an.

Fehlerbehandlung

  • Checksummen-Fehler
  • Erkennen von Übertragungsfehlern
  • Defekte Pakete werden weggeworfen
  • Nach Timeout wird das entsprechende Paket neu gesendet
  • Abgebrochene Verbindung
  • plötzlicher Abbruch (Absturz, Kabel entfernt, ...)
  • Schließen der Verbindung nach Timeout

Datenaustausch

  • Senden eines Segments und Start eines Timer
  • Bestätigung mit nächster erwarteter Sequenznummer
  • Wird Timer überschritten, erneutes Senden

Effiziente Datenübertragung

  • TCP verwendet das Sliding-Window-Protocol
  • um möglichst effizient Daten zu übertragen und Flusskontrolle zu ermöglichen.
  • Bei einer Vollduplex-Verbindung müssen insgesamt 4 Fenster verwaltet werden.

TCP PUSH Flag (PSH)

  • die ursprüngliche Aufgabe des PSH Flags war es, dass der Sender eines Segmentes den Empfänger auffordert, dieses (und alle vorangegangenen) sofort bei der jeweiligen Anwendung auszuliefern, ohne dass es lange gepuffert wird
  • dies sollte z.B. für interaktive Anwendungen verwendet werden
  • wird inzwischen jedoch standardmäßig (fast) immer gesetzt, da keine Rechenzeit beim Auslesen der Puffer gespart werden muss

Sliding Window (wanderndes Fenster)

Variable Fenstergröße

  • Größe des Fensters kann variieren
  • Reagieren auf Netzwerk-Engpässe
  • Flusskontrolle (z.B. zwischen verschieden starken Partnern)
  • Verkehrssteuerung
  • Jacobsen's "slow start" Algorithmus variiert die Grösse des Sendefensters, um die Senderate an die Netzbelastung anzupassen
  • Siehe Überlastungskontrolle
  • Flusssteuerung
  • Jedes Bestätigungspaket enthält einen "window advertisement" Wert, in dem der Empfänger angibt, für wieviele weitere Pakete er noch freie Kapazität hat
  • das Fenster kann also größer oder kleiner werden

Abbau einer TCP-Verbindung

  • Senden eines Segments mit FIN=1
  • Bestätigung
  • muss für beide Richtungen separat erfolgen

TCP-Verbindungsabbau

  • durch zweimal half-close
  • da die TCP-Verbindung bidirektional ist, können beide Richtungen getrennt voneinander beendet werden
  • wer seine Senderolle beenden möchte, setzt das FIN Flag
  • FIN „kostet“ ein Byte und wird daher durch ein ack(nowledgement) bestätigt
  • der andere Teilnehmer kann weiter senden - jedoch sieht man fast immer das Verhalten, dass der andere Teilnehmer als Reaktion auch seine Senderolle beendet
  • derjenige Teilnehmer, der zuerst seine Verbindung beendet, führt ein „active close“ (i.d.R. der Client) durch, der Kommunikationspartner ein „passive close“ (i.d.R. der Server)

2MSL Wait State

  • derjenige Teilnehmer, der einen active close durchführt, muss nach Senden des ACKS die Verbindung für eine gewisse Zeit für das FIN des Kommunikationspartners offen halten
  • Grund: das ack könnte verloren gehen und müsste dann erneut übertragen werden
  • die „gewisse Zeit“ beträgt 2 maximal segment lifetimes (daher 2MSL wait state)
  • implementiert wird eine MSL als 30 - 120 Sekunden
  • während 2MSL Wait State kann daher die Port-Nummer noch nicht wieder für andere TCP-Verbindungen verwendet werden

TCP Reset

  • ein Segment, bei dem das RST (reset) bit im TCP header gesetzt ist, terminiert die Verbindung in Form eines „abortive release“ (im Gegensatz zum „orderly release“ mit FIN):
  • alle Daten, die beim Sender gepuffert waren, werden verworfen und das reset Segment wird sofort gesendet, die Verbindung ist damit aus Sicht des RST Senders sofort terminiert
  • es können beim Reset Daten verloren gehen (das passiert beim Verbindungsabbau mit FIN nicht)
  • der Emfänger eines RST Segmentes meldet dies der Anwendung und terminiert sofort
  • es gibt prinzipiell zwei unterschiedliche Situationen, wann ein RST gesendet wird:
  • wenn ein Port nicht belegt ist (connection refused)
  • wenn eine bestehende Verbindung abgebrochen wird (connection reset by peer)

Ablehnung einer Verbindung

  • Versuch eines Verbindungsaufbaus zu einem geschlossenen Port
  • Beispiel TCP
  • Beispiel UDP
Ablehnung einer Verbindung TCP
Ablehnung einer Verbindung UDP

Überlastungskontrolle

  • Bei Paketvermittelten Netzen kann es zu Überlastung kommen
  • Beim Zielhost
  • Innerhalb des Netzwerkes
  • Lösungen

Änderung der Fenstergröße

  • Congestion Windows Size (Größe des Überlastungsfensters)
  • Die tatsächliche Segmentgröße ist ein Limit aus beiden Werten

Slow Start with Congestion Avoidance

  • Beim Verbindungsaufbau wird das Überlastungfenster auf die Größe eines Segmentes gesetzt
  • Kommen die Quittungen des versandten Segmentes ohne Timeout an, wird die Größe des Überlastungsfensters verdoppelt
  • Dies geschieht bis zum Schwellenwert von 64 KByte
  • Danach pro erfolgreichem Sende- und Empfangszyklus um jeweils eine Segmentgröße
  • Dieser Algorithmus ist für zuverlässige Verbindungen konzipiert und sollte z.B. bei WLANs deaktiviert werden
  • Dort verringert er stark die effektive Bandbreite

Überlaststeuerung/Staukontrolle (Congestion Control)

  • Wird eine Verbindung stark belastet, werden immer mehr Pakete verworfen.
  • Durch die Wiederholung steigt wiederum die Belastung, dies sorgt (ohne Maßnahmen) für einen Datenstau.
  • Die Verlustrate wird von einem IP-Netzwerk ständig beobachtet.
  • Normalerweise wird eine TCP/IP-Verbindung langsam gestartet (Slow-Start) und die Senderate schrittweise erhöht, bis zum Datenverlust.
  • Ein Datenverlust verringert die Senderate, ohne Verlust wird sie wiederum erhöht.
Algorithmus zur Überlaststeuerung

Gehen bei einer bestimmten Fenstergröße Pakete verloren, kann das festgestellt werden, wenn der Sender innerhalb einer bestimmten Zeit (Timeout) kein ACK erhält.

  • Man muss davon ausgehen, dass das Paket aufgrund zu hoher Netzlast von einem Router im Netz verworfen wurde (Stau im Netz).
  • Um den Stau aufzulösen, müssen alle beteiligten Sender ihre Netzlast reduzieren.

Dazu werden im RFC 2581 vier Algorithmen definiert:

  1. slow start
  2. congestion avoidance
  3. fast retransmit
  4. fast recovery,
  • slow start und congestion avoidance werden zusammen verwendet.
  • fast retransmit und fast recovery werden zusammen verwendet, sind eine Erweiterung von slow start und congestion avoidance.
Slow Start Slow Start und Congestion Avoidance
Grafische Darstellung des Slow-Start-Algorithmus
  • Der Slow-Start-Algorithmus dient zur Bestimmung des congestion window.
  • Da die momentane Auslastung des Netzes nicht bekannt ist, wird mit kleinen Datenmengen begonnen.
  1. Der Algorithmus startet mit einem kleinen Fenster, von einer Maximum Segment Size (MSS), in dem Datenpakete vom Sender zum Empfänger übertragen werden.
  2. Der Empfänger sendet ACK an den Sender zurück.
  3. Für jedes empfangene ACK wird die Größe des congestion window um eine MSS erhöht.
    • Dies führt innerhalb einer Roundtrip-Zeit zu einer Verdopplung des Congestion Windows.
  4. Dieses exponentielle Wachstum wird so lange fortgesetzt, bis der Slow-Start Threshold erreicht wird.
    • Die Phase des exponentiellen Wachstums wird auch Slow Start Phase genannt.
  5. Danach wird das Congestion Window nur noch um eine MSS erhöht, wenn alle Pakete aus dem Fenster erfolgreich übertragen wurden.
    • Es wächst pro Roundtrip-Zeit nur noch um eine MSS, also nur noch linear.
      • Diese Phase wird als Congestion Avoidance Phase bezeichnet.
    • Das Wachstum wird beendet, wenn das vom Empfänger festgelegte Empfangsfenster erreicht worden ist.


Kommt es zu einem Timeout, wird das congestion window auf 1 zurückgesetzt, der slow-start threshold wird auf die Hälfte der gesendeten, unquittierten Pakete herabgesetzt (Flight Size).

  • Die Phase des exponentiellen Wachstums wird also verkürzt.
  • Das Fenster wächst bei häufigen Paketverlusten nur langsam.
Fast-Retransmit und Fast-Recovery
  • Werden eingesetzt, um nach Paketverlust schneller auf die Stau-Situation zu reagieren.
  • Empfänger informiert den Sender, wenn Pakete außer der Reihe ankommen und somit dazwischen ein Paketverlust vorliegt.
  • Der Empfänger bestätigt das letzte korrekte Paket erneut für jedes weitere ankommende Paket außer der Reihe.
  • Man spricht dabei von Dup-Acks (duplicate acknowledgments),
    • Mehrere aufeinanderfolgende Nachrichten, welche dasselbe Datensegment ACKen.
  • Der Sender bemerkt die duplizierten ACKS, und nach dem dritten Duplikat sendet er sofort, vor Ablauf des Timers, das verlorene Paket erneut.
    • Da nicht auf den Timerablauf gewartet werden muss, heißt das Prinzip Fast Retransmit.
  • Dup-Acks: auch Hinweise darauf, dass ein Paketverlust stattfand, dennoch die folgenden Pakete angekommen sind.
  • Das Sendefenster wird nach dem Fehler nur halbiert (kein Slow-Start).


Zusätzlich kann das Sendefenster noch um die Anzahl der Dup-Acks erhöht werden,

  • Jedes Dup-Ack steht für ein weiteres Paket, welches den Empfänger erreicht hat.
  • Dadurch kann nach dem Fehler schneller wieder die volle Sendeleistung erreicht werden.
  • Das Prinzip nennt man Fast-Recovery.
Verwaltung der TCP-Verbindungen als endlicher Automat
Verwaltung der TCP-Verbindungen als endlicher Automat

Installation

Konfiguration

Dateien

Dokumentation

Dokumentation

RFC

  1. RFC 793 (1981)
  2. RFC 7323 (2014)

Man-Pages

Info-Pages

Siehe auch

Links

Projekt-Homepage

Weblinks

Einzelnachweise


Testfragen

Testfrage 1

Antwort1

Testfrage 2

Antwort2

Testfrage 3

Antwort3

Testfrage 4

Antwort4

Testfrage 5

Antwort5

Wikipedia

TCP (Transmission Control Protocol)
Familie: Internetprotokollfamilie
Einsatzgebiet: Zuverlässiger bidirektionaler
Datentransport

Vorlage:Netzwerk-IP-Transportprotokoll

Standards: RFC 9293 (2022)
RFC 7323 (2014)

Das (TCP, Vorlage:DeS) ist ein Netzwerkprotokoll, das definiert, auf welche Art und Weise Daten zwischen Netzwerkkomponenten ausgetauscht werden sollen. Nahezu sämtliche aktuelle Betriebssysteme moderner Computer beherrschen TCP und nutzen es für den Datenaustausch mit anderen Rechnern. Das Protokoll ist ein zuverlässiges, verbindungsorientiertes, paketvermitteltes[1] Transportprotokoll in Computernetzwerken. Es ist Teil der Internetprotokollfamilie, der Grundlage des Internets.

Entwickelt wurde TCP von Robert E. Kahn und Vinton G. Cerf. Ihre Forschungsarbeit, die sie im Jahr 1973 begannen, dauerte mehrere Jahre. Die erste Standardisierung von TCP erfolgte deshalb erst im Jahr 1981 als RFC 793. Danach gab es viele Erweiterungen, die bis heute in neuen RFCs, einer Reihe von technischen und organisatorischen Dokumenten zum Internet, spezifiziert werden. RFC 9293 bündelt die ursprüngliche Fassung und alle ihre Erweiterungen in ein einziges Dokument.

Im Unterschied zum verbindungslosen UDP () stellt TCP eine Verbindung zwischen zwei Endpunkten einer Netzverbindung (Sockets) her. Auf dieser Verbindung können in beide Richtungen Daten übertragen werden. TCP setzt in den meisten Fällen auf das IP (Internet-Protokoll) auf, weshalb häufig (und oft nicht ganz korrekt) auch vom „TCP/IP-Protokoll“ die Rede ist. In Protokollstapeln wie dem OSI-Modell sind TCP und IP nicht auf derselben Schicht angesiedelt. TCP ist eine Implementierung der Transportschicht.

Aufgrund seiner vielen positiven Eigenschaften (Datenverluste werden erkannt und automatisch behoben, Datenübertragung ist in beiden Richtungen möglich, Netzüberlastung wird verhindert usw.) ist TCP ein sehr weit verbreitetes Protokoll zur Datenübertragung. Beispielsweise wurde TCP lange Zeit als fast ausschließliches Transportprotokoll für das WWW, E-Mail und viele andere populäre Netzdienste verwendet. Im WWW bekommt TCP Konkurrenz durch das verschlüsselte Transportprotokoll QUIC, das im Jahr 2021 standardisiert wurde.

Allgemeines

TCP ist im Prinzip eine Ende-zu-Ende-Verbindung in Vollduplex, welche die Übertragung der Informationen in beide Richtungen zulässt, analog zu einem Telefongespräch. Diese Verbindung kann auch als zwei Halbduplexverbindungen, bei denen Informationen in beide Richtungen (allerdings nicht gleichzeitig) fließen können, betrachtet werden. Die Daten in Gegenrichtung können dabei zusätzliche Steuerungsinformationen enthalten. Die Verwaltung dieser Verbindung sowie die Datenübertragung werden von der TCP-Software übernommen. Die TCP-Software ist üblicherweise im Netz-Protokollstack des Betriebssystems angesiedelt. Anwendungsprogramme benutzen eine Schnittstelle dazu, meist Sockets, die sich (je nach Betriebssystem unterschiedlich) beispielsweise bei Microsoft Windows in extra einzubindenden Programmbibliotheken („Winsock.dll“ bzw. „wsock32.dll“) befinden. Linux und viele andere unixoide Betriebssysteme enthalten einen Socketlayer im Betriebssystemkern. Auf den Socketlayer wird über Systemaufrufe zugegriffen. Anwendungen, die TCP häufig nutzen, sind zum Beispiel Webbrowser und Webserver.

Jede TCP-Verbindung wird eindeutig durch zwei Endpunkte identifiziert. Ein Endpunkt stellt ein geordnetes Paar dar, bestehend aus IP-Adresse und Port. Ein solches Paar bildet eine bidirektionale Software-Schnittstelle und wird auch als Socket bezeichnet. Somit wird eine TCP-Verbindung durch vier Werte (einem Quadrupel) identifiziert:

(Lokaler Rechner, Lokaler Port, Entfernter Rechner, Entfernter Port)

Dabei kommt es auf das gesamte Quadrupel an. Beispielsweise können zwei verschiedene Prozesse auf demselben Rechner denselben lokalen Port benutzen und dabei sogar mit demselben Rechner auf der gegenüberliegenden Seite kommunizieren, sofern die beteiligten Prozesse auf der anderen Seite unterschiedliche Ports benutzen. In einem solchen Fall würde es sich um zwei verschiedene Verbindungen handeln, deren Quadrupel sich nur in einem von vier Werten unterscheidet: dem Port auf der gegenüberliegenden Seite.

Verbindung 1: (Lokaler Rechner, Port x, Entfernter Rechner, Port y)
Verbindung 2: (Lokaler Rechner, Port x, Entfernter Rechner, Port z)

Ein Serverprozess erzeugt beispielsweise einen Socket (Vorlage:Lang, Vorlage:Lang) auf Port 80, markiert diesen für eingehende Verbindungen (Vorlage:Lang) und fordert vom Betriebssystem die nächste anstehende Verbindung an (Vorlage:Lang). Diese Anforderung blockiert den Serverprozess zunächst, da noch keine Verbindung existiert. Kommt dann die erste Verbindungsanfrage durch einen Client an, wird sie vom Betriebssystem angenommen, so dass die Verbindung zustande kommt. Ab jetzt wird diese Verbindung durch das oben beschriebene Quadrupel identifiziert.

Schließlich wird der Serverprozess aufgeweckt und ihm ein Handle für diese Verbindung überreicht. Üblicherweise startet der Serverprozess anschließend einen Kindprozess, zu dem er die Behandlung der Verbindung delegiert. Er selbst setzt dann seine Arbeit mit einer weiteren Accept-Anforderung an das Betriebssystem fort. Dadurch ist es möglich, dass ein Webserver mehrere Verbindungen von verschiedenen Rechnern annehmen kann. Mehrfaches Vorlage:Lang auf demselben Port ist nicht möglich. Üblicherweise bestimmt das Programm auf der Clientseite den Port nicht selbst, sondern lässt ihn sich vom Betriebssystem zuweisen.

Ports sind 16-Bit-Zahlen (Portnummern) und reichen von 0 bis 65535. Ports von 0 bis 1023 sind reserviert[2] und werden von der IANA vergeben, z. B. ist Port 80 für das im WWW verwendete HTTP reserviert. Das Benutzen der vordefinierten Ports ist nicht bindend. So kann jeder Administrator beispielsweise einen FTP-Server (normalerweise Port 21) auch auf einem beliebigen anderen Port laufen lassen.

Verbindungsaufbau und -abbau

Abb. 2: Verwaltung der TCP-Verbindungen als endlicher Automat

Ein Server, der seinen Dienst anbietet, erzeugt einen Endpunkt (Socket) mit der Portnummer und seiner IP-Adresse. Dies wird als Vorlage:Lang[3] oder auch als Vorlage:Lang[4] bezeichnet.

Will ein Client eine Verbindung aufbauen, erzeugt er einen eigenen Socket aus seiner Rechneradresse und einer eigenen, noch freien Portnummer. Mit Hilfe eines ihm bekannten Ports und der Adresse des Servers kann dann eine Verbindung aufgebaut werden. Eine TCP-Verbindung ist durch folgende 4 Werte eindeutig identifiziert:

  • Quell-IP-Adresse
  • Quell-Port
  • Ziel-IP-Adresse
  • Ziel-Port

Während der Datenübertragungsphase (Vorlage:Lang) sind die Rollen von Client und Server (aus TCP-Sicht) vollkommen symmetrisch. Insbesondere kann jeder der beiden beteiligten Rechner einen Verbindungsabbau einleiten.

Halb geschlossene Verbindungen

Der Verbindungsabbau kann auf zwei Arten erfolgen: beidseitig oder schrittweise einseitig. Bei letzterer Variante spricht man von einer halb geschlossenen Verbindung (nicht zu verwechseln mit halb offenen Verbindungen, siehe unten). Sie erlaubt der Gegenseite nach der einseitigen Trennung noch Daten zu übertragen.

Halb geschlossene Verbindungen sind ein Erbe des Betriebssystems Unix, in dessen Umfeld TCP entstanden ist. Entsprechend dem Grundsatz Vorlage:Lang (dt. „Alles ist eine Datei“) unterstützt Unix bei TCP-Verbindungen eine zu Pipes völlig analoge Interaktion zweier Prozesse: für ein Programm soll es schlichtweg irrelevant sein, ob es von einer TCP-Verbindung oder einer Datei liest. Ein Unix-Programm liest typischerweise bis zum Ende der Standardeingabe und schreibt anschließend das Verarbeitungsergebnis in die Standardausgabe. Die Standard-Datenströme werden vor Ausführung des Programms mit Dateien verbunden.

Die Hin- und Rückkanäle einer TCP-Verbindung werden mit Standardein- und -ausgabe verbunden und somit logisch als je eine Datei repräsentiert. Eine geschlossene Verbindung wird dem lesenden Prozess als erreichtes Dateiende übersetzt. Das angesprochene typische Unix-Verarbeitungsschema setzt voraus, dass die Verbindung in Rückrichtung nach dem Lesen des Dateiendes noch zum Schreiben bereitsteht, woraus der Bedarf für halb geschlossene Verbindungen resultiert.[5]

Halb offene Verbindungen

Eine Verbindung ist halb offen, wenn eine Seite abstürzt, ohne dass die verbleibende Seite dies erfährt. Dies hat den unerwünschten Effekt, dass Betriebssystemressourcen nicht freigegeben werden. Halb offene Verbindungen können entstehen, weil TCP-Verbindungen von Protokollseite solange bestehen, bis sie abgebaut werden. Häufig werden jedoch von Anwendungsseite entsprechende Vorkehrungen getroffen.

Verbindungsaufbau

Abb. 3: TCP-Handshake

Der Client, der eine Verbindung aufbauen will, sendet dem Server ein SYN-Paket (von ) mit einer Sequenznummer x. Die Sequenznummern sind dabei für die Sicherstellung einer vollständigen Übertragung in der richtigen Reihenfolge und ohne Duplikate wichtig. Es handelt sich also um ein Paket, dessen SYN-Bit im Paketkopf gesetzt ist (siehe TCP-Header). Die Start-Sequenznummer (auch Initial Sequence Number (ISN) genannt) ist eine beliebige Zahl, deren Generierung von der jeweiligen TCP-Implementierung abhängig ist. Sie sollte jedoch möglichst zufällig sein, um Sicherheitsrisiken zu vermeiden.[6]

Der Server (siehe Skizze) empfängt das Paket. Ist der Port geschlossen, antwortet er mit einem TCP-RST, um zu signalisieren, dass keine Verbindung aufgebaut werden kann. Ist der Port geöffnet, bestätigt er den Erhalt des ersten SYN-Pakets und stimmt dem Verbindungsaufbau zu, indem er ein SYN/ACK-Paket zurückschickt (ACK von engl. Vorlage:Lang ‚Bestätigung‘). Das gesetzte ACK-Flag im TCP-Header kennzeichnet diese Pakete, welche die Sequenznummer x+1 des SYN-Pakets im Header enthalten. Zusätzlich sendet er im Gegenzug seine Start-Sequenznummer y, die ebenfalls beliebig und unabhängig von der Start-Sequenznummer des Clients ist.

Der Client bestätigt zuletzt den Erhalt des SYN/ACK-Pakets durch das Senden eines eigenen ACK-Pakets mit der Sequenznummer x+1. Dieser Vorgang wird auch als „Forward Acknowledgement“ bezeichnet. Aus Sicherheitsgründen sendet der Client den Wert y+1 (die Sequenznummer des Servers + 1) im ACK-Segment zurück. Die Verbindung ist damit aufgebaut. Im folgenden Beispiel wird der Vorgang abstrakt dargestellt:

1. SYN-SENT <SEQ=100><CTL=SYN> SYN-RECEIVED
2. SYN/ACK-RECEIVED <SEQ=300><ACK=101><CTL=SYN,ACK> SYN/ACK-SENT
3. ACK-SENT <SEQ=101><ACK=301><CTL=ACK> ESTABLISHED

Einmal aufgebaut, ist die Verbindung für beide Kommunikationspartner gleichberechtigt, man kann einer bestehenden Verbindung auf TCP-Ebene nicht ansehen, wer der Server und wer der Client ist. Daher hat eine Unterscheidung dieser beiden Rollen in der weiteren Betrachtung keine Bedeutung mehr.

Verbindungsabbau

Abb. 4: TCP-Teardown

Der geregelte Verbindungsabbau erfolgt ähnlich. Statt des SYN-Bits kommt das FIN-Bit (von engl. Vorlage:Lang ‚Ende‘, ‚Abschluss‘) zum Einsatz, welches anzeigt, dass keine Daten mehr vom Sender kommen werden. Der Erhalt des Pakets wird wiederum mittels ACK bestätigt. Der Empfänger des FIN-Pakets sendet zuletzt seinerseits ein FIN-Paket, das ihm ebenfalls bestätigt wird.

Zudem ist ein verkürztes Verfahren möglich, bei dem FIN und ACK genau wie beim Verbindungsaufbau im selben Paket untergebracht werden. Die Vorlage:Lang (MSL) ist die maximale Zeit, die ein Segment im Netzwerk verbringen kann, bevor es verworfen wird. Nach dem Senden des letzten ACKs wechselt der Client in einen zwei MSL andauernden Wartezustand (Vorlage:Lang), in dem alle verspäteten Segmente verworfen werden. Dadurch wird sichergestellt, dass keine verspäteten Segmente fehlinterpretiert werden können als Teil einer neuen Verbindung, die zufällig den gleichen Port benutzt. Außerdem wird eine korrekte Verbindungsterminierung sichergestellt. Geht ACK y+1 verloren, läuft beim Server der Timer ab, und das LAST_ACK-Segment wird erneut übertragen.

Puffer

Beim Versenden von Daten über das TCP werden zwei Puffer verwendet. Senderseitig übermittelt die Applikation die zu sendenden Daten an das TCP und dieses puffert die Daten, um mehrere kleine Übertragungen effizienter in Form einer einzigen großen zu senden. Nachdem die Daten dann an den Empfänger übermittelt wurden, landen sie im empfängerseitigen Puffer. Dieser verfolgt ähnliche Ziele. Wenn vom TCP mehrere einzelne Pakete empfangen wurden, ist es besser, diese zusammengefügt an die Applikation weiterzugeben.

Drei-Wege-Handschlag

Sowohl beim Verbindungsaufbau als auch beim Verbindungsabbau werden die Antworten auf das erste SYN- bzw. FIN-Paket typischerweise zu einem einzelnen Paket (SYN/ACK bzw. FIN/ACK) zusammengefasst – theoretisch wäre auch das Versenden zweier separater Pakete denkbar. Da in diesem Fall nur noch drei Pakete versendet werden müssen, spricht man auch häufig vom sogenannten Drei-Wege-Handschlag. Das Zusammenfassen des FIN-Pakets und des ACK-Pakets ist allerdings problematisch, da das Senden eines FIN-Pakets die Bedeutung hat „es folgen keine weiteren Daten mehr“. Allerdings kann der Sender des FIN-Pakets weiterhin Daten empfangen (wollen); man spricht von einer halb geschlossenen Verbindung (die Empfangsrichtung ist weiterhin offen, während die Senderichtung geschlossen wurde). Es wäre z. B. denkbar, den Beginn einer HTTP-Anfrage (HTTP-Request) direkt im SYN-Paket mitzuschicken, weitere Daten, sobald die Verbindung aufgebaut wurde, und im letzten HTTP-Request-Paket die (Senderichtung der) Verbindung gleich mittels FIN zu schließen. In der Praxis wird dieses Verfahren allerdings nicht angewendet. Würde der Browser die Verbindung auf diese Art sofort schließen, würde möglicherweise auch der Server die Verbindung schließen anstatt die Anfrage vollständig zu beantworten.

Aufbau des TCP-Headers

Allgemeines

Das TCP-Segment besteht immer aus zwei Teilen: dem Header und der Nutzlast (). Die Nutzlast enthält die zu übertragenden Daten, die wiederum Protokollinformationen der Anwendungsschicht, wie HTTP oder FTP, entsprechen können. Der Header enthält für die Kommunikation erforderliche Daten sowie die Dateiformat-beschreibende Information. Den schematischen Aufbau des TCP-Headers kann man in Abbildung 5 sehen. Da das Options-Feld in der Regel nicht genutzt wird, hat ein typischer Header eine Größe von 20 Byte. Die Werte werden in der Byte-Reihenfolge Big-Endian angegeben.

Erläuterung

Abb. 5: Aufbau des TCP-Headers
Vorlage:Lang (Quellport) (2 Byte)
Gibt die Portnummer auf der Senderseite an.
Vorlage:Lang (Zielport) (2 Byte)
Gibt die Portnummer auf der Empfängerseite an.
Vorlage:Lang (4 Byte)
Sequenznummer des ersten Daten-Oktetts (Byte) dieses TCP-Pakets oder die Initialisierungs-Sequenznummer falls das SYN-Flag gesetzt ist. Nach der Datenübertragung dient sie zur Sortierung der TCP-Segmente, da diese in unterschiedlicher Reihenfolge beim Empfänger ankommen können.
Vorlage:Lang (Quittierungsnummer) (4 Byte)
Sie gibt die Sequenznummer an, die der Absender dieses TCP-Segmentes als Nächstes erwartet. Sie ist nur gültig, falls das ACK-Flag gesetzt ist.
Vorlage:Lang (4 Bit)
Länge des TCP-Headers in 32-Bit-Blöcken – ohne die Nutzdaten (Payload). Hiermit wird die Startadresse der Nutzdaten angezeigt.
Reserved (4 Bit)
Das Reserved-Feld ist für zukünftige Verwendungen reserviert. Alle Bits müssen null sein.
Control-Flags (8 Bit)
Sind zweiwertige Variablen mit den möglichen Zuständen gesetzt und nicht gesetzt, die zur Kennzeichnung bestimmter für die Kommunikation und Weiterverarbeitung der Daten wichtiger Zustände benötigt werden. Im Folgenden werden die Flags des TCP-Headers und die von ihrem Zustand abhängigen, auszuführenden Aktionen beschrieben.
CWR und ECE
sind zwei Flags, die für Explicit Congestion Notification (ECN) benötigt werden. Mit gesetztem ECE-Bit (ECN-Echo) teilt der Empfänger dem Sender mit, dass das Netzwerk überlastet ist und die Senderate reduziert werden muss. Hat der Sender das getan, teilt er dies dem Empfänger durch Setzen des CWR-Bit (Vorlage:Lang) mit.
URG
Ist das Urgent-Flag (urgent = dringend) gesetzt, so werden die Daten nach dem Header sofort von der Anwendung bearbeitet. Dabei unterbricht die Anwendung die Verarbeitung der Daten des aktuellen TCP-Segments und liest alle Bytes nach dem Header bis zu dem Byte, auf das das Urgent-Pointer-Feld zeigt, aus. Dieses Verfahren ist fern verwandt mit einem Softwareinterrupt. Dieses Flag kann zum Beispiel verwendet werden, um eine Anwendung auf dem Empfänger abzubrechen. Das Verfahren wird nur äußerst selten benutzt, Beispiele sind die bevorzugte Behandlung von CTRL-C (Abbruch) bei einer Terminalverbindung über rlogin oder telnet.
In der Regel wird dieses Flag nicht ausgewertet.
ACK
Das Acknowledgment-Flag hat in Verbindung mit der Acknowledgment-Nummer die Aufgabe, den Empfang von TCP-Segmenten beim Datentransfer zu bestätigen. Die Acknowledgment-Nummer ist nur gültig, wenn das Flag gesetzt ist.
PSH
RFC 1122 und RFC 793 spezifizieren das Push-Flag so, dass bei gesetztem Flag sowohl der ausgehende, als auch der eingehende Puffer übergangen wird. Da man bei TCP keine Datagramme versendet, sondern einen Datenstrom hat, hilft das PSH-Flag, den Strom effizienter zu verarbeiten, da die empfangende Applikation so gezielter aufgeweckt werden kann und nicht bei jedem eintreffenden Datensegment feststellen muss, dass Teile der Daten noch nicht empfangen wurden, die aber nötig wären, um überhaupt weitermachen zu können.
Hilfreich ist dies, wenn man zum Beispiel bei einer Telnet-Sitzung einen Befehl an den Empfänger senden will. Würde dieser Befehl erst im Puffer zwischengespeichert werden, so würde dieser (stark) verzögert abgearbeitet werden.
Das PSH-Flag kann, abhängig von der TCP-Implementation im Verhalten zu obiger Erklärung abweichen.
RST
Das Reset-Flag wird verwendet, wenn eine Verbindung abgebrochen werden soll. Dies geschieht zum Beispiel bei technischen Problemen oder zur Abweisung unerwünschter Verbindungen (wie etwa nicht geöffneten Ports, hier wird – anders als bei UDP – kein ICMP-Paket mit „Port Unreachable“ verschickt).
SYN
Pakete mit gesetztem SYN-Flag initiieren eine Verbindung. Der Server antwortet normalerweise entweder mit SYN+ACK, wenn er bereit ist, die Verbindung anzunehmen, andernfalls mit RST. Dient der Synchronisation von Sequenznummern beim Verbindungsaufbau (daher die Bezeichnung SYN).
FIN
Dieses Schlussflag (finish) dient zur Freigabe der Verbindung und zeigt an, dass keine Daten mehr vom Sender kommen. Die FIN- und SYN-Flags haben Sequenznummern, damit diese in der richtigen Reihenfolge abgearbeitet werden.
(Receive) Window (2 Byte)
Ist – nach Multiplikation mit dem Fensterskalierungsfaktor – die Anzahl der Daten-Oktetts (Bytes), beginnend bei dem durch das Acknowledgementfeld indizierten Daten-Oktett, die der Sender dieses TCP-Pakets bereit ist zu empfangen.
Checksum (2 Byte)
Die Prüfsumme dient zur Erkennung von Übertragungsfehlern und wird über den TCP-Header, die Daten und einen Pseudo-Header berechnet. Dieser Header besteht aus der Ziel-IP, der Quell-IP, der TCP-Protokollkennung (0x0006) und der Länge des TCP-Headers inkl. Nutzdaten (in Bytes).
Vorlage:Lang (2 Byte)
Zusammen mit der Sequenz-Nummer gibt dieser Wert die Position des ersten Bytes nach den Urgent-Daten im Datenstrom an. Die Urgent-Daten beginnen sofort nach dem Header. Der Wert ist nur gültig, wenn das URG-Flag gesetzt ist.
Options (0–40 Byte)
Das Options-Feld ist unterschiedlich groß und enthält Zusatzinformationen. Die Optionen müssen ein Vielfaches von 32 Bit lang sein. Sind sie das nicht, muss mit Nullbits aufgefüllt werden (Vorlage:Lang). Dieses Feld ermöglicht, Verbindungsdaten auszuhandeln, die nicht im TCP-Header enthalten sind, wie zum Beispiel die Maximalgröße des Nutzdatenfeldes.

Datenübertragung

Abb. 6: Segmentierung der Nutzdaten

TCP-/IP-Segment-Größe

Ein TCP-Segment hat typischerweise eine Größe von maximal 1500 Bytes. Ein TCP-Segment muss jedoch in die darunter liegende Übertragungsschicht passen, das Internetprotokoll (IP); siehe hierzu auch Maximum Transmission Unit (MTU).

IP-Pakete wiederum sind zwar theoretisch bis 65.535 Bytes (64 KiB) spezifiziert, werden aber selbst meist über Ethernet übertragen, und bei Ethernet ist die Größe der (Layer-3-)Nutzdaten (wenn man von Jumbo Frames absieht) auf 64 (ggf. inklusive Padding) bis 1500 Bytes festgelegt. TCP- und IP-Protokoll definieren jeweils einen Header von 20 Bytes Größe. Für die (Applikations-)Nutzdaten bleiben in einem TCP/IP-Paket also 1460 Bytes (= 1500 Bytes Ethernet-[Nutzdaten] − 20 Bytes Headerdaten TCP − 20 Bytes Headerdaten IP) übrig. Da die meisten Internet-Anschlüsse DSL verwenden, kommt dort zusätzlich noch das Point-to-Point Protocol (PPP) zwischen IP und Ethernet zur Anwendung, was weitere 8 Bytes für den PPP-Rahmen verbraucht. Die Nutzdaten reduzieren sich also auf insgesamt 1500 − 20 − 20 − 8 = 1452 Bytes MSS (Maximum Segment Size). Dies entspricht einer maximalen Nutzdatenrate von 96,8 %.

Aufteilen der Anwendungsdaten auf TCP-/IP-Segmente

Empfänger und Sender einigen sich vor dem Datenaustausch über das Options-Feld auf die Größe der MSS. Die Anwendung, die Daten versenden möchte, etwa ein Webserver, legt zum Beispiel einen 7 Kilobyte großen Datenblock im Puffer ab. Um mit einem 1460 Byte großen Nutzdatenfeld 7 Kilobyte Daten zu versenden, teilt die TCP-Software die Daten auf mehrere Pakete auf, fügt einen TCP-Header hinzu und versendet die TCP-Segmente. Dieser Vorgang wird Segmentierung genannt. Der Datenblock im Puffer wird in fünf Segmente aufgeteilt (siehe Abb. 6). Jedes Segment erhält durch die TCP-Software einen TCP-Header. Die TCP-Segmente werden nacheinander abgeschickt. Diese kommen beim Empfänger nicht notwendigerweise in derselben Reihenfolge an, in der sie versendet wurden, da im Internet unter Umständen jedes TCP-Segment einen anderen Weg nimmt. Damit die TCP-Software im Empfänger die Segmente wieder sortieren kann, ist jedes Segment nummeriert. Bei der Zuordnung der Segmente im Empfänger wird die Sequenznummer herangezogen.

Abb. 7: Beispiel eines Datentransfers

Die TCP-Software des Empfängers bestätigt diejenigen TCP-Segmente, die einwandfrei (das heißt mit korrekter Prüfsumme) angekommen sind. Andernfalls werden die Pakete neu angefordert.

Beispiel einer TCP-/IP-Datenübertragung

Der Sender schickt sein erstes TCP-Segment mit einer Sequenznummer SEQ=1 (variiert) und einer Nutzdatenlänge von 1460 Bytes an den Empfänger. Der Empfänger bestätigt es mit einem TCP-Header ohne Daten mit ACK=1461 und fordert damit das zweite TCP-Segment ab dem Byte Nummer 1461 beim Sender an. Dieser schickt es dann mit einem TCP-Segment und SEQ=1461 an den Empfänger. Dieser bestätigt es wieder mit einem ACK=2921 und so weiter. Der Empfänger braucht nicht jedes TCP-Segment zu bestätigen, wenn diese zusammenhängend sind. Empfängt er die TCP-Segmente 1–5, so braucht er nur das letzte TCP-Segment zu bestätigen. Fehlt zum Beispiel das TCP-Segment 3, weil es verlorengegangen ist, so kann er nur die 1 und die 2 bestätigen, 4 und 5 jedoch noch nicht. Da der Sender keine Bestätigung für die 3 bekommt, läuft sein Timer ab, und er verschickt die 3 noch einmal. Kommt die 3 beim Empfänger an, so bestätigt er alle fünf TCP-Segmente, sofern beide Seiten die TCP-Option SACK (Selective ACK) unterstützen. Der Sender startet für jedes TCP-Segment, welches er auf die Reise schickt, einen Retransmission Timer.

Retransmission Timer

Zur Feststellung, wann ein Paket im Netzwerk verloren gegangen ist, wird vom Sender ein Timeout verwendet, bis zu dem das ACK der Gegenseite eingetroffen sein muss. Ein zu niedriger Timeout bewirkt, dass Pakete, die eigentlich korrekt angekommen sind, wiederholt werden; ein zu hoher Timeout bewirkt, dass bei tatsächlichen Verlusten das zu wiederholende Paket unnötig spät gesendet wird. Aufgrund unterschiedlicher Laufzeiten der zugrundeliegenden IP-Pakete ist nur ein dynamisch an die Verbindung angepasster Timer sinnvoll. Die Details werden in RFC 6298[7] wie folgt festgelegt:

  • Der Timeout (RTO = Retransmission Timeout) berechnet sich aus zwei beim Sender mitgeführten Statusvariablen:
  • Initial wird geschätzt, dass RTO = 1s (um die Kompatibilität mit der älteren Version des Dokuments zu schaffen sind auch Werte > 1s möglich.)
  • Nach der Messung der RTT des ersten gesendeten Pakets wird gesetzt:
    • SRTT:= RTT
    • RTTVAR:= 0,5 * RTT
    • RTO:= RTT + 4 * RTTVAR (Sollte 4 * RTTVAR kleiner sein als die Messgenauigkeit des Timers, wird stattdessen diese addiert.)
  • Bei jeder weiteren Messung der RTT' werden die Werte aktualisiert (hierbei muss RTTVAR vor SRTT berechnet werden):
    • RTTVAR:= (1-β) * RTTVAR + β * |SRTT – RTT'| (Auch die Varianz wird mit einem Faktor β geglättet; da die Varianz eine durchschnittliche Abweichung angibt (welche immer positiv ist), wird hier der Betrag der Abweichung von geschätzter und tatsächlicher RTT' verwendet, nicht die einfache Differenz. Es wird empfohlen, β = 1/4 zu wählen.)
    • SRTT:= (1-α) * SRTT + α * RTT' (Es wird somit nicht einfach die neue RTT' gesetzt, sondern diese mit einem Faktor α geglättet. Es wird empfohlen, α = 1/8 zu wählen.)
    • RTO:= SRTT + 4 * RTTVAR (Sollte 4*RTTVAR kleiner sein als die Messgenauigkeit des Timers, wird stattdessen diese addiert. Für den RTO gilt – unabhängig von der Berechnung – ein Minimalwert von 1 s; es darf auch ein Maximalwert vergeben werden, sofern dieser mindestens 60 s beträgt.)

Durch die Wahl von 2er-Potenzen (4 bzw. 1/2, 1/4 etc.) als Faktoren, können die Berechnungen in der Implementierung durch einfache Shift-Operationen realisiert werden.

Zur Messung der RTT muss der Karn-Algorithmus von Phil Karn verwendet werden; d. h., es werden nur diejenigen Pakete zur Messung verwendet, deren Bestätigung eintrifft, ohne dass das Paket zwischendurch erneut gesendet wurde. Der Grund dafür ist, dass bei einer erneuten Übertragung nicht klar wäre, welches der wiederholt gesendeten Pakete tatsächlich bestätigt wurde, so dass eine Aussage über die RTT eigentlich nicht möglich ist.

Wurde ein Paket nicht innerhalb des Timeouts bestätigt, so wird der RTO verdoppelt (sofern er noch nicht die optionale obere Schranke erreicht hat). In diesem Fall dürfen (ebenfalls optional) die für SRTT und RTTVAR gefundenen Werte auf ihren Anfangswert zurückgesetzt werden, da sie möglicherweise die Neuberechnung der RTO stören könnten.

Zusammenhang von Flusssteuerung und Staukontrolle

In den folgenden zwei Abschnitten werden die TCP-Konzepte zur Flusssteuerung und Staukontrolle (oder Überlaststeuerung) erläutert. Dabei werden das Sliding Window und das Congestion Window eingeführt. Der Sender wählt als tatsächliche Sendefenstergröße das Minimum aus beiden Fenstern. Um eine zuverlässige Datenübertragung durch Sendewiederholungen zu gewährleisten, werden sogenannte ARQ-Protokolle (englisch Automatic Repeat reQuest, dt. Automatische Wiederholungsanfrage) eingesetzt.

Flusssteuerung

Abb. 8: Sliding Window

Da die Anwendung Daten aus dem Puffer liest, ändert sich der Füllstand des Puffers ständig. Deshalb ist es notwendig, den Datenfluss dem Füllstand entsprechend zu steuern. Dies geschieht mit dem Sliding Window und dessen Größe. Den Puffer des Senders erweitern wir, wie in Abb. 8 zu sehen, auf 10 Segmente. In der Abb. 8a werden gerade die Segmente 1–5 übertragen. Die Übertragung ist vergleichbar mit Abb. 7. Obwohl der Puffer des Empfängers in Abb. 7 am Ende voll ist, fordert er mit ACK=7301 die nächsten Daten ab dem Byte 7301 beim Sender an. Dies hat zur Folge, dass das nächste TCP-Segment vom Empfänger nicht mehr verarbeitet werden kann. Ausnahmen sind jedoch TCP-Segmente mit gesetztem URG-Flag. Mit dem Window-Feld kann er dem Sender mitteilen, dass er keine Daten mehr verschicken soll. Dies geschieht, indem er im Window-Feld den Wert Null einträgt (Zero Window). Der Wert Null entspricht dem freien Speicherplatz im Puffer. Die Anwendung des Empfängers liest nun die Segmente 1–5 aus dem Puffer, womit wieder ein Speicherplatz von 7300 Byte frei ist. Damit kann er die restlichen Segmente 6–10 mit einem TCP-Header, der die Werte SEQ=1, ACK=7301 und Window=7300 enthält, beim Sender anfordern. Der Sender weiß nun, dass er maximal fünf TCP-Segmente an den Empfänger schicken kann, und verschiebt das Window um fünf Segmente nach rechts (siehe Abb. 8b). Die Segmente 6–10 werden nun alle zusammen als Burst verschickt. Kommen alle TCP-Segmente beim Empfänger an, so quittiert er sie mit SEQ=1 und ACK=14601 und fordert die nächsten Daten an.

Silly Window Syndrome
Der Empfänger sendet ein Zero Window an den Sender, da sein Puffer voll ist. Die Anwendung beim Empfänger liest allerdings nur zwei Byte aus dem Puffer. Der Empfänger schickt einen TCP-Header mit Window=2 (Window Update) an den Sender und fordert gleichzeitig die zwei Byte an. Der Sender kommt der Aufforderung nach und schickt die zwei Byte in einem 42 Byte großen Paket (mit IP-Header und TCP-Header) an den Empfänger. Damit ist der Puffer des Empfängers wieder voll, und er schickt wieder ein Zero Window an den Sender. Die Anwendung liest jetzt zum Beispiel hundert Byte aus dem Puffer. Der Empfänger schickt wieder einen TCP-Header mit einem kleinen Window-Wert an den Sender. Dieses Spiel setzt sich immer wieder fort und verschwendet Bandbreite, da nur sehr kleine Pakete versandt werden. Clarks Lösung ist, dass der Empfänger ein Zero Window sendet und so lange mit dem Window Update warten soll, bis die Anwendung mindestens die maximale Segmentgröße (maximum segment size, in unseren bisherigen Beispielen 1460 Byte) aus dem Puffer gelesen hat oder der Puffer halbleer ist – je nachdem, was zuerst eintritt (Dave Clark, 1982). Auch der Sender kann zu kleine Pakete abschicken und dadurch Bandbreite verschwenden. Dieser Umstand wird mit dem Nagle-Algorithmus beseitigt. Deswegen ergänzt er sich mit Clarks Lösung.

Überlaststeuerung/Staukontrolle (Congestion Control)

Im Internet, in dem viele Netze mit unterschiedlichen Eigenschaften verbunden werden, ist Datenverlust einzelner Pakete durchaus normal. Wird eine Verbindung stark belastet, werden immer mehr Pakete verworfen, die entsprechend wiederholt werden müssen. Durch die Wiederholung steigt wiederum die Belastung, ohne geeignete Maßnahmen kommt es zu einem Datenstau.

Die Verlustrate wird von einem IP-Netzwerk ständig beobachtet. Abhängig von der Verlustrate wird die Senderate durch geeignete Algorithmen beeinflusst: Normalerweise wird eine TCP/IP-Verbindung langsam gestartet (Slow-Start) und die Senderate schrittweise erhöht, bis es zum Datenverlust kommt. Ein Datenverlust verringert die Senderate, ohne Verlust wird sie wiederum erhöht. Insgesamt nähert sich die Datenrate so zunächst dem jeweiligen zur Verfügung stehenden Maximum und bleibt dann ungefähr dort. Eine Überbelastung wird vermieden.

Algorithmus zur Überlaststeuerung

Gehen bei einer bestimmten Fenstergröße Pakete verloren, kann das festgestellt werden, wenn der Sender innerhalb einer bestimmten Zeit (Timeout) keine Bestätigung (ACK) erhält. Man muss davon ausgehen, dass das Paket aufgrund zu hoher Netzlast von einem Router im Netz verworfen wurde. Das heißt, der Puffer eines Routers ist vollgelaufen; es handelt sich hier sozusagen um einen Stau im Netz. Um den Stau aufzulösen, müssen alle beteiligten Sender ihre Netzlast reduzieren. Dazu werden im RFC 2581 vier Algorithmen definiert: slow start, congestion avoidance, fast retransmit und fast recovery, wobei slow start und congestion avoidance zusammen verwendet werden. Die zwei Algorithmen fast retransmit und fast recovery werden auch zusammen verwendet und sind eine Erweiterung der Algorithmen slow start und congestion avoidance.

Vorlage:Anker Slow Start und Congestion Avoidance

Grafische Darstellung des Slow-Start-Algorithmus

Zu Beginn einer Datenübertragung dient der Slow-Start-Algorithmus zur Bestimmung des congestion window (wörtlich: Überlastfenster), um einer möglichen Überlastsituation vorzubeugen. Man möchte Staus vermeiden, und da die momentane Auslastung des Netzes nicht bekannt ist, wird mit zunächst kleinen Datenmengen begonnen. Der Algorithmus startet mit einem kleinen Fenster von einer MSS (Maximum Segment Size), in dem Datenpakete vom Sender zum Empfänger übertragen werden.

Der Empfänger sendet nun eine Bestätigung (ACK) an den Sender zurück. Für jedes empfangene ACK wird die Größe des congestion window um eine MSS erhöht. Da für jedes versandte Paket bei erfolgreicher Übertragung ein ACK geschickt wird, führt dies innerhalb einer Roundtrip-Zeit zu einer Verdopplung des Congestion Windows. In dieser Phase gibt es also ein exponentielles Wachstum. Wenn das Fenster beispielsweise das Versenden von zwei Paketen gestattet, so erhält der Sender auch zwei ACKs und erhöht das Fenster daher um 2 auf 4. Dieses exponentielle Wachstum wird so lange fortgesetzt, bis der sogenannte Slow-Start Threshold erreicht wird (engl. Vorlage:Lang ‚Schwelle‘). Die Phase des exponentiellen Wachstums wird auch Slow Start Phase genannt.

Danach wird das Congestion Window nur noch um eine MSS erhöht, wenn alle Pakete aus dem Fenster erfolgreich übertragen wurden. Es wächst also pro Roundtrip-Zeit nur noch um eine MSS, also nur noch linear. Diese Phase wird als Congestion Avoidance Phase bezeichnet. Das Wachstum wird beendet, wenn das vom Empfänger festgelegte Empfangsfenster erreicht worden ist (siehe Fluss-Steuerung).

Kommt es zu einem Timeout, wird das Vorlage:Lang wieder auf 1 zurückgesetzt, und der Vorlage:Lang wird auf die Hälfte der Flight Size (Flight Size ist die Anzahl an Paketen, die verschickt, aber noch nicht quittiert wurden)[8] herabgesetzt. Die Phase des exponentiellen Wachstums wird also verkürzt, so dass das Fenster bei häufigen Paketverlusten nur langsam wächst.

Fast-Retransmit und Fast-Recovery

Vorlage:Lang und Vorlage:Lang („schnelles Erholen“) werden eingesetzt, um nach einem Paketverlust schneller auf die Stau-Situation zu reagieren. Dazu informiert ein Empfänger den Sender, wenn Pakete außer der Reihe ankommen und somit dazwischen ein Paketverlust vorliegt. Hierfür bestätigt der Empfänger das letzte korrekte Paket erneut für jedes weitere ankommende Paket außer der Reihe. Man spricht dabei von Dup-Acks (Vorlage:Lang), also mehrere aufeinanderfolgende Nachrichten, welche dasselbe Datensegment ACKen. Der Sender bemerkt die duplizierten Bestätigungen, und nach dem dritten Duplikat sendet er sofort, vor Ablauf des Timers, das verlorene Paket erneut. Weil nicht auf den Ablauf des Timers gewartet werden muss, heißt das Prinzip Vorlage:Lang. Die Dup-Acks sind auch Hinweise darauf, dass zwar ein Paketverlust stattfand, aber doch die folgenden Pakete angekommen sind. Deshalb wird das Sendefenster nach dem Fehler nur halbiert und nicht wie beim Timeout wieder mit Slow-Start begonnen. Zusätzlich kann das Sendefenster noch um die Anzahl der Dup-Acks erhöht werden, denn jedes steht für ein weiteres Paket, welches den Empfänger erreicht hat, wenn auch außer der Reihe. Da dadurch nach dem Fehler schneller wieder die volle Sendeleistung erreicht wird, nennt man das Prinzip Vorlage:Lang.

Selective ACKs (SACK)

Vorlage:Lang werden genutzt, um noch mehr Kontrollinformationen über den Datenfluss vom Empfänger an den Sender zurückzuschicken. Dabei wird nach einem Paketverlust vom Empfänger im TCP-Optionsfeld ein zusätzlicher Header eingefügt, aus welchem der Sender genau ersehen kann, welche Pakete bereits angekommen sind und welche fehlen (im Gegensatz zu den standardmäßigen kumulativen ACKs von TCP, s. o.). Als bestätigt gelten die Pakete auch weiterhin erst dann, wenn der Empfänger dem Sender ein ACK für die Pakete übermittelt hat.

TCP-Tahoe und TCP-Reno

Bei den nach Orten in Nevada benannten TCP-Congestion-Control-Varianten Tahoe und Reno handelt es sich um zwei verschiedene Verfahren, wie TCP auf ein Überlast-Ereignis in Form von Timeouts oder Dup-Acks reagiert.

Das inzwischen nicht mehr verwendete TCP Tahoe reduziert, sobald ein Timeout vorliegt, das Congestion Window für die nächste Übertragungseinheit auf 1. Anschließend startet wieder der TCP-Slow-Start-Prozess (mit verringertem Threshold, s. u.), bis ein neues Timeout- oder DUP-Acks-Ereignis stattfindet oder aber der Schwellwert (Threshold) zum Übergang in die Congestion-Avoidance-Phase erreicht wird. Dieser Schwellwert wurde nach dem Auftreten des Überlast-Ereignisses auf die Hälfte der Größe des derzeitigen Congestion Window gesetzt. Der Nachteil dieses Verfahrens ist zum einen, dass ein Paketverlust nur durch einen Timeout festgestellt wird, mitunter also recht lange dauert, und zum anderen die starke Reduktion des Congestion Windows auf 1.

Die Weiterentwicklung von Tahoe ist TCP-Reno. Hierbei wird zwischen auftretenden Timeout- und Dup-Acks-Ereignissen unterschieden: Während TCP-Reno beim Auftreten eines Timeout genauso verfährt wie TCP Tahoe, wendet es beim Auftreten von drei doppelten Acks eine andere Variante für die Festlegung des nachfolgenden Congestion Windows an. Die grundlegende Idee dabei ist, dass der Verlust eines Segments auf dem Weg zum Empfänger nicht nur durch einen Timeout erkannt werden kann, sondern auch dadurch, dass der Empfänger mehrfach dieselben ACKs für das unmittelbar vor dem verlorengegangenen Segment zurückschickt (und zwar jedes Mal, wenn er ein weiteres Segment nach der „Lücke“ empfängt). Daher wird das nachfolgende Congestion Window auf die Hälfte des Wertes des Congestion Windows zum Zeitpunkt des Überlast-Ereignisses gesetzt; anschließend wird wieder in die Congestion Avoidance Phase übergegangen. Dieses Verhalten wird, wie oben im Artikel erwähnt, als Fast-Recovery beschrieben.

Überlaststeuerung als Forschungsfeld

Vorlage:Veraltet Die genaue Gestaltung der TCP-Überlaststeuerung war und ist ein überaus aktives Forschungsfeld mit zahlreichen wissenschaftlichen Publikationen. Auch heute arbeiten weltweit viele Wissenschaftler an Verbesserungen der TCP-Überlaststeuerung oder versuchen, sie an bestimmte äußere Gegebenheiten anzupassen. In diesem Zusammenhang sind insbesondere die speziellen Bedingungen der diversen drahtlosen Übertragungstechniken zu erwähnen, welche oft zu hohen oder stark schwankenden Laufzeitverzögerungen oder zu hohen Paketverlusten führen. TCP geht standardmäßig bei Paketverlusten davon aus, dass der Übertragungsweg an irgendeiner Stelle ausgelastet ist (Datenstau). Dies ist bei drahtgebundenen Netzen auch meistens der Fall, da dort nur selten Pakete auf der Leitung verlorengehen, sondern nicht angekommene Pakete fast immer von einem überlasteten Router verworfen wurden. Die richtige Reaktion auf so einen „Datenstau“ ist daher die Reduktion der Senderate. Bei drahtlosen Netzen trifft diese Annahme jedoch nicht mehr zu. Aufgrund des wesentlich unzuverlässigeren Übertragungsmediums treten Paketverluste oft auf, ohne dass einer der Router überlastet ist. In diesem Szenario ist das Reduzieren der Senderate jedoch nicht sinnvoll. Im Gegenteil, eine Erhöhung der Senderate, etwa durch Mehrfachsenden von Paketen, könnte die Zuverlässigkeit der Verbindung erhöhen.

Häufig basieren diese Änderungen bzw. Erweiterungen der Überlastkontrolle auf komplexen mathematischen bzw. regelungstechnischen Fundamenten. Der Entwurf entsprechender Verbesserungen ist alles andere als einfach, da im Allgemeinen gefordert wird, dass TCP-Verbindungen mit älteren Überlastkontrollmechanismen durch die neuen Verfahren nicht wesentlich benachteiligt werden dürfen, wenn beispielsweise mehrere TCP-Verbindungen um Bandbreite auf einem gemeinsam genutzten Medium „kämpfen“. Aus all diesen Gründen ist die in der Realität verwendete TCP-Überlaststeuerung auch wesentlich komplizierter gestaltet, als es weiter oben im Artikel beschrieben wird.

Aufgrund der zahlreichen Forschungen zur TCP-Überlaststeuerung setzten sich im Laufe der Zeit verschiedene Überlaststeuerungsmechanismen als Quasi-Standards durch. Hier sind insbesondere TCP Reno, TCP Tahoe und TCP Vegas zu nennen.

Im Folgenden sollen exemplarisch einige neuere bzw. experimentellere Ansätze grob umrissen werden. Ein Ansatz ist beispielsweise RCF (Router Congestion Feedback). Hierbei werden durch die Router entlang dem Pfad umfangreichere Informationen an die TCP-Sender oder -Empfänger geschickt, damit diese ihre Ende-zu-Ende-Überlaststeuerung besser abstimmen können. Hierdurch sind erwiesenermaßen beträchtliche Durchsatzsteigerungen möglich. Beispiele dafür finden sich in der Literatur unter den Stichworten XCP (Vorlage:Lang), EWA (Vorlage:Lang), FEWA (Vorlage:Lang), FXCP (Vorlage:Lang) und ETCP (Vorlage:Lang) (Stand: Mitte 2004). Weiterhin ist die Vorlage:Lang (ECN) eine Implementierung einer RFC. Vereinfacht gesagt bilden diese Verfahren eine Überlaststeuerung nach Art von ATM nach.

Andere Ansätze verfolgen die logische Trennung der Regelschleife einer TCP-Verbindung in zwei oder mehr Regelschleifen an den entscheidenden Stellen im Netz (z. B. beim sogenannten Split-TCP). Weiterhin gibt es das Verfahren der logischen Bündelung mehrerer TCP-Verbindungen in einem TCP-Sender, damit diese Verbindungen ihre Informationen über den momentanen Zustand des Netzes austauschen und schneller reagieren können. Hier ist insbesondere das Verfahren EFCM (Vorlage:Lang) zu nennen. All diese Verfahren können unter dem Begriff Vorlage:Lang zusammengefasst werden.

TCP-Prüfsumme und TCP-Pseudo-Header

Der Pseudo-Header ist eine Zusammenstellung von Header-Teilen eines TCP-Segments und Teilen des Headers des einkapselnden IP-Pakets. Es ist ein Modell, an dem sich die Berechnung der TCP-Prüfsumme () anschaulich beschreiben lässt.

Falls IP mit TCP eingesetzt wird, ist es wünschenswert, den Header des IP-Pakets mit in die Sicherung von TCP aufzunehmen. Dadurch ist die Zuverlässigkeit seiner Übertragung garantiert. Darum bildet man den IP-Pseudo-Header. Er besteht aus IP-Absender und -Empfängeradresse, einem Null-Byte, einem Byte, das angibt, zu welchem Protokoll die Nutzdaten des IP-Pakets gehören und der Länge des TCP-Segments mit TCP-Header. Da es sich im Fall des Pseudo-Headers immer um IP-Pakete handelt, die TCP-Segmente transportieren, ist dieses Byte auf den Wert 6 gesetzt. Der Pseudo-Header wird für die Berechnung der Prüfsumme vor den TCP-Header gelegt. Anschließend berechnet man die Prüfsumme. Die Summe wird im Feld „checksum“ abgelegt und das Fragment versendet. Kein Pseudo-Header wird je versendet.

TCP-Pseudo-Header (IPv4)
Bit offset Bits 0–3 4–7 8–15 16–31
0 IP-Absenderadresse
32 IP-Empfängeradresse
64 00000000 6 (=TCP) TCP-Länge
96 Quellport Zielport
128 Sequenznummer
160 ACK-Nummer
192 Datenoffset Reserviert Flags Window
224 Prüfsumme Urgent pointer
256 Options (optional)
256/288+  
Daten
 

Die Berechnung der Prüfsumme für IPv4 ist in RFC 793 definiert:

Die Prüfsumme ist das 16-Bit-Einerkomplement der Einerkomplement-Summe aller 16-Bit-Wörter im Header und der Nutzdaten des unterliegenden Protokolls. Wenn ein Segment eine ungerade Anzahl Bytes enthält, wird ein Padding-Byte angehängt. Das Padding wird nicht übertragen. Während der Berechnung der Prüfsumme wird das Prüfsummenfeld selbst mit Nullen gefüllt.

Abweichend hiervon sieht bei IPv6 der Pseudo-Header gemäß RFC 2460 wie folgt aus:

Vorlage:"

TCP Pseudo-Header für IPv6
Bit offset 0–7 8–15 16–23 24–31
0 Quelladresse
32
64
96
128 Zieladresse
160
192
224
256 TCP-Länge
288 Nullwerte Nächster Header
320 Quellport Zielport
352 Sequenznummer
384 ACK-Nummer
416 Datenoffset Reserviert Flags Window
448 Prüfsumme Urgent pointer
480 Options (optional)
480/512+  
Daten
 

Der Empfänger erstellt ebenfalls den Pseudo-Header und führt anschließend dieselbe Berechnung aus, ohne das Checksum-Feld auf Null zu setzen. Dadurch sollte das Ergebnis FFFF (Hexadezimal) sein. Ist dies nicht der Fall, so wird das TCP-Segment ohne Nachricht verworfen. Dies hat zur Folge, dass der RTT-Timer beim Absender abläuft und das TCP-Segment noch einmal abgeschickt wird.

Der Grund für dieses komplizierte Verfahren liegt darin, dass sich Teile des IP-Headers während des Routings im IP-Netz verändern. Das TTL-Feld wird bei jedem IP-Hop um eins dekrementiert. Würde das TTL-Feld in die Prüfsummenberechnung einfließen, würde IP die Sicherung des Transports durch TCP zunichtemachen. Deshalb wird nur ein Teil des IP-Headers in die Prüfsummenberechnung einbezogen. Die Prüfsumme ist zum einen wegen ihrer Länge von nur 16 Bit und wegen der einfachen Berechnungsvorschrift anfällig für nicht erkennbare Fehler. Bessere Verfahren wie CRC-32 wurden zur Zeit der Definition als zu aufwendig angesehen.

Datenintegrität und Zuverlässigkeit

Im Gegensatz zum verbindungslosen UDP implementiert TCP einen bidirektionalen, byte-orientierten, zuverlässigen Datenstrom zwischen zwei Endpunkten. Das darunterliegende Protokoll (IP) ist paketorientiert, wobei Datenpakete verlorengehen können, in verkehrter Reihenfolge ankommen dürfen und sogar doppelt empfangen werden können. TCP wurde entwickelt, um mit der Unsicherheit der darunterliegenden Schichten umzugehen. Es prüft daher die Integrität der Daten mittels der Prüfsumme im Paketkopf und stellt die Reihenfolge durch Sequenznummern sicher. Der Sender wiederholt das Senden von Paketen, falls keine Bestätigung innerhalb einer bestimmten Zeitspanne (Timeout) eintrifft. Die Daten der Pakete werden beim Empfänger in einem Puffer in der richtigen Reihenfolge zu einem Datenstrom zusammengefügt und doppelte Pakete verworfen.

Der Datentransfer kann selbstverständlich jederzeit nach dem „Aufbau einer Verbindung“ gestört, verzögert oder ganz unterbrochen werden. Das Übertragungssystem läuft dann in einen Timeout. Der vorab getätigte „Verbindungsaufbau“ stellt also keinerlei Gewähr für eine nachfolgende, dauerhaft gesicherte Übertragung dar.

Bestätigungen

Die jeweilige Länge des Puffers, bis zu der keine Lücke im Datenstrom existiert, wird bestätigt (Vorlage:Lang). Dadurch ist das Ausnutzen der Netz-Bandbreite auch bei großen Strecken möglich. Bei einer Übersee- oder Satellitenverbindung dauert das Eintreffen des ersten ACK-Signals aus technischen Gründen bisweilen mehrere 100 Millisekunden, in dieser Zeit können unter Umständen mehrere hundert Pakete gesendet werden. Der Sender kann den Empfängerpuffer füllen, bevor die erste Bestätigung eintrifft. Alle Pakete im Puffer können gemeinsam bestätigt werden. Bestätigungen können zusätzlich zu den Daten in den TCP-Header des entgegengesetzten Datenstroms eingefügt werden (Vorlage:Lang), falls der Empfänger ebenfalls Daten für den Sender bereithält.

Siehe auch

Literatur

  • Douglas Comer: Internetworking with TCP/IP. Principles, Protocols, and Architectures. Prentice Hall, 2000, ISBN 0-13-018380-6.
  • Craig Hunt: TCP/IP Netzwerk-Administration. O’Reilly, Bejing 2003, ISBN 3-89721-179-3.
  • Richard Stevens: TCP/IP Illustrated. Volume 1. The Protocols. Addison-Wesley, Boston 1994, 2004. ISBN 0-201-63346-9.
  • Richard Stevens: TCP/IP Illustrated. Volume 2. The Implementation. Addison-Wesley, Boston 1994, ISBN 0-201-63354-X.
  • Andrew S. Tanenbaum: Computernetzwerke. 4. Auflage. Pearson Studium, München 2003, ISBN 978-3-8273-7046-4, S. 580 ff.
  • James F. Kurose, Keith W. Ross: Computernetze. Ein Top-Down-Ansatz mit Schwerpunkt Internet. Bafög-Ausgabe. Pearson Studium, München 2004, ISBN 3-8273-7150-3.
  • Michael Tischer, Bruno Jennrich: Internet Intern. Technik & Programmierung. Data-Becker, Düsseldorf 1997, ISBN 3-8158-1160-0.

Weblinks

RFCs

  • RFC 793 (Transmission Control Protocol)
  • RFC 1071 (Berechnen der Prüfsumme für IP, UDP und TCP)
  • RFC 1122 (Fehlerbehebungen bei TCP)
  • RFC 1323 (Erweiterungen bei TCP)
  • RFC 2018 (TCP SACK – Selective Acknowledgment Options)
  • RFC 3168 (Explicit Congestion Notification)
  • RFC 5482 (TCP User Timeout Option)
  • RFC 5681 (TCP Congestion Control – TCP-Überlastkontrolle)
  • RFC 7414 (Übersicht zu TCP RFCs)

Sonstige

Einzelnachweise

  1. Nicht zu verwechseln mit paketvermittelnd. Die Aufgabe von TCP ist es nicht, Pakete zu übertragen, sondern die Bytes eines Datenstroms. Die Paketvermittlung wird durch das Internetprotokoll (IP) bereitgestellt. Daher ist IP paketvermittelnd, aber TCP paketvermittelt.
  2. RFC 793. Internet Engineering Task Force (IETF), 1981. “A passive OPEN request means that the process wants to accept incoming connection requests rather than attempting to initiate a connection.”
  3. RFC 793. Internet Engineering Task Force (IETF), 1981. “Briefly the meanings of the states are: LISTEN – represents waiting for a connection request from any remote TCP and port.”
  4. W. Richard Stevens: TCP/IP Illustrated, Vol. 1: The Protocols. Addison-Wesley, Kapitel 18.
  5. Steven M. Bellovin: RFC 1948 – Defending Against Sequence Number Attacks. Internet Engineering Task Force (IETF), 1996
  6. RFC 6298 - Computing TCP's Retransmission Timer