Transport

Timery TCP

Rola RTO, estymacja RTT (Jacobson/Karels), keep-alive, persistence, oraz TIME-WAIT.

Timery TCP i ich role

TCP musi podejmować decyzje zależne od czasu, gdy potwierdzenia są opóźnione, segmenty giną albo bezczynny punkt końcowy przestaje odpowiadać. Licznik czasu wyznacza warunek retransmisji, usunięcia stanu lub wysłania sondy. Samo wygaśnięcie licznika nie wskazuje przyczyny braku odpowiedzi, lecz dostarcza określonego zdarzenia dla maszyny stanów.

Internet jest środowiskiem . Zdarzenia mogą występować w nieregularnych odstępach, a nadawca i odbiorca nie mają wspólnego zegara. Segment może dotrzeć po kilku milisekundach lub sekundach, przyjść poza kolejnością albo zaginąć całkowicie.

Protokół sterowania transmisją (TCP) wykorzystuje więc kilka liczników czasu. Ich wartości i działania obejmują retransmisję po braku potwierdzenia, okres TIME-WAIT po uporządkowanym zamknięciu, sondowanie po ogłoszeniu zerowego okna oraz opcjonalne sprawdzanie bezczynnego połączenia. Timery wspierają niezawodność i zarządzanie zasobami bez założenia synchronicznej pracy sieci. Licznik należy do lokalnego stanu połączenia, a jego wygaśnięcie jest obsługiwane razem z segmentami i żądaniami aplikacji. Różne timery mają różne cele i nie powinny być traktowane jako ogólna miara stanu sieci. Implementacje mogą łączyć zdarzenia liczników dla wydajności, lecz działania nadal muszą odpowiadać semantyce właściwego timera.

1. Licznik retransmisji i RTO

Licznik retransmisji zarządza limitem czasu retransmisji (RTO). Zapobiega nieograniczonemu oczekiwaniu, gdy segment danych lub jego potwierdzenie zaginie. Po wygaśnięciu TCP retransmituje najwcześniejsze niepotwierdzone dane zgodnie z regułami retransmisji. Licznik dotyczy oczekujących danych, a potwierdzenie obejmujące retransmitowany zakres może go zatrzymać albo uruchomić ponownie. Wygaśnięcie wpływa również na kontrolę przeciążenia, lecz retransmisja i decyzje o szybkości wysyłania są odrębnymi mechanizmami. Timer nie wymaga jednej stałej wartości dla każdego segmentu: połączenie szacuje RTT i jego zmienność, a następnie stosuje bieżące RTO do oczekujących danych.

Wybór RTO na podstawie RTT

TCP musi dobrać limit do obserwowanego czasu obiegu. Połączenie z pobliskim serwerem może mieć inny RTT niż połączenie z Sydney, a przeciążenie może zmieniać obie wartości w czasie. Stała wartość powodowałaby zbędne retransmisje na wolnej ścieżce albo opóźniała reakcję na stratę na ścieżce szybkiej.

  • Jeśli RTO jest ustawione zbyt krótko, TCP może retransmitować segment opóźniony, lecz nieutracony. Zużywa to przepustowość i może zwiększać obciążenie przeciążonej ścieżki.
  • Jeśli RTO jest ustawione zbyt długo, TCP dłużej czeka po rzeczywistej stracie. Okres bezczynności opóźnia odzyskiwanie i może obniżać wydajność aplikacji.

TCP oblicza więc RTO dla każdego połączenia na podstawie pomiaru . RFC 6298 określa estymator i wymaga dolnej granicy jednej sekundy dla obliczonego RTO, z uwzględnieniem rozdzielczości zegara implementacji.

Estymator Jacobsona/Karelsa: RTT i RTO

Estymator kojarzony z Jacobsonem i Karelsem nie wykorzystuje tylko ostatniego pomiaru RTT. Utrzymuje wygładzony RTT oraz oszacowanie zmienności RTT, a następnie łączy te wartości w limicie retransmisji. Składnik zmienności jest potrzebny na ścieżkach, których opóźnienie się zmienia, ponieważ taka sama średnia RTT może wymagać różnych marginesów. RFC 6298 aktualizuje zmienność przed wygładzonym RTT, aby obie wartości odnosiły się do poprzedniego oszacowania podczas obsługi próbki.

  1. Pomiar Próbki RTT ('SampleRTT')

    TCP mierzy czas od wysłania segmentu do otrzymania odpowiedniego ACK. Jest to 'SampleRTT'. Dla pierwszej próbki RFC 6298 ustawia SRTT na wartość próbki, a RTTVAR na połowę tej wartości. Retransmisja powoduje niejednoznaczność, ponieważ ACK może dotyczyć pierwszego wysłania albo retransmisji. Algorytm Karna wyklucza więc pomiary segmentów retransmitowanych. Znaczniki czasu mogą wskazać konkretne wysłanie i pozwolić na próbkę, gdy obowiązują reguły znaczników, a zwykła niejednoznaczna próbka jest nie używana.

  2. Obliczanie Wygładzonego RTT ('SRTT')

    Pojedynczy 'SampleRTT' może być zakłócony. TCP utrzymuje Wygładzony Czas Obiegu, 'SRTT', jako ważoną średnią ruchomą:

    SRTT=(1−α)⋅SRTTstary+α⋅SampleRTTSRTT = (1 - \alpha) \cdot SRTT_{stary} + \alpha \cdot SampleRTT

    Parametr α\alpha (alfa) zwykle ma wartość 1/81/8. Nowy SRTT otrzymuje więc 87,5% wagi poprzedniego oszacowania i 12,5% wagi najnowszego pomiaru. Ogranicza to wpływ pojedynczego opóźnienia, lecz pozwala śledzić trwałą zmianę.

  3. Uwzględnianie Zmienności ('RTTvar')

    Średnia nie wystarcza. Połączenie ze średnim RTT 100 ms może dawać próbki 80 ms i 120 ms. TCP oblicza więc zmienność RTT, 'RTTVAR', która śledzi wygładzoną bezwzględną różnicę między próbką a poprzednim SRTT.

    RTTvar=(1−β)⋅RTTvarstary+β⋅∣SRTT−SampleRTT∣RTTvar = (1 - \beta) \cdot RTTvar_{stary} + \beta \cdot |SRTT - SampleRTT|

    Parametr β\beta (beta) zwykle ma wartość 1/41/4. Zmienność jest aktualizowana przed użyciem nowej próbki przez SRTT, więc opisuje odchylenie względem poprzedniego oszacowania.

  4. Obliczanie Końcowego RTO

    Limit Czasu Retransmisji łączy wygładzony RTT z marginesem zmienności. RFC 6298 uwzględnia również rozdzielczość zegara i używa współczynnika cztery:

    RTO=SRTT+max(G,4⋅RTTVAR)RTO = SRTT + max(G, 4 \cdot RTTVAR)

    RTO jest zaokrąglany w górę do co najmniej jednej sekundy. Implementacja może ustalić maksimum, lecz musi ono wynosić co najmniej 60 sekund. Te granice i składnik zmienności ograniczają przedwczesne wygaśnięcia licznika. G oznacza rozdzielczość zegara używanego przez implementację. Po wygaśnięciu nadawca podwaja licznik, zamiast traktować opóźnione ACK jako nową próbkę RTT, dlatego reguła Karna i wykładnicze wycofywanie występują razem w algorytmie.

  5. Wykładnicze Wycofywanie (Exponential Backoff)

    Jeśli retransmitowany segment również nie otrzyma ACK, wygaśnięcie RTO powoduje kolejną retransmisję i wycofywanie wykładnicze. TCP podwaja RTO przy każdym kolejnym wygaśnięciu dla tego samego segmentu. Przy początkowym RTO równym 1 sekundzie ciąg wynosi 2, 4 i 8 sekund aż do skonfigurowanego limitu. Po wygaśnięciu RFC 6298 uruchamia licznik ponownie, a nowa prawidłowa próbka RTT może obniżyć oszacowanie. Dla niepotwierdzonego SYN RTO retransmisji jest ponownie ustawiane na co najmniej 3 sekundy przed transferem danych.

2. Licznik TIME-WAIT (2MSL)

Po typowym uporządkowanym zamknięciu strona, która je zainicjowała, nie przechodzi od razu do stanu 'CLOSED'. Wchodzi w TIME-WAIT, którym zarządza licznik ustawiony na 2MSL. Stan pozwala obsłużyć retransmisję FIN i oddziela stare połączenie od późniejszego, które może użyć tej samej krotki adresów i portów.

jest maksymalnym czasem przypisanym segmentowi na potrzeby tej reguły TCP. RFC 9293 przyjmuje dla swojej specyfikacji MSL równe dwóm minutom, więc 2MSL wynosi tam cztery minuty. Implementacja może optymalizować licznik zgodnie z regułami znaczników czasu. Oczekiwanie ogranicza ryzyko pomylenia starych duplikatów z późniejszym połączeniem. TIME-WAIT utrzymuje punkt końcowy wykonujący aktywne zamknięcie, a stan pozwala również odpowiedzieć wymaganym ACK na retransmitowany FIN.

Dwa cele stanu TIME-WAIT

Okres oczekiwania odpowiada za dwa wymagania protokołu.

  • Implementacja Niezawodnego Zakończenia Połączenia

    Końcową wymianą jest wysłanie przez aktywnego zamykającego ACK w odpowiedzi na FIN pasywnego zamykającego. Jeśli ACK zaginie, pasywny zamykający retransmituje FIN po wygaśnięciu własnego licznika. Bez TIME-WAIT aktywny zamykający mógłby być już w CLOSED i potraktować retransmitowany FIN jako należący do nieistniejącego połączenia, odpowiadając prawdopodobnie segmentem RST.

    W stanie TIME-WAIT aktywny zamykający utrzymuje potrzebny stan przez 2MSL. Gdy dotrze retransmitowany FIN, może ponownie wysłać ostatnie ACK i pozwolić pasywnemu zamykającemu zakończyć połączenie.

  • Zapobieganie Uszkodzeniu Nowych Połączeń przez Opóźnione Duplikaty

    Segment z poprzedniego połączenia może zostać opóźniony albo zduplikowany w sieci i dotrzeć po jego zamknięciu.

    Rozważmy zamknięte połączenie między 1.2.3.4:500001.2.3.4:50000 a 5.6.7.8:805.6.7.8:80. Późniejsze połączenie między 1.2.3.4:500001.2.3.4:50000 a 5.6.7.8:805.6.7.8:80 może ponownie użyć tej samej 4-krotki. Kontrola numerów sekwencyjnych i TIME-WAIT ograniczają ryzyko przyjęcia opóźnionego segmentu starego połączenia jako danych nowego.

    Reguła 2MSL utrzymuje starą krotkę w TIME-WAIT, gdy stare duplikaty mogą mieć jeszcze znaczenie. Po wygaśnięciu licznika punkt końcowy może przejść do CLOSED, z uwzględnieniem reguł ponownego użycia i znaczników czasu implementacji.

3. Licznik podtrzymania i sondowanie zerowego okna

Kontrola przepływu TCP ma scenariusz awarii związany z ogłoszeniem zerowego okna odbiorczego ('rwnd=0'). Nadawca przestaje wysyłać nowe dane. Później aplikacja odbiorcy odczytuje dane i zwalnia miejsce, więc odbiorca wysyła ACK z aktualizacją okna o wartości większej od zera.

Segmenty zawierające wyłącznie ACK nie są przez TCP niezawodnie retransmitowane. Jeśli aktualizacja okna zaginie, nadawca może nadal czekać na zmianę, a odbiorca na dane, co tworzy impas zerowego okna.

Licznik podtrzymania (ang. Persistence Timer) przełamuje ten impas. Po ogłoszeniu zerowego okna nadawca uruchamia licznik. Jeśli wygaśnie przed nadejściem aktualizacji, nadawca wysyła małą sondę okna (ang. window probe). RFC 9293 określa, że pierwsza sonda jest wysyłana po czasie retransmisji, a odstęp może rosnąć wykładniczo. Sonda zawiera co najmniej jeden nowy oktet, gdy dane są dostępne, albo dane retransmitowane, a odbiorca odpowiada z aktualnym oknem. Sonda jest dozwolona przy ogłoszonym zerowym oknie, ponieważ ma wykryć późniejszą aktualizację, bez uruchamiania nieograniczonego transferu danych.

  • Jeśli okno nadal wynosi zero, nadawca planuje kolejną sondę, a odstęp może rosnąć przez wykładnicze wycofywanie.
  • Jeśli okno ma wartość większą od zera, nadawca może wznowić transmisję w ogłoszonym limicie.

4. Opcjonalny licznik keep-alive

Połączenia TCP mogą pozostawać bezczynne przez wiele godzin, na przykład podczas sesji SSH. Jeśli jeden punkt końcowy ulegnie awarii albo utraci dostęp do sieci bez wysłania FIN, drugi może zachować połączenie półotwarte i związane z nim zasoby. Duża liczba takich połączeń może zwiększać presję na zasoby.

Licznik keep-alive jest opcjonalnym mechanizmem TCP do sprawdzania bezczynnego punktu końcowego. Aplikacja decyduje o jego włączeniu. RFC 1122 określa domyślne wyłączenie oraz odstęp konfigurowany przez aplikację, z domyślną wartością co najmniej dwóch godzin, gdy keep-alive jest używany.

  1. Serwer wysyła segment sondy keep-alive, zwykle ACK z numerem SEG.SEQ=SND.NXT−1SEG.SEQ = SND.NXT - 1, dobranym tak, aby wywołać odpowiedź.
  2. Jeśli klient odpowie ACK, serwer otrzymuje informację, że punkt końcowy TCP odpowiada, i może zresetować skonfigurowany licznik keep-alive.
  3. Jeśli klient uległ awarii i został ponownie uruchomiony, może nie rozpoznać połączenia i odpowiedzieć pakietem RST, co pozwala usunąć jego stan.
  4. Jeśli klient jest nieosiągalny, może nie odpowiedzieć. TCP nie definiuje jednej liczby sond ani jednego odstępu, a pojedynczy brak odpowiedzi nie dowodzi awarii punktu końcowego. Implementacja lub polityka aplikacji decyduje, czy kolejne sondy prowadzą do zamknięcia połączenia.

Ruch keep-alive może być filtrowany przez urządzenia pośredniczące albo mylony z pulsem aplikacyjnym. Domyślny odstęp może być zbyt długi dla wymagań aplikacji, dlatego wiele aplikacji implementuje własny heartbeat i własną politykę awarii nad TCP. Prawidłowa odpowiedź sondy pokazuje, że punkt końcowy odpowiedział na segment TCP w danej chwili. Nie potwierdza sprawności aplikacji ani trwałej dostępności ścieżki, dlatego aplikacja może potrzebować własnego terminu odpowiedzi. Odpowiedź keep-alive jest odrębna od potwierdzenia danych aplikacyjnych i nie powinna pełnić funkcji potwierdzenia dostarczenia komunikatu aplikacji.

Powiązane artykuły