Explicit Congestion Notification (ECN)

Wenn ein Server über TCP seine Daten von einem anderen Server sehr langsam bekommt, dann kann eine alte Netzwerkkomponente schuld dran sein. Mit der Funktion "Explicit Congestion Notification (ECN)" wurde im Jahr 2001 eine Erweiterung des IP/TCP-Stacks geschaffen, über den Router auf dem Transportweg eine drohende Überlastung mitteilen können.

ECN Funktionsweise

Zwei Endgeräte, die Daten über eine gegebene Netzwerkverbindung übertragen, müssen dynamisch auf wechselnde Bandbreiten reagieren. Dazu messen die Endpunkte kontinuierlich die Roundtrip-Zeit, Paketverlust und Jitter um schließen so auf die Verbindung. Wenn Teilstrecken einer Verbindungen voller werden, verzögern die Router aufgrund der Warteschlangen zuerst die Übertragung, was die Endpunkte über die RTT/Jitter-Messung erkennen können. Bei extremer Überlastung werfen Router Pakete weg, was dann als "Packet Loss" erkannt wird. Clients drosseln dann die Sendegeschwindigkeit. Das ist nicht schlecht sondern notwendig, denn ihr PC als auch der Server auf der anderen Seite haben vielleicht Gigabit-Netzwerkkarten aber oft ist schon die erste DSL-Leitung deutlich schwächer, so dass hier eine Flusskontrolle passieren muss.

Allerdings ist so eine Reaktion oft schon zu spät, wenn mit einer großen TCP Window Scaling der Sender schon viele Pakete auf die Reise gesendet hat. Hier steigt dann ECN ein, indem Router auf dem Weg schon den Endstellen eine drohende Überlastung signalisieren, ehe Sie passiert. Es entsprich der Verkehrslenkung auf Schnellstraßen, bei der ein Zuflusskontrolle an der Einfahrt die Menge kontrolliert, ehe es zum Stau kommt und alle ausgebremst werden. Die Kontrolle kann auch von den Endpunkten genutzt werden, um den Sender schon vorher zu bremsen, damit die Daten kontinuierlich fließen.

Das gleiche Bit kann aber auch ein Router setzen und so den Teilnehmern mitteilen, dass sie etwas "langsamer" senden sollen. Das Ziel ist die Überlastung von Teilstrecken mit dem damit verbundenen Paketverlust mit den dann erforderlichen Retransmits von Vorneherein zu verhindern.

ECN Handshake

Voraussetzung ist natürlich, dass die Endpunkte dieses Bit korrekt interpretieren. Die Funktion wurde erst mit der RFC3168 im Jahre 2001 festgelegt. Die Bits finden Sie mit Wireshark recht einfach sowohl in der Übersicht als auch in den Details beim TCP SYN ACK RES

Genau genommen sind es sogar die Bits 6 und 7 , die hier zu beachten sind und wie folgt definiert sind.

Bit 6 Bit 7 Bedeutung

0

0

Not-ECT: Der Sender weiß nichts mit ECN anzufangen, d.h. er sendet keine ECN Meldung und versteht sie auch nicht
bei einer aktiven Verbindung steht 00 für "Keine Congestion"

0

1

ECT(1): ECN Support und aktiv - Der Sender versteht ECN und setzt es auch ein.

1

0

ECT(0): ECN Support vorhanden aber nicht aktiv, d.. der Sender versteht ECN aber nutzt es nicht.

1

1

CE: Überlastung vorhanden. Ein beliebiges System setzt dieses Bit und signalisiert den Endpunkten, die ECM unterstützen, dass Sie ihre Senderrate drosseln sollen.

Auch wenn ECN schon seit 2001 spezifiziert ist, wird es wohl noch immer nicht auf allen Systemen korrekt unterstützt. Nicht umsonst steht z.B. auf Wikipedia dazu.

Wer ECN einsetzt, sollte sich bewusst sein, dass manche Administratoren die geänderte Semantik des TOS-Bytes durch den RFC 3168 im September 2001 noch nicht realisiert haben. Auch gehen Router und Firewalls selbst namhafter Unternehmen teilweise unvorhersehbar mit den ECN-Bits um. Es besteht daher die Gefahr, dass eine Verbindung mit eingeschaltetem ECN nicht zustande kommt.
https://de.wikipedia.org/wiki/Explicit_Congestion_Notification

Aufgefallen ist da bei einem Kunden, bei dem eine Firewall zwischen zwei Servern ECN aktiviert hat. Aufgefallen ist das bei einem End2End-HTTP-Test, bei dem die Latenzzeit immer konstant über 500ms gewesen ist.

Clients waren aber nicht betroffen sondern nur Windows Server

ECN und Clients

Damit stellt sich natürlich die Frage, welcher Client welche Standardeinstellung hat. Das können wir per Wireshark oder über die Konfigurationseinstellungen ermitteln. Bei Windows gibt es eine entsprechenden Kommandozeilentools, um die Einstellung in Erfahrung zu bringen

C:\> netsh interface tcp show global
Querying active state...

TCP Global Parameters
----------------------------------------------
Receive-Side Scaling State          : enabled
Chimney Offload State               : disabled
NetDMA State                        : disabled
Direct Cache Access (DCA)           : disabled
Receive Window Auto-Tuning Level    : normal
Add-On Congestion Control Provider  : default
ECN Capability                      : enabled
RFC 1323 Timestamps                 : disabled
Initial RTO                         : 3000
Receive Segment Coalescing State    : enabled
Non Sack Rtt Resiliency             : disabled
Max SYN Retransmissions             : 2
TCP Fast Open                       : disabled

Der Wert hinter "ECN Capability" liefert hier ein "Disabled". Das geht auch per PowerShell mit:

PS C:\Users\fcarius> Get-NetTCPSetting | ft Settingname,ecn*

Settingname      EcnCapability
-----------      -------------
Automatic
InternetCustom   Disabled
DatacenterCustom Disabled
Compat           Disabled
Datacenter       Disabled
Internet         Disabled

Die aktuell aktive Konfiguration bekommen Sie aus dem Feld "SettingName" von

PS C:\Users\fcarius> Get-NetTransportFilter

SettingName       : Internet
Protocol          : TCP
LocalPortStart    : 0
LocalPortEnd      : 65535
RemotePortStart   : 0
RemotePortEnd     : 65535
DestinationPrefix : *

Wenn Sie mit Wireshark nun die TCP-Handshake-Meldungen anschauen, dann ist immer das erste SYN-Paket eine Quelle für die Einstellung des Clients. Wenn er ECN liefert, dann bietet er es an und dann kann auch die Antwort der Gegenstelle ausgewertet werden. Wenn Sie natürlich auf einem Client testen, der selbst kein ECN kann, dann sollten Sie auch keine Antwort mit aktiviertem ECN erwarten. Daher habe ich ECN auf meiner Windows Workstation aktiviert:

C:\> netsh interface tcp set global ecncapability=enabled
OK

Danach habe ich in Wireshark gesehen, dass mein Client auch ECN anbietet.

Die Antwort der Gegenseite liefert aber kein ECN. Für ein Endsystem würde ich dann annehmen, dass ECN nicht verfügbar ist. Sobald aber ein Router dazwischen ist, könnte er diesen Handshake "verändern" oder selbst die Bits setzen. Hier bleibt dann nur die Kontrolle auf beiden Seiten beim TCP SYN ACK RES-Handshake. Hier meine Test-Ergebnisse.

Betriebssystem ECN Handshake mit Gegenstellen

Windows Client 1909

ECN nicht

Windows Server 2008/2008R2

ECN nicht aktiv

Windows Server 2012R2, 2016

ECN aktiv

Sophos UTM 9

ECN nicht aktiv, Kann aber unter QoS werden


Quelle: https://www.sophos.com/de-de/medialibrary/PDFs/documentation/utm9201_manual_eng.pdf

HP LaserJet 300 colorMFP M375nw

ECN nicht aktiv

QNAP

ECN aktiv

Synology DS216j

ECN nicht aktiv

HTTPS outlook.office365com:443

ECN aktiv

SMTP outlook.office365com: 25

ECN nicht aktiv

POP3 outlook.office365com: 110

ECN nicht aktiv

IMP4 outlook.office365com: 143

ECN nicht aktiv

Linux

ECN nicht aktiv. Laut Wikipedia sollte seit Linux 4.1 aber ECN angeboten werden. Mein Linux Mint (Stand Dez 2019) hat aber kein ECN bei ausgehenden Verindungen genutzt. Andere Distributionen können sich aber anders verhalten.

Fritz!Box

ECN nicht aktiv

IOS 9
IOS 10
IOS 11

ECN aktiv für 10% der Verbindungen
 ECN aktiv für 50% der Verbindungen
ECN aktiv

Interessant ist die Abweichung bei Office 365 nach den unterschiedlichen Diensten. Da die ECN-Konfiguration normalerweise aus dem IP-Stack global festgelegt wird und ich nur beim Zugriff per HTTPS die ECN-Option angeboten bekomme aber bei IMAP, POP und SMTP nicht, vermute ich einen Loadbalancer vor den Servern, der je nach Dienst andere Server oder Einstellungen nutzt.

Danach habe ich meinen Windows Client natürlich wieder auf die Standard-Werte gestellt:

C:\> netsh interface tcp set global ecncapability=disabled
OK

Auf Windows Server ist der Default aber "Enabled".

ECN und Netzwerkkarten

Die Zentral-CPU eines Servers ist zu kostbar, um sich mit IP-Paketen und dem TCP-Stack zu beschäftigen. Mit den ersten Gigabit-Netzwerkkarten haben die Prozessoren auf der Netzwerkkarte diverse Funktionen mehr und mehr übernommen um den Host zu entlasten. Dazu gehören Checksummen aber auch die erneute Übertragung von Paketen. Damit ist auch klar, dass die ECN-Funktion ebenfalls schon auf der Netzwerkkarte bereitgestellt werden muss, da sie da direkt in die Flusssteuerung eingreift.

Hier eine Ausgabe meines deutschen Windows 10 Build 1909 PCs. Anscheinend gibt es hier keine ECN-Einstellung, oder sie ist unter einem anderen Namen versteckt:

PS C:\> Get-NetAdapterAdvancedProperty -Name ethernet | ft -AutoSize                                                    
Name     DisplayName                              DisplayValue                      RegistryKeyword          RegistryValue
----     -----------                              ------------                      ---------------          ----------
Ethernet Flusssteuerung                           Rx und Tx aktiviert               *FlowControl             {3}
Ethernet Interrupt-Drosselung                     Aktiviert                         *InterruptModeration     {1}
Ethernet IPv4-Prüfsummen abladen                  Rx und Tx aktiviert               *IPChecksumOffloadIPv4   {3}
Ethernet Jumbo Packet                             Deaktiviert                       *JumboPacket             {1514}
Ethernet Large-Send-Offload V2 (IPv4)             Aktiviert                         *LsoV2IPv4               {1}
Ethernet Large-Send-Offload V2 (IPv6)             Aktiviert                         *LsoV2IPv6               {1}
Ethernet Max. Anzahl RSS-Warteschlangen           2 Warteschlangen                  *NumRssQueues            {2}
Ethernet Protokoll-ARP-Abladung                   Aktiviert                         *PMARPOffload            {1}
Ethernet Protokoll-NS-Abladung                    Aktiviert                         *PMNSOffload             {1}
Ethernet Paketpriorität und VLAN                  Paketpriorität und VLAN aktiviert *PriorityVLANTag         {3}
Ethernet PTP Hardware Timestamp                   Deaktiviert                       *PtpHardwareTimestamp    {0}
Ethernet Empfangspuffer                           256                               *ReceiveBuffers          {256}
Ethernet RSS (Empfangsseitige Skalierung)         Aktiviert                         *RSS                     {1}
Ethernet RSS-Load-Balancing-Profil                Nächster Prozessor                *RSSProfile              {1}
Ethernet Software Timestamp                       Deaktiviert                       *SoftwareTimestamp       {0}
Ethernet Geschwindigkeit und Duplex               Automatische Aushandlung          *SpeedDuplex             {0}
Ethernet TCP-Prüfsummen abladen (IPv4)            Rx und Tx aktiviert               *TCPChecksumOffloadIPv4  {3}
Ethernet TCP-Prüfsummen abladen (IPv6)            Rx und Tx aktiviert               *TCPChecksumOffloadIPv6  {3}
Ethernet Übertragungspuffer                       512                               *TransmitBuffers         {512}
Ethernet UDP-Prüfsummen abladen (IPv4)            Rx und Tx aktiviert               *UDPChecksumOffloadIPv4  {3}
Ethernet UDP-Prüfsummen abladen (IPv6)            Rx und Tx aktiviert               *UDPChecksumOffloadIPv6  {3}
Ethernet Akt. über Magic Packet                   Aktiviert                         *WakeOnMagicPacket       {1}
Ethernet Akt. bei Musterübereinstimmung           Aktiviert                         *WakeOnPattern           {1}
Ethernet Adaptives Interframe-Spacing             Deaktiviert                       AdaptiveIFS              {0}
Ethernet Geschwindigkeits-Akkusparoption          Deaktiviert                       AutoPowerSaveModeEnabled {0}
Ethernet Energieeffizientes Ethernet              Ein                               EEELinkAdvertisement     {1}
Ethernet PME aktivieren                           Aktiviert                         EnablePME                {1}
Ethernet Interrupt-Drosselungsrate                Adaptiv                           ITR                      {65535}
Ethernet Kompatibilitätsmodus für ältere Switches Deaktiviert                       LinkNegotiationProcess   {1}
Ethernet Verbindungsereignis protokollieren       Aktiviert                         LogLinkStateEvent        {51}
Ethernet Gigabit Master/Slave-Modus               Automatische Erkennung            MasterSlave              {0}
Ethernet Lokal verwaltete Adresse                 --                                NetworkAddress           {--}
Ethernet Geschw. beim Abschalten reduzieren       Aktiviert                         ReduceSpeedOnPowerDown   {1}
Ethernet Systemleerlauf-Energiesparoption         Deaktiviert                       SipsEnabled              {0}
Ethernet ULP-Modus                                Aktiviert                         ULPMode                  {1}
Ethernet Auf Verbindung warten                    Automatische Erkennung            WaitAutoNegComplete      {2}
Ethernet Akt. bei Verbindung                      Deaktiviert                       WakeOnLink               {0}

Die Einstellungen betreffen aber nicht nur physikalische Netzwerkkarten. Auch virtuelle Adapter unter VMWare oder HyperV sind hier zu berücksichtigen.

supplemental custom congestionprovider

In dem Zusammenhang habe ich auch noch einen weiteren Parameter gefunden, den man setzen kann

REM Default
netsh int tcp set supplemental custom congestionprovider=none


REM Alternative Einstellung
netsh int tcp set supplemental custom congestionprovider=ctcp

Allerdings habe ich noch keine Details oder Auswirkungen in meinen Umgebungen feststellen können. Zu CTCP aber ich aber nur Hinweise zu einem besonderen Protokoll für IRC  (Internet Relay Chat) gefunden, was hier sicher nicht zielführend ist. Daher lasse ich diesen Wert unverändert auf "none"

Reaktion auf ECN

Ich haben aktuell noch nicht weiter analysiert, wie sich ein Windows Client oder Server denn verhält, wenn er ein Paket mit gesetztem ECN-Bit bekommt.

Eigentlich müsste der Endpunkt dann von einer Überlastung ausgehen und seine Senderate drosseln. Das es aber nur ein "Bit" ist, stellt sich die Frage nach den Details, z.B.

  • Um welchen Prozentsatz wird die Rate gedrosselt
  • Wie lange hält der Zustand an?
  • Welches adaptives Verhalten gibt es

Bislang habe ich noch nichts dazu gefunden. Bei dem Fehlerfall, bei dem eine Firewall aber ECN gesetzt hat, hat sich die Antwortzeit um ca. 500ms erhöht. Es könnte fast den Eindruck machen, dass ein Windows Server beim Empfang einer Quittung mit ECN = 1, den Versand um 0,5 Sekunden aussetzt.

Einschätzung

ECN hatte ich lange Zeit nicht auf dem Radar, da es ja quasi unbemerkt seit 2001 im Standard enthalten ist und anscheinend gut funktioniert oder nicht genutzt wird. Interessant ist dabei schon, dass Windows Server und Windows Clients unterschiedliche Default-Einstellungen haben. Server bieten ECN an und nutzen es auch während Client es nicht anbieten und Server daher auch nicht darauf reagieren. In der Realität kommt ECN daher bei Client zu Client aber auch Client zu Server-Verbindungen gar nicht zur Einsatz. Nur zwischen Servern ist ECN dann überhaupt aktiv.

Mir ist es auch nur aufgefallen, weil auf einem Terminal Server, der organisatorisch zwar ein Client aber vom Betriebssystem doch ein Server ist, die Ergebnisse von End2End-HTTP so gar nicht passen wollten. Ursache war hier aber nicht der Server sondern die Firewall dazwischen, die den ECN-Handshake wohl missverstanden und den Durchsatz dann negativ beeinflusst hat.

Es zeigt mir aber wieder, dass selbst in einem LAN mit Gigabit-Switches u.a. es immer wieder zu Störungen kommen kann, deren Ursache sie nur durch geplante und dauerhafte Tests einkreisen können. Ob sie per PING, HTTP, SMB oder andere Protokolle eine Leistung testen ist fast egal. Ich habe mir einfach angewöhnt, Server und Clients im Rahmen einer Vergleichsmessung mal schnell zu überprüfen.

Weitere Links