# TCP ## TCP vs. UDP | **TCP** | **UDP** | |----------------------------------------------------------------------------------------|-----------------------------------| | Garantierte Übertragung | keine Garantie | | Verbindungsorientiert | keine Verbindung | | Langsam | Schnell | | Sicher (SSL/TLS) | nicht sicher | | Paket-Sortier-Mechanismus | keiner | | ACKs | keine ACKs | | Erweitertes Error-Checking | nur Checksumme | | [Flow Control](#tcp-flusskontrolle) | keine | | [SlowStart & CongestionAvoidance](#tcp-berlastungskontrolle) | keine | | 20-Byte Header | 8-Byte Header | | [3-Wege-Handshake](#tcp-verbindungsaufbau)
SYN SYN-ACK ACK | keiner | | Genutzt von kritischen Anwendungen | genutzt von Real-Time Anwendungen | | HTTP, HTTPS, FTP, DNS, SMTP, Telnet | DHCP, DNS, VoIP, RIP, TFTP | ## TCP > Zuverlässiger Byte-Strom mit integrierter Flusskontrolle ### Ausgangslage für eine (virtuelle) TCP-Verbindung ![image_866.png](image_866.png) - MSS (Maximum Segment Size) - maximale Größe eines TCP-Segments (NUR Daten, ohne Header) - wird bei Verbindungsaufbau ausgehandelt - abhängig von der MTU (Maximum Transmission Unit) des darunterliegenden Netzwerks - Retransmission Timer (Timeout = RTO) - Nach Ablauf des Timers werden unbestätigte Datenpakete erneut gesendet ## TCP Sequenznummern - Sequenznummer eines TCP-Segments - Bytestromnummer des ersten Bytes im Segment - wird bei Verbindungsaufbau ausgehandelt ## TCP Bestätigungsnummern - Bestätigungsnummer eines TCP-Segments - Bytestromnummer des nächsten erwarteten Bytes - Als Quittungsnummer wird gesetzt: - ACK-Nummer (von Host B) = fehlerfrei empfangene Squenznummer + Größe der Nutzdaten in Byte - i.d.R poitiv - stellen Summenquittungen dar - d.h. alle Bytes bis zur ACK-Nummer wurden fehlerfrei empfangen - werden zusammen mit den restlichen Daten die von B nach A gesendet werden, in einem TCP-Segment übertragen - "Huckepack" ### TCP Telnet Fallstudie ![image_867.png](image_867.png) #### Neuübertragung aufgrund einer verlorenen ACK ![image_868.png](image_868.png) #### keine Neuübertragung, weil Bestätigung vor Timeout ankommt ![image_869.png](image_869.png) #### Keine Neuübertragung, weil kumulative Bestätigung ankommt (Summenquittung) ![image_870.png](image_870.png) ## TCP Verbindungsaufbau > TCP-Verbindung ist Full-Duplex > > Beide Verbindungen (Hin und Rück) müssen separat aufgebaut werden > > SYN-Flag = 1 dient zum Aufbau (Synchronisation) > > ACK-Flag = 1 dient zur Bestätigung (Quittung) > > Sequenz- und Quittungsnummern beziehen sich auf Bytes - TCP-Verbindung wird mit einem 3-Wege-Handshake aufgebaut - **Verbindungsanfrage (SYN) von A an B** - SYN = 1 - SEQ = x (Startsequenznummer) - **Verbindungsbestätigung (SYN, ACK) von B an A** - SYN = 1 - ACK = x + 1 (Bestätigungsnummer) - SEQ = y (Startsequenznummer von B) - **Bestätigung (ACK) von A an B** - SYN = 0 - ACK = y + 1 (Bestätigungsnummer) - SEQ = x + 1 (Fortsetzung der Sequenznummer von A) - ![image_871.png](image_871.png) ### Verbindungsaufbau Übung ![image_872.png](image_872.png) ## TCP Verbindungsabbau > TCP-Verbindung ist Full-Duplex → Jede Richtung muss separat abgebaut werden > > Falls nur eine Verbindung abgebaut wird (und die andere noch aktiv ist), dann wird die Verbindung in den Zustand "Half-Close" versetzt. > bspw. Wenn der Client nur noch empfangen möchte, aber nicht mehr senden. - Schematisch - Schließung TCP-Verbindung mit anschließender Wartezeit von 30 Sekunden - ![image_873.png](image_873.png) ### Verbindungsabbau Übung ![image_874.png](image_874.png) ## TCP Verbindungsmanagement ![image_875.png](image_875.png) - TCP-Verbindungen werden in einem Verbindungsmanagement verwaltet - Zustände: - CLOSED: Verbindung ist geschlossen - LISTEN: Verbindung wartet auf Verbindungsanfrage - SYN-SENT: Verbindungsanfrage wurde gesendet, aber noch keine Antwort erhalten - SYN-RECEIVED: Verbindungsanfrage wurde empfangen, aber noch keine Bestätigung gesendet - **ESTABLISHED**: Verbindung ist aufgebaut und kann Daten übertragen - FIN-WAIT-1: Die Anwendung möchte Übertragung beenden - FIN-WAIT-2: Andere Seite ist einverstanden die Verbindung zu beenden - TIME-WAIT: Verbindung ist geschlossen, aber wartet auf mögliche ausstehende Pakete - CLOSING: Beide Seiten haben gleichzeitig versucht, die Verbindung zu schließen - CLOSE-WAIT: Gegenseite hat Verbindungsfreigabe eingeleitet - LAST-ACK: Warten, bis keine TCP-Segmente mehr kommen ### TCP Client Lifecycle ![image_876.png](image_876.png) ### TCP Server Lifecycle ![image_877.png](image_877.png) ## TCP Zuverlässigkeit sicherstellen - Quittungen - positive ACKs - kumulative Summenquittungen - Zeitüberwachung - Retransmission Timer - Timeout (RTO) - Sequenznummern ## TCP Flusskontrolle ### Senden - TCP-Sender sendet Daten, solange der Sendepuffer nicht voll ist - enthält die gesendeten, aber noch nicht bestätigten Daten - ![image_878.png](image_878.png) - Sendefenster wird dazu benutzt, um die Anzahl von Bytes anzugeben, die der Empfänger bereit ist anzunehmen - bildet absolute obere Grenze, die vom Sender nicht überschritten werden darf ### Empfangen - TCP-Empfänger sendet ACKs, solange der Empfangspuffer nicht voll ist - ![image_879.png](image_879.png) - Empfangsfenster ist dynamisch - wird vom Empfänger in jedem ACK aktualisiert - gibt an, wie viele Bytes der Empfänger noch aufnehmen kann ### Flusskontrolle Beispiel ![image_880.png](image_880.png) ### Datenfluss: Fehlerfreie Übertragung ![image_883.png](image_883.png) ### Datenfluss: Fehlerhafte Übertragung ![image_884.png](image_884.png) ## TCP Pipelining, Sliding Window ### Pipelining - TCP-Sender kann mehrere Segmente senden, ohne auf die Bestätigung des Empfängers zu warten - Erlaubt eine höhere Auslastung der Verbindung - Sender sendet mehrere Segmente in einem Rutsch - z.B. 3 Segmente mit jeweils 1000 Bytes - **Konsequenzen**: - Sender und Empfänger benötigen einen Puffer für mehrere Segmente - Minimum: Sender muss alle gesendeten, aber noch nicht bestätigten Segmente puffern - Bereich der Sequenz- und Bestätigungsnummern wird größer ### Sliding Window ![image_881.png](image_881.png) - Sliding Window ist eine Erweiterung des Pipelining - Gewährleistet: - Zuverlässige Übertragung in einem Bytestrom - Übertragung der Daten in richtiger Reihenfolge - Flusskontrolle zwischen Sender und Empfänger - Integrierte Flusskontrolle - keine feste Sliding Window Größe - wird Sender vom Empfänger mitgeteilt ("Advertised Window") - auf Grundlage des Speicherplatzes, der der Verbindung zugewiesen ist #### Sliding Window Beispiel ![image_882.png](image_882.png) - **Senderseite** (a) - LastByteAcked ≤ LastByteSent - LastByteSent ≤ LastByteWritten - Bytes zwischen LastByteAcked und LastByteSent puffern - **Empfängerseite** (b) - LastByteRead ≤ LastByteExpected - LastByteExpected ≤ LastByteReceived + 1 - Bytes zwischen LastByteRead und LastByteReceived puffern ## TCP Fehlerbehandlung - Erfolgt durch Go-Back-N - Sender sendet Datenpakete, bis er eine Bestätigung erhält - Bei Verlust eines Pakets wird es erneut gesendet - Arbeitet mit positiven ACKs - Empfänger sendet ACKs für empfangene Pakete (ggf. kumulative ACKs) - Ab dem ersten, nicht quittierten Paket, werden alle folgenden Pakete erneut gesendet ## TCP Überlastungskontrolle - Funktion der Netzwerkschicht zur Regelung des Datenflusses - Begrenzung der Übertragungsrate - Lösungsansatz: - **TCP-Slow-Start** - Startet mit einer niedrigen Übertragungsrate - Erhöht die Rate (cwnd) exponentiell, bis ein Paket verloren geht - maximal Windowsize - **TCP-Überlastungskontrolle** - Reduziert die Übertragungsrate, wenn Pakete verloren gehen ## Silly Window > Sender/Empfänger senden/empfangen nur sehr kleine Datenmengen → Fragmentierung in viele Segmente, welche aber immer > noch den TCP/IP-Header haben und damit Netzwerknutzung ineffizient wird ### Empfängerseitig (Window Shrinking) - Empfänger bestätigt sehr kleines Empfangsfenster - bspw. 1 Byte - weil er nur wenig internen Speicher hat - Sender darf nur 1 Byte schicken → viele Pakete #### Lösung (Clark) - Empfänger schickt keine ACKs (inkl. Fensteraktualisierungen), außer: - Er kann ein volles Segment (MSS) empfangen - order Empfangspuffer ist mind. halb leer - → Sender schickt nicht andauernd ### Senderseitig - Sender generiert kleien Datenmengen und sendet immer sofort - bspw. durch interaktiven Dienst, bei jedem Tastendruck wird gesendet #### Lösung (Nagle) - Sender darf nur Segment schicken, wenn - alle bisherigen Daten bestätigt (ACK) - oder ein vollständiges MSS-Paket vorliegt - → kleine Datenmengen werden gepuffert, weniger Pakete ## Abschätzung von TCP Timeout (Jacobson/Karels) > Timeout = EstimatedRTT + (4 * Abweichung) ## TCP Fast Open - Verwendet einen TFO-Cookie - Server gibt Client beim ersten Verbindungsaufbau - spätere Verbindungen können so authentifiziert werden - | Erste Verbindungen | Zukünftige Verbindungen | |---------------------------------|---------------------------------| | ![image_940.png](image_940.png) | ![image_941.png](image_941.png) | ## Relevante Fallstudien ### Download einer Webseite aus dem Internet - Step (1): Enter website in browser - Step (2): DNS Client creates a message - Step (3): Transport Layer creates an UDP datagram - Step (4): Network Layer creates an IP packet - Step (5): ARP determine Destination MAC address - Step (6): Link Layer creates and transmit a frame - Step (7): NAT entry and forward frame to ISP Router - Step (8): ISP Router forwards frame to DNS Server - Step (9): DNS Server receives frame - Step (10): DNS translate and generate reply - Step (11): ISP Router forwards frame to local router - Step (12): NAT translation in local router - Step (13): Local Router forwards frame to PC - Step (14): DNS Client delivers IP address to HTTP - Step (15): HTTP Client creates Request message - _(Step (16): PC receives website from HTTP Server)_ ### Anwendungsprotokolle | Anwendung | Beschreibung | Bild | |---------------------------------------------|-----------------------------------------------------------|---------------------------------| | DHCP | gibt IP-Adressen | ![image_942.png](image_942.png) | | DNS | übersetzt Webseitenname in IP-Adresse | ![image_943.png](image_943.png) | | HTTP
Hyper Text Transfer Protocol | Webseiten transferieren | ![image_944.png](image_944.png) | | NBNS
NetBIOS Name Service | übersetzt lokale Hostnamen in IP-Adressen | ![image_945.png](image_945.png) | | SMTP
Simple Mail Transfer Protocol | Emails senden | ![image_946.png](image_946.png) | | SNMP
Simple Network Management Protocol | Netzwerkgeräte Managen | ![image_947.png](image_947.png) | | SNTP
Simple Network Time Protocol | Gibt Zeit | | | Telnet | Bidirektionale Text-Kommunikation über Terminal-Anwendung | ![image_948.png](image_948.png) | | TFTP
Trivial File Transfer Protocol | Transferiert kleine Datenmengen | ![image_949.png](image_949.png) | ## Port Handling - Ports werden genutzt um laufende Prozesse in den Anwendungen zu identifizieren - Clientseitige Ports werden dynamisch vom Transport Layer erzeugt - zwischen 1024 und 65535 ### Well Known Ports | Über | Anwendung | Port | |------|-----------|------| | UDP | DHCP | 67 | | UDP | NBNS | 137 | | UDP | DNS | 53 | | UDP | SNTP | 123 | | UDP | SNMP | 161 | | TCP | Telnet | 23 | | TCP | SMTP | 25 | | TCP | HTTP | 80 | | TCP | FTP | 21 | ## Socket Handling - Ermöglichen Anwendungen sich mit TCP/IP-Netzwerken zu verbinden - Virtuelle TCP/UDP Kommunikationskanäle - ![image_950.png](image_950.png) - Sockets als TC/RX Buffer - ![image_951.png](image_951.png) ## Ports und Sockets in der Praxis ![image_952.png](image_952.png) ![image_953.png](image_953.png) ## Aufbau einer TCP Verbindung mit Sockets ### 1. Server erstellt Socket ![image_954.png](image_954.png) - stellt sich danach in den "listening" Modus - wartet auf Client-Request ### 2. Client erstellt Socket und verbindet sich ![image_955.png](image_955.png) ### 3. Transport Layer überträgt Nachricht zu Server ![image_956.png](image_956.png) ### 4. Server erstellt Socket und Prozess ![image_957.png](image_957.png) ### 5. Transport Layer übermittelt Nachrichten ### 6. Sockets schließen (außer den aus 1) ![image_958.png](image_958.png) ## TCP Tuning für HTTP/1.1 und HTTP/2 - nicht standardisiert, nur Best-Practise - Ziel - Transportverhalten von TCP anpassen, damit HTTP effizienter läuft - besonders bei kurzen, parallelen, latenzsensiblen Verbindungen - Vermeidung von Verzögerungen bei kleinen Paketen - Verbesserung Durchsatz bei parallelen Streams > Große Puffer, schnelle ACKs und kleine Latenzen lassen HTTP über TCP glänzen > > Nagle aus, ACKs schnell, Puffer groß - so wird TCP zum HTTP-Turbo. - Ablauf: - TCP-Sendepuffer - größer dimensionieren - am besten dynamisch (je nach RTT * Bandbreite) - TCP-Empfangspuffer - groß genug um alle Daten ohne Drop zu puffern - [Nagle-Algorithmus](#l-sung-nagle) deaktivieren - kleine, verzögerte Pakete leiden - → sofortiges Senden kleiner Pakete - Delayed ACKs abschalten/reduzieren ## TCP Flusskontrolle und MSS ## TCP Sliding Window - rwnd, cwnd, swnd = min(cwnd, rwnd) ## Slow Start (sstresh) und Congestion Avoidance ## TCP Timeout und RTO-Berechnung ## TCP Fast Retransmit und Fast Recovery ## TCP Tahoe und TCP Reno