Protokół TCP. Nawiązywanie i kończenie połączenia.
Protokół TCP (ang. Transmission Control Protocol) jest jednym z dwóch protokołów warstwy transportowej (obok UDP). TCP kosztem szybkości stawia na niezawodność , w tym wpisie krótko o samy protokole i w jaki sposób nawiązywana jest i kończona sesja TCP.
Głównymi zadaniami protokołu TCP jest stwierdzenie czy transmitowane dane są:
- uszkodzone,
- zagubione,
- powielone,
- dostarczone w nieodpowiedniej kolejności do odbiorcy.
Protokół TCP używany jest wszędzie tam, gdzie musi być zachowana integralność przesyłanych danych, należy do tzw. protokołów niezawodnych. Aby została zapewniona niezawodność transmisji i aby dane dotarły w nie zmienionej formie stosuje następujące mechanizmy:
- każdy wysłany pakiet danych TCP jest numerowany,
- każdy pakiet TCP potwierdzający odbiór jest numerowany,
- protokół wykorzystuje mechanizm pozytywnego potwierdzenia odbioru danych z retransmisją tzn. potwierdzany jest poprawny odbiór danych,
- stosowany jest zegar mierzący czas oczekiwania na potwierdzenie odbioru.
Nagłówek protokołu TCP został przedstawiony poniżej.
Budowa nagłówka TCP rozpoczyna się od pól w których przechowywane są wartości portu źródłowego oraz portu docelowego. Wartości te w połączeniu z danymi zawartymi w nagłówku IP (adres IP źródłowy oraz adres docelowy) są podstawą identyfikacji połączenia.
Pola numer sekwencyjny oraz numer potwierdzenia zawierają wartości, które są niezbędne aby prowadzić skuteczną wymianę danych gdyż tylko w oparciu o numerowanie pakietów hosty prowadzące ze sobą komunikację wiedzą jakich pakietów mają się spodziewać, czy nadchodzą one w prawidłowej kolejności i czy przypadkiem, któryś z pakietów nie zaginął. Więcej informacji i użyciu tych pól już za chwilę.
Wartość w polu długość nagłówka zawiera informację o długości nagłówka.
W polu bity kodu znajduje się osiem jednobitowych pól (zwanych również flagmi), których włączenie bądź wyłączenie sygnalizuje z jakim typem nagłówka TCP mamy do czynienia. Co ważne włączenie jednego z pól nie wyklucza włączenia innych. Zastosowanie poszczególnych pól zaprezentowano poniżej (opis ten jest skrótowy, gdyż do tematu flag będziemy wracać nie raz):
- CWR (ang. Congestion Window Reduced) – ustawienie flagi informuje o zmniejszeniu szybkości transmisji,
- ECE (ang. ECN Echo) – informacja o przeciążeniu,
- URG (ang. Urgent) – pilne dane (rzadko używane),
- ACK (ang. Acknowledgement) – numer potwierdzenia,
- PSH (ang. Push) – otrzymane dane mają być przekazane tak szybko jak to możliwe (nieużywane, gdyż sposób implementacji tej funkcji nie do końca spełnia niezawodność),
- RST (ang. Reset) – zresetowanie połączenia na wskutek błędu,
- SYN (ang. Synchronize) – flaga używana celem synchronizacji numerów ISN,
- FIN (ang. Finished) – flaga używana przy kończeniu połączenia sygnalizująca koniec wysyłania danych.
W protokole TCP celem zapewnienia ciągłości komunikacji oraz optymalnej dla danego typu połączenia szybkości przesyłania danych zastosowano tzw. mechanizm przesuwnego okna pakietów (działanie tej funkcji wykracza poza ramy tego artykułu więc wybacz iż tematu nie rozwijam – na razie :-)). Pole okno jest odpowiedzialne za ustawienie rozmiaru okna pakietów.
Pole suma kontrolna jest odpowiedzialne za wyliczenie wartości bazującej na danych zawartych w nagłówku TCP (chociaż nie tylko) a celem jest sprawdzenie czy dane podczas przesyłu nie uległy modyfikacji. Pole te jest wyliczane przez nadawcę a weryfikowane przez odbiorcę.
Pole wskaźnik ważności ma znaczenie tylko przy ustawionej fladze URG i odznacza dane, które mają być pilnie przekazane.
W nagłówku TCP mogą być definiowane różne parametry, których ustawienie ma wpływ na działanie protokołu TCP i tu również opis ich wszystkich stanowiłby zbyt dalekie zboczenie z tematu wpisu, aczkolwiek opiszemy jedną. Najczęściej umieszczanym parametrem w polu opcje jest maksymalny rozmiar segmentu (tzw. MSS, ang. maximum segment size). Opcja ta odpowiedzialna jest za ustalenie rozmiaru największego segmentu jaki może zostać przesłany. Rozmiar segmentu ustalany jest podczas procesu nawiązywania połączenia.
Ostatnie pole zawiera dane, choć zdarzają się pakiety, które tych danych są pozbawione
Po omówieniu podstawowych parametrów protokołu TCP czas przejść do pokazania ich zastosowania.
Podczas nawiązywania połączenia pomiędzy dwoma urządzeniami i przy wykorzystaniu protokołu TCP w pierwszej kolejności musi nastąpić proces zestawienia połączenia (ang. Three-Way Handshake). Dopiero po dokonanym uzgodnieniu można przejść do właściwej wymiany informacji.
Cały proces negocjacji rozpoczyna się od wysłania na zdefiniowany adres IP i do określonego portu pakietu z ustawioną flagą SYN. Pakiet ten wysyła host nawiązujący połączenie. Jeśli host docelowy jest uruchomiony i usługa korzystająca z danego portu nasłuchuje na tym porcie w kierunku hosta ustanawiającego połączenie zostaje odesłany pakiet z ustawioną flagą SYN/ACK. Po otrzymaniu takiego pakietu w kierunku hosta, z którym nawiązujemy połączenie zostaje wysłane potwierdzenie w postaci pakietu z włączoną flagą ACK.
Proces nawiązywania połączenia TCP przedstawia poniższy rysunek, komputer Host jest inicjującym połączenie z Serwerem.
Dociekliwy Czytelnik mógłby zadać pytanie – Ale jak to się dzieje, że komputer rozróżnia poszczególne sesje TCP, przecież w danej chwili może być nawiązanych kilka sesji? Rozróżnienie sesji TCP opiera się na wykorzystaniu numerów sekwencyjnych oraz numerów potwierdzenia. Numer sekwencyjny często jest określany jako ISN zaś numer potwierdzenia jako ACK.
Jak już wiesz, aby sesja TCP mogła zostać nawiązana w pierwszej kolejności zostaje wysłany pakiet z ustawioną flagą SYN. Pakiet ten został pokazany na rysunku poniżej. Prześledzimy sesję nawiązaną pomiędzy hostem o adresie IP 10.0.0.100 a komputerem o adresie IP 10.0.0.103 na przykładzie ruchu przechwyconego za pomocą Wireshark-a.
Pakiet SYN (punkt 1) z hosta 10.0.0.100 (port 62953) zostaje wysłany w kierunku komputera 10.0.0.103 na port 80 (sesja WWW). Numer sekwencyjny został ustalony na 3319205950 (punkt 2). Numer ten jest losową liczbą z przedziału od 0 do 2^32-1.
Host 10.0.0.103 na otrzymany pakiet SYN odpowiada pakietem z ustawioną flagą SYN/ACK (punkt 4). Pakiet ten zostaje odesłany z źródłowego portu 80 na docelowy port 62953 w kierunku hosta 10.0.0.100 (punkt 1). Host w pakiecie SYN/ACK umieszcza swój własny numer sekwencyjny: 2611984040 (punkt 2) ale dodatkowo zostaje jeszcze umieszczony tzw. numer potwierdzenia Numer ten ma wartość o jeden większą niż numer sekwencyjny otrzymany w pakiecie SYN – 3319205951 (punkt 3).
Ostatnim pakietem jest pakiet ACK (punkt 4), który jest odpowiedzią hosta 10.0.0.100 na otrzymany pakiet SYN/ACK (punkt 1). W pakiecie tym numer sekwencyjny zostaje ustalony na wartość o jeden większą w stosunku do pierwszego pakietu, którym był pakiet SYN – 3319205951 (punkt 2) zaś numer potwierdzenia stanowi wartość o jeden większą niż wartość numeru sekwencyjnego otrzymanego od hosta 10.0.0.103 w pakiecie SYN/ACT – 2611984041 (punkt 3).
Proces ustanowienia sesji TCP zakończył się sukcesem. Nasz schemat ustanawiania sesji TCP możemy wzbogacić o dodatkowe informacje.
Po tym etapie następuje transmisja danych, która również opiera się na przekazywaniu pomiędzy hostami pakietów z odpowiednimi wartościami numerów sekwencyjnych i numerów potwierdzenia.
Po przesłaniu wszystkich danych komunikacja musi się zakończyć. Zakończenie sesji może odbyć się na dwa sposoby. Jeden należy do sposobów „eleganckich” i polega na wykorzystaniu czterech pakietów wraz z ustawioną flagą FIN. Drugi zaś np. na skutek nieoczekiwanego błędu (wyłączenie hosta, błędna konfiguracja) wykorzystuje pakiety TCP z ustawioną flagą RST.
Użycie pierwszego ze sposobów rozpoczyna się od wysłania pakietu z ustawionymi flagami FIN i ACK (pakiet wysyła host chcący zakończyć sesję). Komputer, do którego trafia pakiet odpowiada pakietem ACK a dodatkowo wysyła własny pakiet, w którym ustawione są flagi FIN i ACK. Host inicjujący zamknięcie odpowiada pakietem ACK.
Poniżej na zrzucie pokazano zamknięcie sesji TCP przy wykorzystaniu pakietu FIN.
Host 10.0.0.103 inicjuje zamknięcie w tym celu do komputera o adresie 10.0.0.100 zostaje wysłany pakiet FIN/ACK (punkt 1). 10.0.0.100 odpowiada dwoma pakietami – pakietem ACK oraz własnym pakietem FIN/ACK (punkt 2 i 3). Po otrzymaniu od 10.0.0.100 pakietu FIN/ACK komputer 10.0.0.100 potwierdza fakt zamknięcia sesji pakietem ACK (punkt 4).
Zwróć uwagę na wartości numerów sekwencyjnych i potwierdzenia. Schemat numeracji opiera się na tej samej zasadzie jaka została wykorzystana w przypadku nawiązywania połączenia. Schematycznie proces został przedstawiony na rysunku poniżej.
Drugi ze sposobów wykorzystuje pakiet TCP z ustawioną flagą RST. Wysłanie takiego pakietu informuje hosta o zerwaniu połączenia bądź odmowie jego nawiązania.
Poniżej przedstawiono pakiet wysłany od hosta 10.0.0.100 kończącego sesję TCP na skutek wystąpienia błędu. Pakiet ma ustawione flagi RST oraz ACK (punkt 1). Wysłanie pakietu kończy komunikację pomiędzy komputerami 10.0.0.100 a 10.0.0.103.