Kurs Packet Tracer 6.2 — od zera do sieci tworzenia cz. 5.1 — protokoły: TCP
W ostatniej części kursu sieci komputerowych, zajmowaliśmy się protokołami routingu RIP i EIGRP. Wiemy już, jak pakiety w sieci mogą być przekazywane pomiędzy komputerami jednego lub różnych systemów autonomicznych. W tej części odejdziemy trochę od tematyki routingu (wrócimy do niej później, omawiając jeden z zewnętrznych protokołów trasowania (BGP) oraz bardzo popularny OSPF. W trakcie poprzednich części pominęliśmy kilka ważnych zagadnień teoretycznych. W dalszym ciągu nie wiemy, co to jest enkapsulacja pakietów. Nie znamy nagłówków ani zasad działania podstawowych protokołów wykorzystywanych w dzisiejszym Internecie. (np.: Skąd przeglądarka po wpisaniu adresu www.dobreprogramy.pl wie, z jakim serwerem ma się połączyć?) Poznamy także co nieco poleceń systemu IOS służących do diagnostyki działania sieci. No to do dzieła!
Podstawowe protokoły wykorzystywane w sieci Internet
Otwórzmy Packet Tracera, ustawmy serwer i po dwukrotnym kliknięciu na nim przejdźmy na zakładkę Services. Właśnie tu możemy konfigurować usługi, które dany komputer ma dostarczać sieci. Jednakże, zanim przejdziemy do omawiania tych protokołów, wróćmy jeszcze na chwilę do modelu OSI, podstawy działania dzisiejszego Internetu.
Wszystkie protokoły, które widzimy pod napisem Services w Packet Tracer to protokoły warstwy aplikacji. Jak wiemy z wcześniejszych części kursu, są to aplikacje uruchomione na komputerze, które chcą przesyłać dane w sieci. Takie zadanie spełnia każdy z protokołów wymienionych wyżej: HTTP obsługuje żądania pobierania treści stron internetowych, FTP – pobieranie plików itd.
Jednym z najpopularniejszych protokołów niższej warstwy jest TLS – zajmujący się szyfrowaniem danych. TLS‑em, SSL i innymi protokołami warstwy prezentacji zajmiemy się w późniejszych częściach kursu.
Warstwa sesji to protokoły służące głównie autoryzacji użytkowników. Najbardziej znanymi są SMB (Server Message Block, wykorzystywany, jeśli udostępniamy/pobieramy pliki w ramach sieci lokalnej systemów Windows). Również on nas na razie nie interesuje.
Doszliśmy wreszcie do warstwy transportowej. To właśnie w tym miejscu dzieje się najwięcej ciekawych rzeczy. Pracuje tutaj dwa protokoły, które są powszechnie używane w każdym zakamarku współczesnego Internetu. Są to Transmission Control Protocol (TCP) oraz User Datagram Protocol. Protokoły te zajmują się podziałem danych otrzymanych z wyższych warstw na części i przygotowaniu ich do wysłania. Jest to bardzo ciekawy proces, któremu warto się przyjrzeć.
W tej części zajmiemy się protokołem TCP. Jest połączeniowy. Cóż to oznacza? Otóż, przed wysłaniem lub odebraniem danych pomiędzy stacją źródłową i docelową musi zostać nawiązane połączenie. TCP gwarantuje, że wszystkie pakiety, które zostaną wysłane przez serwer, klient bezpiecznie i w całości odbierze. W przeciwnym wypadku klient może wysłać „reklamację” (żądanie retransmisji), którą serwer z reguły przyjmuje i retransmituje segmenty. Mimo zagwarantowania, że pakiety na 100% dotrą do celu, to nie jest powiedziane, że dotrą w odpowiedniej kolejności. Klient na podstawie danych zawartych w nagłówku musi je odpowiednio poskładać.
Nagłówek protokołu TCP
Wygląda na skomplikowany? To tylko pozory. Dzięki analizie nagłówka wszystko stanie się jasne.
Port nadawcy i port odbiorcy
Pierwsze, co rzuca się w oczy to pola: port nadawcy i port odbiorcy. Cóż to jest ten port? Do tej pory pod pojęciem port rozumieliśmy co najwyżej fizyczny port przełącznika/routera. Jednakże tutaj znaczenie tego słowa jest całkowicie inne. Pole zajmuje 16 bitów, a więc mamy 2 do potęgi 16 kombinacji. Zastanówmy się do czego to może służyć… Otóż, załóżmy, że posiadamy jeden komputer. Chcemy, aby po połączeniu się z nim użytkownik mógł przeglądać stronę internetową. Bardzo proszę, uruchamiamy serwer WWW i wszystko hula. Jednakże, co się stanie, gdybyśmy chcieli na tym samym komputerze uruchomić jeszcze serwer FTP lub nawet uTorrenta? Przecież wszystkie te programy pracują na jednym komputerze i w tym samym czasie odbierają lub wysyłają pakiety! Skąd np.: uTorrent ma wiedzieć, jakie dane powinien odebrać dla siebie, a jakie powinny odczytać inne aplikacje? No właśnie. Aby uniknąć takich konfliktów, wprowadzono pojęcie portu. Jest to 16 bitowa liczba, która określa daną aplikację lub protokół. Przykładowo, serwery stron internetowych zwykle działają na porcie 80. Natomiast, jeśli chcemy pobrać plik przez serwer FTP, korzystamy z portu 21.
Porty od 1 do 1023 są tzw. portami systemowymi. Używane są przez usługi systemowe lub serwery różnych aplikacji, których używamy na co dzień w Internecie. Twórcy aplikacji sieciowych nie powinni używać portów z tego zakresu. Dla nich przeznaczone są liczby większe od 1023.
Numer sekwencyjny
Następnym polem jest numer sekwencyjny. Jego zastosowanie również jest bardzo logiczne. Pojedynczy segment danych, jak dobrze wiemy, ma ograniczoną wielkość. Może zdarzyć się tak, że dane, które chcemy przesłać nie zmieszczą się w jednym segmencie. Lecz, w takim razie w jaki sposób poskładać plik z kilku segmentów po stronie odbiorcy? Poszczególne części plików nie muszą przecież przyjść w takiej kolejności, w jakiej zostały wysłane. Za to właśnie odpowiada numer sekwencyjny. Na początku transmisji ustawiany jest tzw. inicjujący numer sekwencyjny. Strony transmisji umawiają się, że od takiej i takiej cyfry zaczną numerację bajtów w przesyłanych plikach. W kolejnych segmentach numer ten jest powiększany o liczbę bajtów wysłanych w poprzednim segmencie. Żebyśmy lepiej zrozumieli znaczenie tego pola, omówmy następujący przykład. Przyjmijmy, że mamy do wysłania 500 bajtów danych, które udało się upakować w czterech segmentach o rozmiarach kolejno: 92 bajtów, 130 bajtów, 143 bajtów i 135 bajtów. Przyjmijmy również, że strony dogadały się, że numerację zaczynamy od zera. Wtedy pole numer sekwencyjny będzie miało następujące wartości:
- Dla pierwszego segmentu: 0 (gdyż umówiliśmy się, że właśnie od 0 rozpoczynamy transmisję, a jest to właśnie pierwszy właściwy segment).
- Dla drugiego segmentu: 92 (gdyż właśnie na tym bajcie zakończyliśmy odbiór pliku.)
- Dla trzeciego segmentu: 222 (gdyż 92+130=222. Upraszczając, numer sekwencyjny to suma długości wszystkich wcześniejszych segmentów)
- Dla czwartego segmentu: 365.
W ten sposób, nawet jeśli jako pierwszy odbierzemy pakiet trzeci (o numerze sekwencyjnym 222) to będziemy wiedzieli, że należy poczekać, gdyż jest to jakaś część pliku. Gdy odbierzemy wszystkie części, będziemy wiedzieli, jak je uporządkować i jak z tych części z powrotem złożyć działający instrument.
Numer potwierdzenia
Co tam mamy dalej… numer potwierdzenia. Mówiliśmy wcześniej, że protokół TCP gwarantuje dotarcie pakietu do kresu jego podróży. Klient po odebraniu segmentu, powinien powiadomić serwer że dane zostały poprawnie wysłane. W takim wypadku ustawia się flagę ACK. W polu numer potwierdzenia wpisuje się natomiast sumę odebranych dotychczas danych. Dzięki temu serwer wie, które części np.: pliku zostały poprawnie wysłane, a które trzeba retransmitować.
Długość nagłówka
Pole, o którego zastosowaniu mówi sama nazwa. Jednakże, jedna rzecz może być zastanawiająca … Dlaczego to pole ma tylko 4 bity? Według najprostszej interpretacji nagłówek mógłby mieć wtedy zaledwie 2^4=16 bitów/bajtów. To nie jest prawdą.
Pole długość nagłówka określa liczbę słów 32 bitowych, które składają się na cały nagłówek. Więc jeśli nagłówek będzie miał 160 bitów (20 bajtów), to w tym polu ujrzymy cyfrę 5. W ten sposób możemy też obliczyć maksymalny rozmiar nagłówka segmentu TCP, który wynosi 2^4‑1=16-1=15 trzydziesto-dwu bitowych słów. Maksymalny rozmiar nagłówka wynosi więc 15*32=480 bitów, czyli 60 bajtów. Dla informacji, nagłówek nie może mieć mniej niż 5 słów, co zresztą doskonale widać na załączonym schemacie.
Zarezerwowane
Pole zostawione dla przyszłych zastosowań. Domyślnie wypełnione jest samymi zerami. W nowszych implementacjach pełni pewną rolę (konkretnie chodzi o przeciążenia) ale w naszych obecnych rozważaniach możemy bezpiecznie przyjąć, że ta część nagłówka nie pełni żadnej roli.
Flagi
Bardzo ciekawe pole. Flagi częściowo definiują, jak należy interpretować dany pakiet. Przykładowo, pakiety oznaczone flagą SYN służą do tworzenia połączenia, a pakiety oznaczone ACK to pakiety potwierdzenia. Te dwa rodzaje flag były wspominane we wcześniejszej części tego artykułu. Jednakże, to nie wszystko, co TCP ma w tym miejscu do zaoferowania:
- URG – pakiet oznaczony tą flagą musi być natychmiast przetworzony. Host docelowy może nawet zawiesić aktualnie wykonywane czynności w celu przetworzenia danych znajdujących się w pakiecie oznaczonych flagą Urgent.
- ACK – flaga, którą omówiliśmy już wcześniej. Oznacza, że segment jest potwierdzeniem poprawnie przesłanych danych. Wskazuje także na użycie pola numer potwierdzenia.
- PSH – dane, które aplikacja chce wysłać zwykle gromadzone są w buforze. Dzięki temu można optymalniej wykorzystać pasmo, wysyłając większą ilość danych w jednym segmencie. Nie zawsze jest to korzystne. Np.: w przypadku telnetu czy ssh chcemy, aby polecenie zostało natychmiastowo przesłane i wykonane przez zdalną maszynę. Właśnie w takich wypadkach używana jest flaga PSH. Powoduje ona natychmiastowe opróżnienie bufora i wysłanie danych.
- RST – rzadko używana. Mówi o konieczności zresetowania połączenia
- SYN – mówiliśmy o niej we wcześniejszej części artykułu. Wykorzystywana przy nawiązywaniu połączenia. Numer umieszczony w polu numer sekwencyjny, w segmencie oznaczonym flagą SYN to inicjujący numer sekwencyjny.
- FIN – flaga wykorzystywana przy zakończeniu połączenia. Informuje, że nadawca nie zamierza już wysyłać więcej danych.
Szerokość okna
Powoli zbliżamy się do końca. Dotarliśmy do enigmatycznie brzmiącej „szerokości okna”. Cóż to oznacza? Jest to maksymalna ilość bajtów danych, jakie może odczytać odbiorca. Zapobiega to zbyt dużemu napływowi danych. Jeśli klient nie może sobie poradzić z natłokiem zer i jedynek, w pakiecie z flagą ACK ustalana jest wartość zero. Oznacza to, że strona wysyłająca powinna się na jakiś czas wstrzymać z wysyłaniem kolejnych danych.
Suma kontrolna
Powiedzieliśmy już sobie, że protokół TCP gwarantuje dotarcie bezbłędnych danych do komputera docelowego. Jeśli dane są błędne, możemy poprosić o retransmisję. Lecz, skąd mamy wiedzieć, czy rzeczywiście w przesłanych danych kryje się jakaś nieprawidłowość? Za to właśnie odpowiada suma kontrolna. Zmiana choćby jednego bitu nagłówka lub danych pociąga za sobą zmianę sumy kontrolnej, co pozwala wykryć że coś po drodze poszło nie tak. Na podstawie sumy kontrolnej zawartej w nagłówku TCP nie naprawimy segmentu. Nie ma takiej możliwości. Możemy jedynie zdefiniować czy dane są uszkodzone czy nie.
Suma kontrolna składa się z 16 bitów. Liczona jest dość prosto. Obliczymy sumę kontrolną dla następującego pakietu:
Przede wszystkim musimy wziąć pod uwagę jedną bardzo ważną rzecz. W procesie liczenia sumy kontrolnej biorą udział dane nie tylko z nagłówka TCP. Komputer, w trakcie wykonywania tego procesu, tworzy sobie tymczasowo w pamięci tzw. pseudo nagłówek, którego schemat znajduje się poniżej:
Dzięki temu zabiegowi nawet uszkodzenie nagłówka IP zostanie wychwycone w sumie kontrolnej TCP. Liczenie sumy kontrolnej musimy więc zacząć od skonstruowania pseudo nagłówka. Wszystkie dane, które będą brały udział w operacji dzielimy na 16 bitowe bloki, które będą zapisane w systemie szesnastkowym. Jeśli czegoś do końca nie rozumiesz, wszystko wyjaśni się na poniższym przykładzie.
Ad.1 – zauważ, że zarówno pole zarezerwowane jak i protokół mają po 8 bitów. Aby policzyć sumę kontrolną, wszystkie „słowa” muszą być 16‑bitowe. Dlatego też połączyliśmy te dwa pola w zapisie w jedno.
Ad. 2 – Długość segmentu TCP musimy policzyć sami. W naszym segmencie nie są zapisane żadne dane, gdyż jest to pakiet z flagą synchronizacji i potwierdzenia. Wobec tego pod uwagę będziemy brali jedynie długość nagłówka TCP, która wynosi 32 bajty (spójrz na pozycję Header Length). Jeśli nasz segment przenosiłby jakieś dane, musielibyśmy do długości nagłówka doliczyć także długość danych.
Przeprowadźmy teraz zwykłe dodawanie. Należy zsumować wszystkie wiersze zapisane w powyższej tabeli, czyli D83A+D123+C0A8+0107+0006+0020. Wynik, który otrzymamy, będzie równy 26B32. Zapamiętajmy go.
Teraz przejdźmy do analizy samego nagłówka TCP. Podobnie jak wyżej, sporządźmy sobie tabelkę, którą skrzętnie wypełnimy danymi:
Ad. 3. Suma kontrolna jest obecna w nagłówku TCP, dlatego dałem ją w tabelce. Jednakże, w procesie jej pierwszego obliczania pole to przyjmuje wartość 0000.
Sumujemy przepisane do tabelki wartości. Wynik, jaki powinniśmy otrzymać, to: 4A2DA. Jesteśmy już bardzo blisko celu. Teraz musimy dodać ten wynik do otrzymanego wcześniej 26B32. Powinniśmy otrzymać 70E0C. Zastanówmy się, czy wszystko poszło tak jak trzeba? Wynik otrzymany przez nas jest coś za duży, czyż nie? To dlatego, że na samym wyniku musimy przeprowadzić jeszcze kilka operacji. Jeśli otrzymamy liczbę, która zajmuje więcej niż 16 bitów (4 pozycje w zapisie szesnastkowym) to pierwszą cyfrę usuwamy i dodajemy do otrzymanego wyniku. W naszym przypadku efekt obliczeń zostanie przekształcony następująco: 70E0C->E0C+7=E13.
Ostatni krok to przeprowadzenie operacji NOT. Na czym to polega? Po prostu w zapisie binarnym E13 musimy zamienić wszystkie zera na jedynki, a jedynki na zera. Zróbmy to, dla uproszczenia, w tabelce.
Voila! Otrzymaliśmy poprawny wynik. Właśnie taka suma kontrolna została zapisana w nagłówku segmentu TCP, nad którym pracowaliśmy. W podobny sposób przebiega sprawdzanie poprawności pakietu. Oblicza się sumę kontrolną, a potem porównuje z tą zapisaną w nagłówku. To jest najtrudniejszy element dzisiejszego artykułu. Dalej będzie tylko prościej :)
Wskaźnik priorytetu
Pole to oznacza koniec pilnych danych. W polu zawarty jest numer pierwszego bajtu następującego po pilnych danych (liczone względem numeru sekwencyjnego).
Opcje
Wykorzystywane najczęściej do przesłania dodatkowych informacji na temat połączenia. Parametrów, które można tu wpisać jest dość dużo. Pełna lista dostępna jest na stronie IANA. (http://www.iana.org/assignments/tcp-parameters/tcp-parameters.xhtml#tc... ). Omówimy kilka najczęściej używanych:
- MSS – maksymalny rozmiar segmentu – opcja używana w trakcie nawiązywania połączenia. Przekazuje maksymalny rozmiar segmentu, jaki host może przyjąć.
- NAK – Potwierdzenie negatywne – ciekawa nazwa i ciekawa opcja. Przyjmijmy, że mamy 5 segmentów, które składają się na pojedynczy pakiet. Załóżmy, że odebraliśmy 1,2,3 oraz 5 segment. Brakuje nam jednej części, więc nie możemy złożyć całego pakietu w jedną całość. Nie możemy też poprosić o retransmisję tylko jednego segmentu, gdyż nie pozwala na to standardowa polityka TCP. W przypadku dużej ilości takich błędów generujemy spore dodatkowe obciążenie. Jeśli obydwie strony zadeklarują możliwość korzystania z NAK, to strona może poprosić o retransmisję jedynie brakującego fragmentu.
- SACK – Zastosowanie podobne do NAK. Z tym że tym razem odbiorca informuje, które segmenty udało się odebrać poprawnie. Żeby korzystać z tej funkcjonalności, najpierw obydwie strony komunikacji muszą wynegocjować w trakcie inicjacji połączenia możliwość korzystania z SACK.
Nawiązywanie połączenia TCP
Protokół TCP jest protokołem połączeniowym. Wobec tego wymaga, aby ustalić połączenie oraz wszystkie jego parametry zanim zacznie się właściwa transmisja. Proces ten możemy zaobserwować w programie Packet Tracer. Stwórzmy prostą sieć, złożoną z klienta i serwera. Ustaw serwer (Server-PT) oraz klienta (PC‑PT). Połącz je kablem skrosowanym. Adresy IP ustaw takie, jakie chcesz. Reguły poznałeś już w poprzednich artykułach.
Przejdź w tryb symulacji (przełączanie trybu pracy – między simulation a realtime znajduje się w dolnej prawej części ekranu.). Wejdź teraz na komputer klienta. W zakładce Desktop uruchom przeglądarkę internetową (Web Browser). W polu URL wpisz adres IP serwera.
Przy PC0 pojawiła się koperta (najprawdopodobniej zielona). Kliknij na nią i przejdź na zakładkę Outbound PDU Details.
Klient nawiązuje połączenie
To jest pierwszy pakiet, który klient wysyła do serwera, chcąc nawiązać połączenie. Co my tu widzimy ciekawego? Przede wszystkim, ustalona jest flaga SYN. Klient informuje także, od jakiej cyfry rozpocznie numerację swoich segmentów (SEQUENCE NUM: 0). Zobaczmy, jaka będzie odpowiedź serwera.
Serwer akceptuje połączenie
Klient odpowiada na żądanie serwera. W pakiecie ustalone są dwie flagi: SYN – co oznacza, że ten pakiet służy do nawiązania połączenia oraz ACK – która informuje klienta, że pakiet wysłany przez niego został poprawnie odebrany. W pozostałych polach znajdują się dane. Podobnie jak wcześniej, SEQUENCE NUM zawiera numer, od którego rozpocznie się numerowanie danych.
Klient akceptuje warunki i rozpoczyna komunikację
W tym segmencie znajdują się już właściwe dane (w tym wypadku http). Numer sekwencyjny oraz numer potwierdzenia ustawione są na jeden. Ustawiona flaga ACK powoduje, że pakiet, oprócz przekazania danych ma uświadomić serwerowi, że pakiet wysłany przez niego został poprawnie odebrany.
Dalsza komunikacja -> zakończenie połączenia
Dalsza komunikacja przebiega już na prostej zasadzie – klient wysyła dane->serwer odbiera dane i wysyła potwierdzenie (flaga ACK) do klienta. Jednakże, co się dzieje w wypadku, gdy jedna lub obie strony chcą zakończyć pogawędkę?
Przyjmijmy, że najpierw klient chce zakończyć połączenie. Wysyła wtedy do serwera pakiet z flagą FIN. Warto zauważyć, że nawet ostatni pakiet może zawierać dane dla serwera. Serwer, po odebraniu i przeanalizowaniu pakietu odsyła do klienta segment TCP z flagą ACK. Warto zauważyć, że strona, która nie zgłosiła chęci zakończenia połączenia (w tym wypadku serwer) może dalej do drugiego rozmówcy wysyłać swoje wiadomości. Druga strona może oczywiście zakończyć połączenie w ten sam sposób, jaki opisany jest wyżej.
Słowem zakończenia
Informacji na temat podstawowych protokołów używanych w sieci Internet jest zbyt duzo, aby umieścić je w jednym artykule. Obecnie wiemy już, jak działa TCP. W następnej części poznamy jego brata – bezpołączeniowy protokół UDP. W dalszej części zajmiemy się też protokołem IP i (być może) diagnostyką sieci za pomocą ICMP.