Warstwa sieciowa
Zadaniem warstwy sieciowej jest przenoszenie pakietów na całej trasie od źródła do celu. Dotarcie do miejsca przeznaczenia może wymagać wielu przeskoków przez routery na trasie pakietu. W oczywisty sposób różni się ona tym od warstwy łącza danych, której skromniejsze zadanie polega jedynie na przeniesieniu ramki z jednego końca kabla na drugi. Warstwa sieciowa jest więc najniższą warstwą zajmującą się transmisją dwupunktową.
Aby osiągnąć swoje cele, warstwa sieciowa musi znać topologię podsieci komunikacyjnej (tzn. zbiór wszystkich routerów) i wybierać odpowiednią trasę poprzez tę podsieć. Musi też tak wybierać trasy, aby unikać przeciążania części linii komunikacyjnych i routerów, pozostawiając inne bez pracy. Na koniec pojawia się nowy problem, gdy źródło i cel pakietu mieszczą się w osobnych sieciach. W tym rozdziale przestudiujemy i zilustrujemy wszystkie te kwestie, głównie na przykładzie Internetu i jego protokołu warstwy sieciowej (IP), aczkolwiek sieci bezprzewodowe też zostaną tu omówione.
W następnych punktach przedstawimy wprowadzenie do części problemów, z którymi muszą się zmagać projektanci warstwy sieciowej. Należą do nich usługi udostępniane warstwie transportowej i wewnętrzna struktura podsieci.
Zanim jednak zaczniemy objaśniać szczegóły działania warstwy sieciowej, warto chyba przypomnieć kontekst, w którym funkcjonują protokoły tej warstwy. Kontekst ten przedstawia rysunek 5.1. Główne składniki systemu to sprzęt należący do operatora (routery połączone liniami transmisyjnymi), Przedstawiony wewnątrz zacieniowanego owalu, oraz urządzenia klientów pokazane na zewnątrz owalu. Host H1 jest bezpośrednio połączony z jednym z routerów operatora (A) łączem dzierżawionym, natomiast H2 znajduje się w sieci lokalnej z routerem F, którego właścicielem i operatorem jest klient. Ten router również połączony jest linią dzierżawioną z siecią operatora. Pokazaliśmy F na zewnątrz owalu, ponieważ nie należy do operatora, lecz pod względem budowy, oprogramowania i protokołów Prawdopodobnie nie różni się od routerów operatora. Można dyskutować, czy należy do podsieci,
lecz na potrzeby niniejszego rozdziału routery mieszczące się u klienta będą uznawane za element podsieci, ponieważ stosują te same algorytmy jak routery operatora (a właśnie algorytmami będziemy się zajmować przede wszystkim).
Host. który ma pakiet do przesłania, nadaje go do najbliższego routera: albo we własnej sieci lokalnej, albo przez łącze dwupunktowe do operatora. Pakiet jest tu przechowywany, dopóki nie dotrze w całości, aby można było zweryfikować sumę kontrolną. Następnie zostaje przekazany dalej do następnego routera na trasie, i tak dalej aż do hosta docelowego, gdzie zostaje doręczony. Jest to komutacja pakietów z buforowaniem (inaczej pamiętająco-wysyłająca).
Warstwa sieciowa świadczy na rzecz transportowej usługi na interfejsie pomiędzy tymi dwoma warstwami. Istotnym pytaniem jest, jakiego typu usługi warstwa sieciowa udostępnia transportowej? Usługi warstwy sieciowej zostały zaprojektowane z myślą o następujących celach:
Usługi powinny być niezależne od technologii routerów.
Warstwa transportowa powinna być izolowana od liczby, typu i topologii obecnych routerów.
Adresy sieciowe udostępniane warstwie transportowej powinny stosować jednolity plan numerowania, nawet na różnych końcach sieci lokalnych i rozległych.
Projektanci warstwy sieciowej, którym wyznacza się takie cele, mają ogromną swobodę w tworzeniu szczegółowych specyfikacji planowanych usług, oferowanych dla warstwy sieciowej. Swoboda ta nieraz prowadzi do zażartych bitew pomiędzy dwoma rywalizującymi obozami. Dyskusja toczy się wokół kwestii, czy warstwa sieciowa powinna świadczyć usługi połączeniowe czy bezpołączeniowe.
Jeden obóz (reprezentowany przez społeczność Internetu) argumentuje, że zadaniem routerów jest przenoszenie pakietów i nic więcej. Z ich punktu widzenia (opartego na 30 latach faktycznych doświadczeń z prawdziwymi, funkcjonującymi sieciami komputerowymi) podsieć jest z natury zawodna, niezależnie od konstrukcji. Wobec tego hosty powinny akceptować fakt, że sieć nie jest niezawodna i same zajmować się kontrolą błędów (czyli wykrywaniem i korekcją) oraz sterowaniem przepływem.
Taki punkt widzenia prowadzi wprost do konkluzji, że usługa sieciowa powinna być bezpołączeniowa, zawierać operacje elementarne wysyłania i odbioru pakietu (SEND PACKET i RECEIVE PACKET) i poza tym niewiele więcej. Przede wszystkim nie powinno odbywać się w niej porządkowanie pakietów i sterowanie przepływem, ponieważ hosty i tak się tym zajmują, a korzyści z dwukrotnego przeprowadzania tych operacji zwykle są znikome. Co więcej, każdy pakiet musi zawierać pełny adres docelowy, ponieważ jest przenoszony niezależnie od swoich ewentualnych poprzedników.
Drugi obóz (który reprezentują firmy telefoniczne) argumentuje, że podsieć powinna świadczyć niezawodne usługi połączeniowe. Firmy te twierdzą, że 100 lat pomyślnych doświadczeń z ogólnoświatowym systemem telefonii jest doskonałym dowodem. Z tej perspektywy jakość usług jest czynnikiem dominującym, a bez połączeń w podsieci bardzo trudno ją osiągnąć, zwłaszcza w ruchu w czasie rzeczywistym, zwłaszcza jeśli chodzi o głos i wideo.
Najlepszymi przykładami tych dwóch obozów są Internet i ATM. Internet oferuje w warstwie sieciowej usługę bezpołączeniową, ATM połączeniową. Warto jednak zauważyć, że w miarę wzrostu znaczenia gwarantowanej jakości usług Internet podlega ewolucji. Przede wszystkim zaczyna nabierać cech zwykle kojarzonych z usługami połączeniowymi, jak zobaczymy w dalszej części rozdziału.
Po przyjrzeniu się dwom klasom usług, jakie warstwa sieciowa może udostępniać swoim użytkownikom, pora zobaczyć, jak ta warstwa działa od środka. Możliwe są dwie odmienne metody organizacji, zależne od oferowanego typu usługi. Jeśli oferowana jest usługa bezpołączeniową, pakiety są wprowadzane do podsieci indywidualnie i kierowane niezależnie od siebie. Nie ma potrzeby uprzedniej konfiguracji połączenia. W tym kontekście pakiety często nazywa się datagramami (przez podobieństwo do telegramów), a podsieć nosi nazwę podsieci datagramowej. Jeśli używana jest usługa połączeniowa, przed wysłaniem jakichkolwiek pakietów musi zostać zestawiona trasa z routera źródłowego do docelowego. Połączenie takie to tzw. obwód wirtualny (VC — virtual circuit) i jest odpowiednikiem fizycznego obwodu tworzonego w systemie telefonicznym, a podsieć nosi nazwę podsieci obwodów wirtualnych. W tym punkcie opiszemy podsieci datagramowe; w następnym zajmiemy się podsieciami obwodów wirtualnych.
Spójrzmy teraz, jak działa podsieć datagramowa. Załóżmy, że proces P1 z rysunku 5.2 ma długą wiadomość dla P2. Proces przekazuje do warstwy transportowej wiadomość z instrukcją, aby została doręczona do procesu P2 w hoście H2. Kod warstwy transportowej działa w HI zwykle w obrębie systemu operacyjnego. Kod ten dołącza nagłówek transportowy z przodu wiadomości i przekazuje wynik do warstwy sieciowej, która jest zwykle inną procedurą systemu operacyjnego.
Załóżmy, że wiadomość jest czterokrotnie dłuższa od maksymalnej wielkości pakietu, więc warstwa sieciowa dzieli ją na cztery pakiety o numerach 1, 2, 3 i 4 i wysyła każdy kolejno do routera A za pomocą jakiegoś protokołu dwupunktowego, na przykład PPP. Teraz transmisję przejmuje operator. Każdy router ma wewnętrzną tablicę informującą, gdzie wysyłać pakiety dla każdego możliwego odbiorcy. Każdy wpis w tablicy jest parą złożoną z celu i prowadzącej do niego linii wyjściowej. Na przykład na rysunku 5.2 router A ma tylko dwie linie wyjściowe — do B i C więc każdy przychodzący pakiet musi zostać wysłany do jednego z tych routerów, nawet jeśli ostatecznym miejscem przeznaczenia jest jakiś inny router. Początkowa tablica tras routera A została na rysunku pokazana pod etykietą „początkowo".
Pakiety 1, 2 i 3 docierające do A były zapisywane na krótko (aby zweryfikować sumy kontrolne), a następnie każdy został przekazany dalej do C zgodnie z tablicą z routera A. Pakiet nr 1 został przekazany do E, a później do F. Gdy dotarł do F, został zapakowany w ramkę warstwy łącza danych i przesłany do H2 siecią lokalną. Pakiety 2 i 3 również podążyły tą trasą.
Jednakże z pakietem 4 wydarzyło się coś innego. Gdy dotarł do A, został przesłany do routera B, limo że również był przeznaczony dla F. Z jakiegoś powodu router A zdecydował, aby wysłać pakiet nr 4 inną trasą niż trzy pozostałe. Być może dowiedział się o „korku ulicznym" gdzieś na trasie ICE i zaktualizował swoją tablicę tras, jak na rysunku pod etykietą „później". Algorytm zarządzający tablicami i podejmujący decyzje o wyborze tras nosi nazwę algorytmu routingu lub algorytmu wyznaczania tras. Algorytmy routingu są jedną z głównych rzeczy, którymi zajmiemy się w tym rozdziale.
Dla usług połączeniowych potrzebujemy podsieci obwodów wirtualnych. Zobaczmy, jak to działa. obwody wirtualne są używane, aby unikać wybierania nowej trasy dla każdego wysyłanego pakietu, jak na rysunku 5.2. Zamiast tego po nawiązaniu połączenia trasa od komputera źródłowego do docelowego zostaje wybrana w ramach konfiguracji połączenia i zapisana w tablicach w routerach. Trasa ta jest używana przez cały ruch odbywający się w połączeniu, dokładnie tak samo jak działa system telefoniczny. W usłudze połączeniowej każdy pakiet zawiera identyfikator mówiący, do którego obwodu wirtualnego należy.
Weźmy na przykład sytuację z rysunku 5.3. Tutaj host H1 nawiązał połączenie nr 1 z hostem H2. jest ono pamiętane jako pierwszy wpis w każdej tablicy routingu. Pierwszy wiersz tablicy w routerze 1 mówi, że jeśli pakiet zawierający identyfikator połączenia pierwszego przyjdzie do niego z H1, to powinien zostać przesłany do routera C i otrzymać identyfikator połączenia 1. Pierwszy wpis w C podobnie kieruje pakiet do E, również z identyfikatorem połączenia 1.
Zobaczmy teraz, co stanie się, jeśli H3 również chce nawiązać połączenie z H2. H3 wybiera identyfikator połączenia nr 1 (ponieważ to on inicjalizuje połączenie i jest to jedyne połączenie tego hosta) i żąda od podsieci utworzenia obwodu wirtualnego. Powoduje to utworzenie drugiego wiersza w tablicach. Mamy tutaj konflikt: chociaż A może z łatwością odróżnić pakiety połączenia nr 1 z HI od pakietów połączenia nr 1 z H3, lecz C nie potrafi tego zrobić. Dlatego A przydziela inny identyfikator połączenia ruchowi wychodzącemu dla drugiego połączenia. Właśnie aby unikać konfliktów tego typu, routery muszą zastępować identyfikatory połączenia w pakietach wychodzących. W niektórych kontekstach działanie takie nosi nazwę „etykietowanie" lub „przełączanie etykiet".
Zarówno obwody wirtualne, jak i datagramy mają swoich zwolenników i przeciwników. Spróbujemy teraz zestawić argumenty przemawiające za obydwoma technikami. Główne zagadnienia zostały przedstawione w tabeli 5.1, aczkolwiek puryści pewnie znajdą kontrprzykłady dla każdej pozycji.
Wewnątrz podsieci pomiędzy obwodami wirtualnymi i datagramami występuje kilka kompromisów. Jeden z nich dotyczy miejsca w pamięci routerów i przepustowości. Obwody wirtualne pozwalają zapisywać w pakietach krótkie numery obwodów zamiast pełnych adresów docelowych. Jeśli pakiety są zwykle dość krótkie, pełny adres docelowy w pakiecie może stanowić spory odsetek informacji dodatkowych, przez co marnuje pasmo. Ceną płaconą za używanie obwodów wirtualnych jest miejsce w tablicach routerów. Zależnie od proporcji kosztów obwodów komunikacyjnych i pamięci routerów pierwsza lub druga metoda może być tańsza.
Kolejny kompromis występuje pomiędzy czasem nawiązywania połączenia i czasem analizy adresu. Korzystanie z obwodów wirtualnych wymaga fazy konfiguracji, która zajmuje czas i zasoby. Jednakże ustalenie, co należy zrobić z pakietem w podsieci obwodów wirtualnych, jest łatwe — router po prostu używa numerów obwodów do indeksowania tablicy i sprawdzania, gdzie idzie pakiet. W podsieci datagramowej do lokalizacji wpisu dla adresu docelowego potrzebna jest bardziej złożona procedura wyszukiwania.
Jeszcze jednym problemem jest objętość pamięci w routerach potrzebnej na tablice. Podsieć datagramowa potrzebuje wpisu dla każdego możliwego miejsca przeznaczenia, podczas gdy podsieć obwodów wirtualnych wymaga jedynie wpisu dla każdego VC. Ta zaleta jest jednak dość złudna, ponieważ pakiety konfigurujące połączenie również wymagają routingu i używają adresów docelowych tak samo jak datagramy.
Obwody wirtualne mają pewną przewagę w gwarantowaniu jakości usług i unikaniu przeciążeń w podsieci, ponieważ zasoby (bufory, pasmo przepustowości i czas procesora) można zarezerwować z góry, w chwili, gdy połączenie zostaje nawiązane. Gdy pakiety zaczną przychodzić, niezbędne pasmo i moce przerobowe routera są już dostępne. W podsieci datagramów unikanie przeciążeń jest trudniejsze.
W systemach przetwarzania transakcyjnego (np. w sklepach zdalnie weryfikujących zakupy kartą kredytową) dodatkowe obciążenie potrzebne do utworzenia i usunięcia obwodu wirtualnego może z łatwością zdominować faktyczne wykorzystanie obwodu. Jeśli większość spodziewanego ruchu ma być tego typu, użycie obwodów wirtualnych nie ma większego sensu. Z drugiej strony tutaj mogą przydać się trwałe obwody wirtualne, tworzone ręcznie i użytkowane przez miesiące lub lata.
Obwody wirtualne mają też problemy z wrażliwością na awarie. Gdy router padnie i utraci zawartość pamięci, to nawet jeśli za kilka sekund znowu zacznie działać, wszystkie obwody wirtualne przechodzące przezeń zostaną zerwane. Z drugiej strony na awarii routera datagramów ucierpią tylko ci użytkownicy, których pakiety były w danej chwili kolejkowane w routerze, i to może nawet nie wszyscy, zależnie od tego, czy pakiety zostały już potwierdzone. Utrata linii komunikacyjnej jest fatalna w skutkach dla używających jej obwodów wirtualnych, lecz może być z łatwością zrekompensowana, jeśli używane są datagramy. Poza tym datagramy pozwalają routerom równoważyć ruch w podsieci, ponieważ trasy można zmieniać w trakcie trwania długich sekwencji przesyłanych pakietów.
Główną funkcją warstwy sieciowej jest przesyłanie pakietów z komputera sieciowego do docelowego. W większości podsieci pakiety do ukończenia podróży wymagają wielu przeskoków. Jedynym godnym uwagi wyjątkiem są sieci rozgłoszeniowe, lecz nawet w nich routing jest pewnym problemem, jeśli nadawca i odbiorca nie znajdują się w tej samej sieci. Algorytmy wybierające trasy i używane przez nie struktury danych są ważnym obszarem projektowania sieci.
Algorytm routingu to ta część oprogramowania warstwy sieciowej, która odpowiada za decydowanie, do której linii wyjściowej powinien zostać przekazany przychodzący pakiet. Jeśli podsieć wewnętrznie używa datagramów, to decyzję tę trzeba podejmować na nowo dla każdego przychodzącego pakietu danych, ponieważ od ostatniego razu najlepsza trasa mogła się zmienić. Jeśli podsieć wewnętrznie używa obwodów wirtualnych, decyzje o wyborze trasy są podejmowane tylko w chwili tworzenia nowego obwodu wirtualnego. Wobec tego pakiety danych po prostu kierują się z góry ustaloną trasą. Drugi przypadek nazywany jest czasem routingiem sesji, ponieważ jedna trasa obowiązuje dla całej sesji użytkownika (np. sesji logowania do terminala lub przesyłu plików).
Warto odróżnić routing, który polega na podejmowaniu decyzji o tym, której trasy użyć, od przekazywania (ang. forwarding) występującego przy nadejściu pakietu. Możemy sobie wyobrazić, że w routerze działają dwa procesy. Jeden obsługuje każdy przychodzący pakiet, szukając dla niego w tablicach routingu linii wyjściowej. Ten proces to przekazywanie. Drugi proces odpowiada za wypełnianie i aktualizację tablic routingu. Tutaj pojawiają się algorytmy routingu.
Bez względu na to, czy trasy są wybierane niezależnie dla każdego pakietu czy tylko przy nawiązywaniu połączeń, od algorytmu routingu oczekuje się pewnych właściwości: poprawności, prostoty, odporności, stabilności, sprawiedliwości i optymalności. Poprawność i prostota raczej nie wymagają komentarzy, lecz potrzeba odporności może być na pierwszy rzut oka mniej oczywista. Po wprowadzeniu do eksploatacji ważnej sieci możemy oczekiwać, że będzie działać nieprzerwanie przez lata, bez awarii na skalę całego systemu. W tym okresie na pewno wystąpią jakieś awarie sprzętu i oprogramowania. Hosty, routery i linie będą co jakiś czas zawodzić, a topologia może się zmienić wielokrotnie. Algorytm routingu powinien poradzić sobie ze zmianami w topologii i ruchu bez żądania przerwania wszystkich zadań we wszystkich hostach i restartu sieci za każdym razem, gdy jakiś router przestanie działać.
Stabilność również jest ważnym wyznacznikiem algorytmu routingu. Istnieją algorytmy routingu, które nigdy nie zbiegają się do stanu ustalonego, niezależne od tego, jak długo pracują. Stabilny algorytm dochodzi do stanu ustalonego i pozostaje w nim. Sprawiedliwość i optymalność mogą wydawać się oczywiste — nikt chyba nie zaprotestuje przeciwko tym postulatom — lecz, jak się okazuje, są to często cele sprzeczne ze sobą. Prosty przykład tego konfliktu pokaże rysunek 5.4. Załóżmy, że pomiędzy A i A', pomiędzy B i B' oraz pomiędzy C i C’ występuje ruch wystarczający, aby nasycić poziome odcinki łączy. Aby zmaksymalizować całkowitą zdolność przepustową systemu, należałoby całkowicie zablokować ruch pomiędzy X i X’. Niestety, X i X' mogą mieć na ten temat odmienne zdanie. Najwyraźniej potrzebny jest jakiś kompromis pomiędzy wydajnością i sprawiedliwością poszczególnych połączeń.
RYSUNEK 5.4. Konflikt pomiędzy sprawiedliwością i optymalnością
Zanim w ogóle spróbujemy znaleźć kompromis pomiędzy sprawiedliwością i optymalnością, musimy zdecydować, co chcemy optymalizować. Oczywistym kandydatem może być minimalizacja średniego opóźnienia pakietu, ale też i maksymalizacja całkowitej zdolności przepustowej sieci.
Co gorsza, te dwa cele również kolidują ze sobą, ponieważ eksploatacja każdego systemu kolejkującego z wydajnością
zbliżoną do maksymalnej wprowadza duże opóźnienia kolejkowania. W wielu sieciach kompromis polega na minimalizacji przeskoków, jakie musi wykonać pakiet, ponieważ pozwala to zredukować opóźnienie, a jednocześnie zmniejsza zużycie pasma, co zwykle poprawia również zdolność przepustową.
Algorytmy routingu można podzielić na dwie główne klasy: adaptacyjne i nieadaptacyjne. Algorytmy nieadaptacyjne nie opierają swoich decyzji o wyborze tras na pomiarach i szacunkach bieżącego ruchu i topologii. Zamiast tego wybór trasy od I do J (dla każdego I i J) jest wyliczany z góry, offline, i informacje są ładowane do routerów przy starcie sieci. Taka procedura czasem nazywana jest routingiem statycznym.
Z drugiej strony algorytmy adaptacyjne zmieniają decyzje o trasach zależnie od zmian w topologii sieci, a zwykle także w zależności od ruchu w sieci. Algorytmy adaptacyjne różnią się tym, skąd pobierają informacje (np. z routerów sąsiednich lub wszystkich), kiedy zmieniają trasy (np. co Δt sekund, po zmianie obciążenia lub po zmianie topologii), oraz parametrami używanymi do optymalizacji (np. odległość, liczba przeskoków lub szacowany czas podróży). W poniższych punktach omówimy szereg różnych algorytmów routingu. zarówno statycznych, jak i dynamicznych.
Zanim przejdziemy do konkretnych algorytmów, warto zauważyć, że możemy zdefiniować ogólne twierdzenie o trasach optymalnych bez odnoszenia się do topologii lub obciążenia sieci. Twierdzenie to znane jest pod nazwą zasady optymalności i mówi, że jeśli router J znajduje się na optymalnej trasie od routera I do routera K, to optymalna ścieżka od J do K przebiega tą samą trasą. Aby to pokazać, oznaczymy część trasy od I do J przez r1 a resztę trasy jako r2. Gdyby istniała trasa lepsza niż r2 od J do K, to mogłaby zostać konkatenowana z r1 aby ulepszyć trasę od I do K, co zaprzecza naszemu stwierdzeniu, że r1r2 jest trasą optymalną.
Z zasady optymalności wynika wprost, że zbiór optymalnych tras z wszystkich źródeł do jednego celu tworzy drzewo z korzeniem w węźle docelowym. Drzewo takie, zwane drzewem ujścia, zostało przedstawione na rysunku 5.5, na którym metryką odległości jest liczba przeskoków. Zwróćmy uwagę, że drzewo ujścia nie musi być unikatowe; mogą istnieć inne drzewa z taką samą długością tras. Zadaniem wszystkich algorytmów routingu jest wykrycie i używanie drzew ujścia dla wszystkich routerów.
Ponieważ drzewo ujścia jest istotnie drzewem, to nie zawiera żadnych pętli, więc każdy pakiet zostanie doręczony w skończonej i ograniczonej liczbie przeskoków. W praktyce życie nie jest aż tak lekkie. Łącza i routery mogą zawodzić i wracać do działania w trakcie eksploatacji, więc różne routery mogą mieć inne obrazy bieżącej topologii. Poza tym po cichu ominęliśmy pytanie, czy każdy router musi indywidualnie zdobywać informacje, na których opiera swoje drzewo ujścia, czy też informacje te są gromadzone w jakiś inny sposób. Do tych zagadnień wrócimy za chwilę. Tak czy owak zasada optymalności i drzewo ujścia stanowią wzorzec, do którego mogą być przyrównywane inne algorytmy routingu.
Zacznijmy analizę nadających się do użycia algorytmów routingu od techniki, która jest używana powszechnie i w wielu formach z uwagi na swoją prostotę i zrozumiałość. Pomysł polega na zbudowaniu grafu podsieci, w którym każdy węzeł reprezentuje router, a każdy łuk linię komunikacyjną (łącze). Aby wybrać trasę pomiędzy daną parą routerów, algorytm znajduje po prostu w grafie najkrótszą ścieżkę pomiędzy nimi.
Idea najkrótszej ścieżki zasługuje na wyjaśnienie. Jednym ze sposobów pomiaru długości ścieżki jest liczenie przeskoków. Przy użyciu tej miary ścieżki ABC i ABE z rysunku 5.6 mają jednakową długość. Inną miarą może być odległość w kilometrach — w tym przypadku ścieżka ABC będzie wyraźnie o wiele dłuższa od ABE (zakładając, że rysunek jest proporcjonalny).
Możliwych jest też jednak wiele innych miar poza przeskokami i odległością fizyczną. Na przykład każdy łuk może być opisany przez średnie opóźnienia kolejkowania i transmisji dla jakiegoś standardowego pakietu testowego, ustalane przez cogodzinne testy. Przy takim oznaczaniu grafu najkrótszą ścieżką jest ścieżka najszybsza, a nie taka, która ma najmniej przeskoków lub kilometrów.
W ogólnym przypadku etykiety łuków mogą być obliczane jako funkcja odległości, przepustowości, średniego obciążenia, kosztów połączenia, średniej długości kolejki, zmierzonego opóźnienia i innych czynników. Zmieniając funkcję ważącą algorytm może obliczać „najkrótszą" ścieżkę mierzoną na podstawie dowolnego kryterium lub kombinacji kryteriów.
Istnieje kilka algorytmów obliczających najkrótszą ścieżkę pomiędzy dwoma węzłami grafu. Autorem algorytmu z rysunku 5.6 jest Dijkstra (1959). Każdy węzeł jest oznaczany (w nawiasach) odległością od węzła źródłowego wzdłuż najlepszej znanej ścieżki. Początkowo nie są znane żadne ścieżki, więc wszystkie węzły są oznaczone symbolem nieskończoności. W miarę postępów algorytmu
1 znajdowania nowych ścieżek etykiety mogą się zmieniać, odzwierciedlając lepsze ścieżki. Etykieta może być tymczasowa lub trwała. Początkowo wszystkie etykiety są tymczasowe. Gdy zostanie odkryte, że etykieta reprezentuje najkrótszą możliwą ścieżkę, to staje się trwała i od tej pory nie jest zmieniana.
Aby zilustrować, jak działa algorytm nadawania etykiet, spójrzmy na graf ważony nieskierowany z rysunku 5.6 (a), na którym wagi oznaczają na przykład odległości. Chcemy znaleźć najkrótszą ścieżkę z A do D. Zaczynamy od oznaczenia wypełnionym kółkiem węzła A (roboczego) jako trwałego. Następnie sprawdzamy kolejno każdy z węzłów sąsiadujący z A, oznaczając każdy odległością do A. Za każdym razem, gdy zostaje zmieniona etykieta węzła, oznaczamy ją też węzłem,
2 którego próba została przeprowadzona, aby można było później zrekonstruować ostateczną ścieżkę. Po sprawdzeniu wszystkich węzłów sąsiadujących z A sprawdzamy wszystkie oznaczone tymczasowo węzły w całym grafie i ten, którego etykieta ma najniższą wartość, oznaczamy jako trwały, jak na rysunku 5.6 (b). Staje się on nowym węzłem roboczym.
Teraz zaczynamy od B i sprawdzamy wszystkie sąsiadujące z nim węzły. Jeśli suma etykiety B i odległości pomiędzy B i sprawdzanym węzłem jest niższa niż etykieta tego węzła, to znaleźliśmy krótszą ścieżkę, więc węzeł otrzymuje nową etykietę.
Po sprawdzeniu wszystkich węzłów sąsiadujących z roboczym i, jeśli to możliwe, zmianie etykiet, cały graf jest sprawdzany w poszukiwaniu węzła oznakowanego tymczasowo o najniższej wartości. Węzeł ten zostaje trwały i staje się węzłem roboczym dla następnej rundy. Rysunek 5.6 przedstawia pierwsze pięć kroków algorytmu.
Aby zobaczyć, dlaczego ten algorytm daje właściwe wyniki, spójrzmy na rysunek 5.6 (c). Właśnie oznaczyliśmy £jako trwały. Załóżmy, że jest jakaś ścieżka do niego krótsza niż ABE, na przykład 4XYZE. Są teraz dwie możliwości: albo Z został już ustawiony jako trwały, albo nie. Jeśli tak, to E był już sprawdzany (w rundzie po tej, w której Z został oznaczony jako trwały), więc ścieżka AXYZE nie umknęła naszej uwadze i nie może być krótsza.
Rozważmy teraz przypadek, w którym Z nadal pozostaje oznaczony tymczasowo. Albo etykieta w Z ma wartość wyższą lub równą tej z E, więc AXYZE nie może być ścieżką krótszą niż ABE, albo jest krótsza od E, lecz w tym przypadku Z, a nie E, jako pierwszy stanie się trwały, co pozwoli na sprawdzenie E z Z.
Cały algorytm przedstawia listing 5.1. Zmienne globalne n i dist opisują graf i są inicjalizowane przed wywołaniem shortest_path. Jedyna różnica pomiędzy programem i algorytmem opisanym powyżej polega na tym, że w listingu 5.1 obliczamy, zaczynając od węzła końcowego t zamiast źródłowego s. Ponieważ w grafie nieskierowanym najkrótsza ścieżka od s do t jest taka sama jak od t do s, więc nie jest ważne, od którego końca zaczniemy (o ile nie istnieje kilka najkrótszych, ścieżek; w tym przypadku odwrócenie wyszukiwania może wykryć inną). Wyszukiwanie odbywał
się wstecz, ponieważ każdy węzeł jest oznaczony swoim poprzednikiem, a nie następcą. Po skopiowaniu ostatecznej ścieżki do zmiennej wyjściowej path ścieżka zostaje w ten sposób odwrócona. Odwrócenie wyszukiwania powoduje, że te dwa efekty znoszą się wzajemnie i wynik zostaje podany we właściwej kolejności.
Kolejnym statycznym algorytmem jest routing rozpływowy (ang. flooding), w którym każdy przychodzący pakiet jest wysyłany na każdą linię wyjściową z wyjątkiem tej, na której przyszedł. Trasowanie rozpływowe oczywiście generuje ogromną liczbę powtarzających się pakietów, teoretycznie nieskończoną, o ile nie zostaną podjęte jakieś kroki w stronę wytłumienia procesu. Jednym z takich kroków jest zawarcie w nagłówku każdego pakietu licznika przeskoków zmniejszanego o jeden przy każdym przeskoku. Pakiet zostaje odrzucony, gdy licznik dojdzie do zera. W idealnych warunkach licznik przeskoków powinien zostać inicjowany z wartością równą długości ścieżki od źródła do celu. Jeśli nadawca nie zna długości trasy, może wpisać do licznika wartość dla najbardziej niekorzystnego przypadku — pełną średnicę sieci.
Alternatywną techniką tamowania rozpływu jest rejestrowanie, które pakiety zostały rozesłane, aby unikać wysyłania ich po raz drugi. Jedną z metod osiągnięcia tego celu jest umieszczenie przez źródłowy router numeru sekwencyjnego w każdym pakiecie, który odbiera od swoich ho-stów. Każdy router potrzebuje wtedy listy dla każdego routera źródłowego informującej, które numery sekwencyjne pochodzące z tego źródła były już widziane. Jeśli przychodzący pakiet znajduje się na liście, nie zostaje rozesłany.
Aby zapobiec nieograniczonemu rozrastaniu się listy, każda lista powinna być uzupełniona o licznik k, która oznacza, że wszystkie numery sekwencyjne aż do k były już widziane. Gdy przychodzi pakiet, łatwo jest sprawdzić, czy jest duplikatem; jeśli tak, zostaje odrzucony. Co więcej, pełna lista poniżej k nie jest potrzebna, ponieważ podsumowuje ją wartość k.
Nieco bardziej praktyczną odmianą tego algorytmu jest selektywny routing rozpływowy. W nim routery nie wysyłają każdego przychodzącego pakietu na wszystkie linie, lecz jedynie te, które zdążają mniej więcej we właściwym kierunku. Zwykle nie ma większego sensu wysyłać pakiet kierujący się na zachód linią skierowaną na wschód, o ile topologia nie jest wyjątkowo nietypowa i router jest świadom tego faktu.
Routing rozpływowy nie we wszystkich sytuacjach jest praktyczny, lecz ma swoje zastosowania. Na przykład w zastosowaniach wojskowych, gdzie duża liczba routerów może w każdej chwili zostać wysadzona w powietrze, wyjątkowa odporność tego algorytmu jest bardzo cenna. W aplikacjach rozproszonych baz danych czasem konieczne jest jednoczesne zaktualizowanie wszystkich baz danych, więc tu routing rozpływowy może się przydać. W sieciach bezprzewodowych wszystkie wiadomości nadawane przez stację mogą być odbierane przez wszystkie pozostałe stacje w zasięgu nadajnika, co w istocie jest podobnym mechanizmem, więc niektóre algorytmy wykorzystują tę właściwość. Czwartą możliwością zastosowania jest wzorzec, z którym można porównywać wszystkie pozostałe algorytmy. Routing rozpływowy zawsze znajduje najkrótszą trasę, ponieważ wybiera wszystkie możliwe równoległe trasy. Żaden inny algorytm nie daje więc krótszego opóźnienia (o ile zignorujemy dodatkowe obciążenie sieci wygenerowane przez proces zalewania).
Współczesne sieci komputerowe zwykle wykorzystują dynamiczne algorytmy routingu zamiast statycznych, opisanych powyżej, ponieważ algorytmy statyczne nie biorą pod uwagę aktualnego obnażenia sieci. Najpopularniejsze są zwłaszcza dwa dynamiczne algorytmy: wektorów odległości distance vector routing) oraz stanu połączeń (link state routing). W tym punkcie opiszemy ) pierwszy algorytm, a w następnym punkcie drugi.
Algorytmy routingu za pomocą wektorów odległości wykorzystują tablicę (czyli wektor) utrzymywaną przez każdy router i podającą najlepsze znane odległości do każdego celu oraz linie służące do dotarcia do celów. Tablice te są aktualizowane przez wymianę informacji pomiędzy sąsiadami.
Algorytm routingu z użyciem wektorów odległości jest również znany pod innymi nazwami, najczęściej rozproszonego algorytmu routingu Bellmana-Forda oraz algorytmu Forda-Fulkersona od nazwisk autorów (Bellman, 1957, oraz Ford i Fulkerson, 1962). Był to pierwotny algorytm routingu w sieci ARPANET, używany również w Internecie pod nazwą R1P.
W tym algorytmie każdy router utrzymuje tablicę routingu indeksowaną po każdym routerze w podsieci i zawierającą po jednym wpisie na router. Wpis ten składa się z dwóch części: preferowanej linii wyjściowej, która ma być użyta dla danego celu, i szacowanego czasu lub odległości do niego. Używaną metryką może być liczba przeskoków, opóźnienie w milisekundach, całkowita liczba pakietów kolejkowanych na trasie lub coś podobnego.
Zakłada się, że router zna „odległość" od każdego swojego sąsiada. Jeśli miarą są przeskoki, odległość wynosi jeden przeskok. Jeśli długość kolejki, to router po prostu sprawdza własną kolejkę. Jeśli miarą jest opóźnienie, router może zmierzyć je bezpośrednio, używając specjalnych pakietów ECHO, do których odbiornik dołącza znacznik czasowy i odsyła tak szybko, jak potrafi.
Załóżmy na przykład, że stosowaną metryką jest opóźnienie i że router zna opóźnienie do każdego ze swoich sąsiadów. Co T milisekund każdy router wysyła do każdego swojego sąsiada szacunkową listę opóźnień do każdego celu. Otrzymuje też od każdego sąsiada podobną listę. Wyobraźmy sobie, że jedna z tych tablic pochodzi od sąsiada X i zawiera X, — szacunkową wartość czasu potrzebną do dotarcia do routera i. Jeśli nasz router wie, że opóźnienie do X wynosi m milisekund, to wie również, że może dotrzeć do routera i poprzez X w X, + m milisekund. Przeprowadzając te obliczenia dla każdego sąsiada, router może ustalić, która wartość szacunkowa będzie najlepsza i użyje tej wartości oraz odpowiadającej jej linii wyjściowej w swojej tablicy routingu. Zwróćmy uwagę, że stara tablica routingu nie została użyta w tych obliczeniach.
Rysunek 5.7.
Podsieć.
Dane od A, I, H
i K oraz nowa tablica routingu I
Proces aktualizacji przedstawia rysunek 5.7. Część (a) pokazuje podsieć. Pierwsze cztery kolumny części (b) zawierają wektory opóźnień odebrane od sąsiadów routera J. A informuje, że ma opóźnienie 12 ms do 5, 25 ms do C, 40 ms do D i tak dalej. Załóżmy, że J zmierzył lub oszacował opóźnienia do swoich sąsiadów A, I, Hi K, wynoszące odpowiednio 8, 10, 12 i 6 milisekund. Zobaczmy, jak J tworzy swoją nową trasę do routera G. Wie, że może dotrzeć do A w 8 milisekund, zaś A twierdzi, że może dostać się do G w 18 ms, więc J wie, że może liczyć na opóźnienie do G rzędu 26 ms, jeśli przekaże dalej pakiety przeznaczone dla G przez router A. Analogicznie oblicza opóźnienia do G poprzez I, H i K jako odpowiednio 41 (31 + 10), 18 (6 + 12) i 37 (31 + 6) milisekund. Najlepsza z tych wartości to 18, więc J tworzy w swojej tablicy routingu wpis informujący, że opóźnienie do G wynosi 18 ms i że trasa powinna przebiegać przez H. Takie same obliczenia przeprowadza dla wszystkich pozostałych miejsc docelowych, a nowa tablica routingu została pokazana w ostatniej kolumnie rysunku.
Routing za pomocą wektorów odległości teoretycznie działa, lecz w praktyce ma poważną wadę — wprawdzie zbliża się do poprawnej odpowiedzi, ale może to robić powoli. Dokładniej mówiąc, reaguje szybko na dobre wiadomości, lecz leniwie na złe. Weźmy na przykład router, którego najlepsza trasa do X jest długa. Jeśli przy następnej wymianie informacji sąsiad A nagle zgłosi, że ma małe opóźnienie do X, router po prostu zacznie używać linii prowadzącej do A, aby wysyłać dane do X. Dobra wiadomość została przetworzona w jednej wymianie wektorów.
Aby zobaczyć, jak szybko propagują się dobre wieści, rozważmy pięciowęzłową podsieć (liniową) z rysunku 5.8, w której metryką jest liczba przeskoków. Załóżmy, że A początkowo nie działa i że inne routery wiedzą o tym. Inaczej mówiąc, wszystkie zapisały opóźnienie do A jako nieskończone.
RYSUNEK 5.8. Problem naliczania do nieskończoności
Gdy A zaczyna działać, inne routery dowiadują się o tym przez wymianę wektorów. Dla uproszczenia przyjmiemy, że gdzieś w sieci jest gigantyczny gong, którego uderzenia okresowo inicjują wymianę wektorów równocześnie przez wszystkie routery. W pierwszej wymianie B dowiaduje się, że jego lewy sąsiad ma zerowe opóźnienie do A. Wobec tego B wprowadza w swojej tablicy routingu wpis mówiący, że A znajduje się o jeden przeskok w lewo. Wszystkie pozostałe routery wciąż uznają, że A nie działa. Wpisy w tablicach routingu dla A w tej chwili przedstawia drugi wiersz rysunku 5.8 (a). W następnej wymianie C dowiaduje się, że B ma trasę o długości 1 do A, więc aktualizuje swoją tablicę routingu, wpisując do niej ścieżkę o długości 2, lecz D i £ jeszcze nie otrzymują dobrej wieści (dopiero później). Jak widać, dobre nowiny rozchodzą się z szybkością jednego przeskoku na wymianę. W podsieci, której najdłuższa ścieżka ma N przeskoków, po N wymian wszystkie routery wiedzą o włączonych właśnie do eksploatacji łączach i routerach.
Zajmijmy się teraz sytuacją z rysunku 5.8 (b), na którym wszystkie linie i routery początkowo są na chodzie. Routery B, C, D i E mają do A odległości równe odpowiednio 1, 2, 3 i 4. Nagle A przestaje działać lub zostaje przecięta linia pomiędzy A i B (co z punktu widzenia routera B jest jednym i tym samym).
W pierwszej wymianie pakietów B nie otrzymuje żadnej wiadomości od A. Na szczęście C mówi: ..Nie martw się, mam do A trasę o długości 2". B nie ma pojęcia, że trasa routera C biegnie przez B. Z punktu widzenia B router C równie dobrze może mieć dziesięć osobnych linii do A, o długości 2 przeskoków każda. Dlatego B wydaje się, że może dotrzeć do A poprzez C ze ścieżką o długości 3. W pierwszej wymianie D i E nie aktualizują swoich wpisów dotyczących A.
W drugiej wymianie C zauważa, że oba sąsiadujące routery twierdzą iż mają do A ścieżkę o długości 3. C wybiera losowo jedną z nich i notuje dla siebie nową odległość do A równą 4, jak w trzecim wierszu rysunku 5.8 (b). Kolejne wymiany tworzą historię widoczną w dalszej części rysunku.
Teraz powinno być jasne, dlaczego złe wieści rozchodzą się powoli — żaden router nie ma nigdy wartości wyższej o więcej niż jeden od minimalnych zgłoszonych przez sąsiadów. Stopniowo wszystkie routery dążą do nieskończoności, lecz liczba wymaganych wymian zależy od wartości liczbowej używanej do oznaczenia nieskończoności. Z tego powodu rozsądnie jest zdefiniować nieskończoność jako najdłuższą trasę plus 1. Jeśli metryką jest opóźnienie czasowe, to nie istnieje ściśle określona górna granica, potrzebna jest więc wysoka wartość, aby zapobiec traktowaniu ścieżki z długim opóźnieniem jako nieczynnej. Nie stanowi specjalnej niespodzianki fakt, że ten problem znany jest pod nazwą problemu naliczania do nieskończoności. Pojawiło się kilka prób rozwiązania go (na przykład dzielenie horyzontu z zatruwaniem wstecznym z RFC 1058), lecz żadna z nich ogólnie nie działa zbyt dobrze. Sednem problemu jest to, że jeśli X mówi Y, iż ma dokądś ścieżkę, Y nie może w żaden sposób ustalić, czy sam nie jest elementem tej ścieżki.
Routing z użyciem wektorów odległości był używany w sieci ARPANET do roku 1979, gdy został zastąpiony routingiem z użyciem stanów połączeń. Jego odejście spowodowały dwa podstawowe problemy. Po pierwsze, ponieważ miarą opóźnienia była długość kolejki, to przy wybieraniu tras nie brał pod uwagę przepustowości łączy. Początkowo wszystkie linie miały 56 kb/s, więc szybkości łącza nie trzeba było uwzględniać, lecz po zmodernizowaniu części z nich do 230 kb/s, a innych do 1544 Mb/s pomijanie przepustowości stało się poważnym problemem. Oczywiście możliwa byłaby zmiana miary opóźnień tak, by brała pod uwagę pasmo, lecz istniał jeszcze drugi problem — zbieżność algorytmu często była zbyt powolna (problem naliczania do nieskończoności). Z tych powodów algorytm został zastąpiony zupełnie nowym, zwanym routingiem z użyciem stanów połączeń (link state routing). Obecnie stosowane są powszechnie odmiany tego algorytmu.
Idea routingu z użyciem stanów połączeń jest prosta i możemy ją przedstawić w pięciu częściach. Każdy router musi:
Odkryć swoich sąsiadów i poznać ich adresy sieciowe.
Zmierzyć opóźnienie lub koszt połączenia z każdym ze swoich sąsiadów.
Utworzyć pakiet zawierający wszystko, czego się nauczył.
Wysłać ten pakiet do wszystkich innych routerów.
Ustalić najkrótszą trasę do każdego innego routera.
W wyniku tego cała topologia i wszystkie opóźnienia są mierzone doświadczalnie i dystrybuowane do każdego routera. Następnie do znalezienia najkrótszej trasy do każdego routera może zostać użyty algorytm Dijkstry. Poniżej omówimy bardziej szczegółowo każdy z tych pięciu kroków.
Po uruchomieniu routera jego pierwszym zadaniem jest dowiedzenie się o wszystkich sąsiadach. Router osiąga ten cel, wysyłając specjalny pakiet HELLO do każdej linii dwupunktowej. Router na drugim końcu linii powinien odesłać identyfikującą go odpowiedź. Nazwy routerów muszą być globalnie unikatowe, ponieważ gdy odległy router dowiaduje się, że do F są podłączone trzy routery, to musi być w stanie ustalić, że wszystkie trzy mają na myśli ten sam F.
Gdy dwa lub więcej routerów łączy sieć lokalna, sytuacja staje się nieco bardziej skomplikowana. Rysunek 5.9 ilustruje LAN, z którą połączone są bezpośrednio trzy routery, A, C i F. Każdy z tych routerów jest, jak widać, połączony z jednym lub więcej kolejnych routerów.
RYSUNEK 5.9. (a) Dziewięć routerów i sieć lokalna, (b) Graf modelujący strukturę (a)
Sieć LAN możemy zamodelować na przykład jako osobny węzeł, jak na rysunku 5.9 (b). Wprowadziliśmy na nim nowy sztuczny węzeł N, z którym łączą się A, C i F. Fakt, że można przejść z A do C siecią lokalną, jest tu reprezentowany przez połączenie ANC.
Algorytm stanu połączeń wymaga od każdego routera znajomości, a przynajmniej rozsądnego przybliżenia opóźnień do wszystkich sąsiadów. Najbardziej bezpośrednim sposobem ustalenia tego opóźnienia jest wysłanie łączem specjalnego pakietu ECHO, który druga strona jest zobowiązana natychmiast odesłać. Pomiar czasu podróży w obie strony i podzielenie go przez dwa pozwala nadającemu routerowi dość dokładnie oszacować opóźnienie. Dla jeszcze lepszych wyników ten test można przeprowadzić kilkakrotnie i użyć średniej. Oczywiście ta metoda milcząco zakłada, że opóźnienia są symetryczne, co nie zawsze musi być prawdą.
Warto zastanowić się, czy przy pomiarze opóźnienia należy brać pod uwagę obciążenie. Aby uwzględnić obciążenie, czasomierz transportu w obie strony powinien zostać uruchomiony w chwili umieszczenia pakietu ECHO w kolejce. Aby zignorować obciążenie, czasomierz powinien zostać uruchomiony, gdy pakiet ECHO dotrze do czoła kolejki.
Można przytaczać argumenty za obydwoma podejściami. Objęcie w pomiarach opóźnień spowodowanych obciążeniem linii oznacza, że gdy router ma wybór pomiędzy dwoma łączami o tej samej przepustowości i różnym obciążeniu, to wybierze mniej obciążoną trasę jako krótszą. Ten wybór pozwoli zwiększyć wydajność sieci.
Niestety, jest też argument przeciwko włączaniu obciążenia do obliczeń opóźnienia. Spójrzmy na podsieć z rysunku 5.10, podzieloną na dwie części — zachodnią i wschodnią— połączone dwoma liniami: CF i EI.
RYSUNEK 5.10. Podsieć, w której części zachodnia i wschodnia połączone są dwoma liniami
Załóżmy, że większość ruchu pomiędzy wschodem i zachodem odbywa się przez łącze CF, w wyniku czego linia ta jest mocno obciążona i wprowadza duże opóźnienia. Wliczenie opóźnień kolejkowania do obliczeń najkrótszej ścieżki spowoduje, że łącze EI stanie się bardziej atrakcyjne. Po zainstalowaniu nowych tablic routingu większość ruchu wschód-zachód pójdzie łączem EI, przeciążając tę linię. Wobec tego w następnej aktualizacji CF okaże się najkrótszą ścieżką. W wyniku tego tablice routingu mogą gwałtownie oscylować, prowadząc do chaotycznego routingu i wielu potencjalnych problemów. Jeśli zignorujemy obciążenie i będziemy brać pod uwagę tylko pasmo, ten problem nie wystąpi. Można alternatywnie podzielić obciążenie na obie linie, lecz takie rozwiązanie nie wykorzysta w pełni najlepszych ścieżek. Mimo to, aby uniknąć oscylacji w wyborze najlepszej ścieżki, rozsądnie byłoby podzielić obciążenie na kilka linii, z częścią ruchu przenoszoną przez każdą linię.
Podsieć.
Pakiety stanu połączeń dla tej podsieci
Po zebraniu informacji potrzebnych do wymiany następnym krokiem jest zbudowanie przez każdy router pakietu zawierającego wszystkie dane. Pakiet ten zaczyna się od tożsamości nadawcy, po której następuje numer sekwencyjny i wiek (który opiszemy później) oraz lista sąsiadów, z opóźnieniem podanym dla każdego sąsiada. Rysunek 5.11 (a) przedstawia przykładową podsieć z opóźnieniami podanymi w postaci etykiet łączy. Odpowiadające tej sieci pakiety stanu połączeń dla wszystkich sześciu routerów przedstawia rysunek 5.11 (b).
Tworzenie pakietów stanu połączeń jest proste. Trudniejszą sztuką jest decyzja, kiedy należy je konstruować. Jedną z możliwości jest tworzenie pakietów okresowo, to znaczy w regularnych odstępach czasu. Inna polega na budowaniu pakietów, gdy wystąpi jakieś znaczące zdarzenie, na Przykład awaria, przywrócenie do eksploatacji lub znacząca zmiana właściwości linii lub sąsiada.
W całym algorytmie najtrudniejszym zadaniem jest niezawodna dystrybucja pakietów stanu połączeń. W miarę dystrybucji i instalowania tych pakietów routery otrzymujące je jako pierwsze zmieniają swoje trasy. Wobec tego różne routery mogą używać różnych wersji topologii, co może prowadzić do niespójności, pętli, nieosiągalności komputerów i innych problemów.
Najpierw opiszemy podstawowy algorytm dystrybucji. Później dodamy kilka udoskonaleń. Podstawową ideą jest dystrybucja pakietów metodą rozpływu. Aby utrzymać rozpływ pod kontrolą, każdy pakiet zawiera numer sekwencyjny inkrementowany przy wysyłaniu każdego nowego pakietu. Routery rejestrują wszystkie pary (router źródłowy, numer sekwencyjny), które zobaczą. Gdy przychodzi nowy pakiet stanu połączeń, zostaje sprawdzony na liście widzianych już pakietów. Jeśli jest duplikatem, zostaje odrzucony. Jeśli dotrze pakiet o numerze sekwencyjnym niższym niż najwyższy spotkany do tej pory, to zostaje odrzucony jako przestarzały, ponieważ router ma już aktualniejsze dane.
Algorytm ten ma kilka wad, lecz można nad nimi zapanować. Po pierwsze, gdyby numery sekwencyjne się zawijały, zapanowałby chaos. Rozwiązaniem jest użycie 32-bitowego numeru sekwencyjnego. Przy jednym pakiecie stanu połączeń na sekundę na zawinięcie numeracji trzeba byłoby czekać 137 lat, więc tę możliwość da się zignorować.
Po drugie, padnięcie routera powoduje, że traci ciągłość numerów sekwencyjnych. Gdyby zaczął ponownie od 0, kolejny pakiet zostałby odrzucony jako duplikat.
Po trzecie, w przypadku uszkodzenia numeru sekwencyjnego takiego, że zostanie odebrana np. wartość 65 540 zamiast 4 (błąd na jednym bicie), to pakiety od 5 do 65 540 będą odrzucane jako nieaktualne, ponieważ za poprawny numer sekwencyjny zostanie uznany 65 540.
Rozwiązaniem wszystkich tych problemów jest zapisanie wieku pakietu zaraz po numerze sekwencyjnym i dekrementowanie go co sekundę Gdy wiek spadnie do zera, informacje z tego routera są odrzucane. Zwykle nowy pakiet przychodzi np. co 10 sekund, więc informacje routera ulegają przeterminowaniu tylko w przypadku, gdy dany router przestaje działać (lub w przypadku utraty sześciu pakietów pod rząd, co jest mało prawdopodobne). Pole Wiek jest również dekrementowane przez każdy router podczas początkowego procesu dystrybucji przez rozpływanie, aby zagwarantować, że żaden pakiet nie zgubi się i nie będzie istniał w nieskończoność (pakiet o wieku zero jest odrzucany).
Kilka usprawnień zwiększa odporność tego algorytmu. Gdy pakiet stanu łączy dociera do routera w celu rozpływu, nie jest natychmiast kolejkowany do transmisji. Zamiast tego zostaje na chwilę odłożony do obszaru przechowywania. Jeśli przed wysłaniem tego pakietu do routera dotrze kolejny pakiet stanu łączy z tego samego źródła, ich numery sekwencyjne są porównywane. Jeśli są równe, duplikat zostaje odrzucony. Jeśli się różnią, starszy jest wyrzucany. Aby zabezpieczyć się przed błędami na liniach między routerami, wszystkie pakiety stanu łączy są potwierdzane. Gdy linia przechodzi w stan bezczynności, obszar przechowywania jest skanowany w sposób cykliczny, aby wybrać pakiet lub potwierdzenie do wysłania.
Strukturę danych, używaną przez router B dla podsieci z rysunku 5.11 (a), przedstawia rysunek 5.12. Każdy wiersz odpowiada w nim pakietowi stanu, który niedawno przyszedł, lecz jeszcze nie został w pełni przetworzony. Tablica rejestruje pochodzenie pakietu, jego numer sekwencyjny i wiek oraz dane. Oprócz tego są tu znaczniki wysłania i potwierdzenia dla każdej z trzech linii routera B (do A, C i F). Znacznik wysłania oznacza, że pakiet musi zostać wysłany na wskazanej linii. Znacznik potwierdzenia oznacza, że musi zostać na niej potwierdzony.
Na rysunku 5.12 pakiet stanu łączy z A dociera bezpośrednio, więc musi zostać wysłany do C i F i potwierdzony do A, na co wskazują bity znaczników. Pakiet z F musi podobnie zostać przekazany dalej do A i C oraz potwierdzony na linii do F.
Sytuacja dla pakietu z £ jest inna. Pakiet ten przyszedł dwukrotnie, raz poprzez EAB i raz poprzez EFB. Wobec tego wystarczy, że zostanie przesłany do C, lecz potwierdzenie trzeba będzie wysłać do C i F, na co wskazują bity znaczników.
Jeśli duplikat dotrze, gdy oryginał jeszcze będzie przechowywany w buforze, trzeba będzie zmienić znaczniki. Na przykład, jeśli kopia stanu C przyjdzie od F, zanim czwarty wpis w tablicy zostanie przekazany dalej, to sześć bitów znacznikowych zmieni się na 100011, aby zasygnalizować, że pakiet musi być potwierdzony dla F, lecz nie należy go tam wysyłać.
Gdy router zakumuluje już pełny zbiór pakietów stanu połączeń, to może zbudować graf całej podsieci, ponieważ dysponuje reprezentacją każdego łącza. W rzeczy samej każde łącze jest reprezentowane dwukrotnie, po jednym razie w każdą stronę. Wartości te mogą zostać uśrednione lub użyte osobno.
Teraz można lokalnie uruchomić algorytm Dijkstry, aby zbudować najkrótsze ścieżki do wszystkich możliwych miejsc przeznaczenia. Wynik działania algorytmu może zostać zainstalowany w tablicach routingu, po czym przywraca się normalną eksploatację.
Dla podsieci z n routerów, z których każdy ma k sąsiadów, objętość pamięci wymaganej do zapamiętania otrzymanych danych jest proporcjonalna do kn. W dużych podsieciach może to być problemem. Poza tym problemy może stwarzać czas niezbędny na dokonanie obliczeń. Mimo to w wielu praktycznych zastosowaniach routing z użyciem stanu połączeń działa nieźle.
Problemy ze sprzętem lub oprogramowaniem mogą nieźle namieszać w tym algorytmie (podobnie jak w innych). Na przykład, jeśli router informuje o posiadaniu linii, której nie ma, lub zapomina zgłosić linii, którą ma, graf podsieci będzie niepoprawny. Jeśli router nie przekazuje pakietów dalej lub uszkadza je podczas przekazywania, problemy pojawią się na pewno. W końcu jeśli braknie w routerze pamięci lub obliczenia tras zostaną przeprowadzone błędnie, to będzie się działo źle. Gdy podsieci rozrastają się do dziesiątków lub setek tysięcy węzłów, prawdopodobieństwo awarii któregoś routera przestaje być zaniedbywalne. Cała sztuka w takim planowaniu, aby w razie nieuniknionych problemów ograniczyć szkody. Perlman (1988) omawia szczegółowo te problemy i ich rozwiązania.
Routing z użyciem stanu połączeń jest powszechnie stosowany w sieciach rzeczywistych, więc należałoby wspomnieć o kilku przykładowych protokołach. Algorytmu stanu połączeń używa protokół OSPF, powszechnie wykorzystywany w Internecie. OSPF opiszemy w punkcie 5.6.4.
Innym protokołem używającym stanu połączeń jest IS-IS (Intermediate System-Intermediate System), który został zaprojektowany dla DECnet, a później zaadaptowany przez ISO na potrzeby bezpołączeniowego protokołu warstwy sieciowej CNLP. Ponieważ został wtedy zmodyfikowany do obsługi również innych protokołów, w tym przede wszystkim IP, protokół IS-IS jest używany w niektórych sieciach szkieletowych Internetu (np. w starej sieci NSFNET) i w pewnych cyfrowych systemach telefonii komórkowej, takich jak CDPD. Novell NetWare używa nieco zmienionego wariantu IS-IS (NLSP) do routingu pakietów IPX.
IS-IS zasadniczo dystrybuuje obraz topologii routerów, na podstawie którego obliczana jest najkrótsza ścieżka. Każdy router ogłasza w swoich informacjach o stanie połączeń, które adresy warstwy sieciowej może dosięgnąć bezpośrednio. Mogą to być adresy IP, IPX, AppleTalk lub dowolne inne. IS-IS może nawet jednocześnie obsługiwać kilka protokołów warstwy sieciowej.
Wiele innowacji zaprojektowanych dla IS-IS przyjęto w OSPF (OSPF został zaprojektowany kilka lat po IS-IS). Należą do nich samostabilizująca się metoda zalewania aktualizacjami stanu łączy, pojęcie wyróżnionego routera w sieci LAN i metoda obliczania i obsługi podziału ścieżki i wielokrotnych metryk. Z tego powodu różnice pomiędzy IS-IS i OSPF są nader niewielkie. Najważniejszą z nich jest zakodowanie IS-IS w taki sposób, dzięki któremu równoczesne przenoszenie informacji o kilku protokołach warstwy sieciowej jest łatwe i naturalne, czym nie dysponuje OSPF. Zaleta ta jest szczególnie cenna w dużych środowiskach z wieloma protokołami.
W miarę rozwoju wielkości sieci tablice routingu w routerach również rosną proporcjonalnie. Nie dość, że pamięć routera jest zajmowana przez coraz większe tablice, lecz coraz więcej czasu procesora trzeba przeznaczyć na ich skanowanie i coraz większe pasmo jest potrzebne na wysyłanie raportów o ich stanie. W pewnym momencie sieć może rozrosnąć się do poziomu, na którym nie da się praktycznie utrzymywać w każdym routerze wpisów dla wszystkich pozostałych routerów, więc routing będzie musiał odbywać się hierarchicznie, jak w sieci telefonicznej.
Gdy stosowany jest routing hierarchiczny, routery zostają podzielone na obszary, które będziemy nazywać regionami. Każdy router zna wszystkie szczegóły kierowania pakietów do celów we własnym regionie, lecz nie wie nic o wewnętrznej strukturze pozostałych regionów. Gdy łączy się ze sobą różne sieci, naturalnie możemy uznawać każdą sieć za osobny region, aby uwolnić routery w jednej sieci od konieczności pamiętania struktury topologicznej pozostałych.
W olbrzymich sieciach hierarchia dwupoziomowa może nie wystarczać — może zajść konieczność zgrupowania regionów w klastry, klastrów w strefy, stref w grupy i tak dalej, póki nie braknie nam słów na agregacje. Jako przykład wielopoziomowej hierarchii rozważmy pakiet kierowany z Berkeley w Kalifornii do Malindi w Kenii. Router w Berkeley może znać szczegółową topologię sieci w Kalifornii, lecz cały ruch wychodzący poza granice stanu będzie kierował do routera w Los Angeles. Ten potrafi kierować ruch do pozostałych routerów w USA, lecz transmisje za granicę przesyła do Nowego Jorku. Nowojorski router może być tak zaprogramowany, że będzie kierował cały ruch do routera w kraju docelowym odpowiedzialnego za transmisje międzynarodowe, na przykład w Nairobi. Dalej pakiet będzie podążał w dół drzewa w Kenii, aż dotrze do Malindi.
Rysunek 5.13 przedstawia ilościowy przykład routingu w dwupoziomowej hierarchii złożonej z pięciu regionów. Pełna tablica routingu w routerze 1A ma 17 wpisów, przedstawionych na rysunku 5.13 (b). Gdy routing odbywa się hierarchicznie, jak na rysunku 5.13 (c), znajdują się w niej jak poprzednio wszystkie routery lokalne, lecz wszystkie pozostałe regiony zostały skondensowane do pojedynczego routera, więc cały ruch dla regionu 2. przechodzi łączem 1B - 2A, lecz reszta zdalnego ruchu podąża łączem 1C - 3B. Routing hierarchiczny pozwolił skrócić tablicę z 17 do 7 pozycji. W miarę zwiększania stosunku liczby regionów do liczby routerów na region wzrasta oszczędność miejsca w tablicy.
Niestety, te oszczędności miejsca nie są darmowe. Trzeba zapłacić za to zwiększoną długością ścieżki. Na przykład najlepsza trasa z 1A do 5C biegnie przez region 2., lecz w routingu hierarchicznym cały ruch dla regionu 5. przechodzi przez region 3., ponieważ jest to lepsza trasa dla większości miejsc przeznaczenia w regionie 5.
Gdy pojedyncza sieć staje się bardzo duża, pojawia się ciekawe pytanie: ile poziomów powinna mieć hierarchia? Weźmy na przykład podsieć z 720 routerami. Jeśli hierarchii nie ma, każdy router potrzebuje 720 wpisów w tablicy routingu. Jeśli podzielimy podsieć na 24 regiony po 30 routerów, to każdy będzie potrzebował 30 lokalnych wpisów i 23 zdalnych, co razem daje 53 wpisy. Jeśli wybierzemy hierarchię trzypoziomową z ośmioma klastrami, z których każdy będzie zawierał 9 regionów po 10 routerów, to każdy router będzie potrzebował 10 wpisów lokalnych, 8 do routingu do innych regionów we własnym klastrze i 7 dla odległych klastrów, co daje razem 25 wpisów. Kamoun i Kleinrock (1979) odkryli, że optymalna liczba poziomów dla podsieci z N routerów wynosi ln Ni wymaga łącznie e lnN wpisów na router. Udowodnili też, że wzrost średniej efektywnej długości ścieżki, powodowany przez routing hierarchiczny, jest wystarczająco mały, aby zwykle był do przyjęcia.
W niektórych zastosowaniach hosty muszą wysyłać wiadomości do wielu lub wszystkich pozostałych hostów. Na przykład usługa dystrybucji prognoz pogody, aktualizacji danych giełdowych lub programów radiowych na żywo może funkcjonować najlepiej, rozgłaszając informacje do wszystkich komputerów i pozwalając tym, które są zainteresowane, czytać dane. Wysłanie pakietu do wszystkich miejsc przeznaczenia jednocześnie nosi nazwę rozgłaszania (ang. broadcasting); istnieją różne metody wykonywania tej czynności.
Jedna z metod rozgłaszania, która nie wymaga żadnych specjalnych funkcji od podsieci, polega Po prostu na wysłaniu ze źródła osobnego pakietu do każdego miejsca przeznaczenia. Ta metoda nie tylko marnuje pasmo, lecz również wymaga od nadajnika znajomości pełnej listy miejsc przeznaczenia. W praktyce może to być jedyna możliwość, lecz jest najmniej pożądanym z istniejących rozwiązań.
Kolejnym oczywistym kandydatem jest rozpływanie. Wprawdzie nie najlepiej nadaje się do zwykłej komunikacji dwupunktowej, lecz w rozgłaszaniu zasługuje na uwagę, zwłaszcza jeśli żadnej z metod opisanych poniżej nie da się zastosować. Problem z rozpływaniem w roli techniki rozgłaszania jest taki sam jak w algorytmie routingu dwupunktowego — generuje zbyt wiele pakietów i zajmuje zbyt wiele pasma.
Trzeci algorytm to routing wieloadresowy (ang. multidestination routing). Gdy używana jest ta metoda, każdy pakiet zawiera albo listę miejsc przeznaczenia, albo mapę bitową wskazującą pożądane cele. Gdy pakiet przychodzi do routera, ten sprawdza wszystkie miejsca przeznaczenia, aby ustalić zbiór potrzebnych linii wyjściowych (linia wyjściowa jest potrzebna, gdy należy do najlepszej trasy do przynajmniej jednego miejsca przeznaczenia). Router generuje nową kopię każdego pakietu dla każdej linii wyjściowej, która ma zostać użyta, i zawiera w każdym pakiecie tylko te miejsca docelowe, które będą używać danej linii. Dzięki temu zbiór miejsc docelowych jest dzielony pomiędzy linie wyjściowe. Po wystarczającej liczbie przeskoków każdy pakiet będzie zawierał tylko jedno miejsce docelowe i będzie można go traktować jak zwykły pakiet. Routing wieloadresowy przypomina wysyłanie odrębnie adresowanych pakietów, z tym wyjątkiem, że gdy jedną trasą trzeba przesłać kilka pakietów, to jeden z nich płaci pełną cenę przejazdu, a reszta wiezie się za darmo.
Czwarty algorytm rozgłoszeniowy wprost korzysta z drzewa ujścia routera inicjującego rozgłoszenie — lub dowolnego innego drzewa częściowego, które będzie dogodne. Drzewo częściowe (ang. spanning tree) jest podzbiorem podsieci, zawierającym wszystkie routery, lecz niezawierającym ani jednej pętli. Jeśli każdy router wie, które jego linie należą do drzewa częściowego, to może skopiować przychodzący pakiet rozgłoszeniowy do wszystkich tych linii z wyjątkiem tej, z której odebrał pakiet. Ta metoda doskonale wykorzystuje pasmo, generując absolutnie minimalną liczbę pakietów potrzebną do wykonania zadania. Jedyny problem polega na tym, że każdy router musi posiadać wiedzę o drzewie częściowym, aby można było zastosować tę metodę. Czasem informacje te są dostępne (np. w routingu z użyciem łączy stanów), lecz czasem nie (np. w routingu z użyciem wektorów odległości).
Nasz ostami algorytm rozgłoszeniowy jest próbą naśladowania zachowania poprzedniego algorytmu, nawet wtedy, gdy routery nie wiedzą nic o drzewach częściowych. Idea ta, zwana reverse pa-th forwarding (przekazywanie z braniem pod uwagę odwrotnej ścieżki), jest nader prosta, gdy już ją pokażemy. Gdy pakiet rozgłoszeniowy przychodzi do routera, ten sprawdza, czy pakiet dotarł linią która zwykle jest używana do wysyłania pakietów do źródła rozgłoszeń. Jeśli tak, to mamy doskonałą szansę, że sam pakiet rozgłoszeniowy podróżował najlepszą trasą z routera, więc jest pierwszą kopią która dotarła do routera. Wobec tego nasz router przekazuje dalej kopie pakietu do wszystkich linii z wyjątkiem tej, na której się pojawił. Jeśli jednak pakiet rozgłoszeniowy pojawi się na linii innej niż preferowana do komunikacji z jego źródłem, to zostaje odrzucony jako prawdopodobny duplikat
Rysunek 5.14 zawiera przykład działania tej metody. Część (a) przedstawia podsieć, część (b) drzewo ujścia dla routera I w tej podsieci, a część (c) pokazuje, jak działa algorytm przekazywania z braniem pod uwagę ścieżki odwrotnej. W pierwszym przeskoku I wysyła pakiety do F, H,Ji N, jak widać na drugim poziomie drzewa. Każdy z tych pakietów dociera ścieżką preferowaną do I (zakładając, że ścieżka preferowana nakłada się na drzewo ujścia), na co wskazuje otoczenie litery kółkiem. W drugim przeskoku zostaje wygenerowanych osiem pakietów, po dwa przez każdy router, który otrzymał pakiet w pierwszym przeskoku. Jak się okazuje, żaden z nich nie został uprzednio odwiedzony, a pięć pakietów przybyło łączem preferowanym. Z sześciu pakietów wygenerowanych w trzecim przeskoku tylko trzy docierają preferowanymi ścieżkami (do C, E i K); pozostałe są duplikatami. Po pięciu przeskokach i 24 pakietach rozgłaszanie kończy się, w porównaniu z czterema przeskokami i 14 pakietami w sytuacji, gdyby transmisja rozchodziła się dokładnie według drzewa ujścia.
Metoda przekazywania z braniem pod uwagę odwrotnej ścieżki ma jedną podstawową zaletę — jest jednocześnie w rozsądnym stopniu efektywna i łatwa do zaimplementowania. Nie wymaga od routerów wiedzy o drzewach częściowych i nie wymaga dodatkowego zwiększania każdego pakietu rozgłoszeniowego o listę adresów docelowych lub mapę bitową, jak w routingu wieloadresowym. Nie potrzebuje też żadnego specjalnego mechanizmu do zatrzymania procesu, jak metoda rozpływowa (licznika przeskoków w każdym pakiecie i wiedzy a priori o średnicy podsieci albo listy pakietów odebranych już od każdego źródła).
Niektóre aplikacje wymagają współpracy odległych od siebie procesów jako grup, jak np. grupa procesów implementująca system rozproszonej bazy danych. W takich sytuacjach często konieczne jest wysyłanie przez jeden proces komunikatu do wszystkich pozostałych członków grupy. Jeśli grupa jest mała, to może po prostu wysłać osobny komunikat wprost do każdego innego członka. Jeśli grupa jest duża, taka strategia będzie kosztowna. Czasami można użyć rozgłaszania, lecz stosowanie rozgłoszeń do informowania 1000 komputerów w sieci złożonej z miliona węzłów jest nieefektywne, ponieważ większość odbiorców nie jest zainteresowana komunikatem (albo, co gorsze, są zdecydowanie nim zainteresowani, lecz nie powinni go widzieć). Potrzebujemy więc sposobu na wysyłanie komunikatów do dobrze zdefiniowanych grup, które mają dużą liczbę członków, lecz są małe w porównaniu z całą siecią.
Wysyłanie komunikatów do takiej grupy nosi nazwę rozsyłania grupowego lub multiemisji (ang. multicasting), a jego algorytm routingu nosi nazwę algorytmu routingu rozsyłania grupowego (ang. multicast routing). W tym punkcie opiszemy jeden ze sposobów takiego routingu. Dodatkowe informacje podają Chu i inni (2000), Costa i innni (2000), Kasera i inni (2000), Madruga i Garcia-Luna-Aceves (2001) oraz Zhang i Ryu (2001).
Rozsyłanie grupowe wymaga zarządzania grupami. Potrzebna jest jakaś metoda tworzenia i rozwiązywania grup oraz umożliwienia procesom dołączania się i opuszczania grup. Sposoby wykonywania tych zadań nie są ważne dla algorytmu routingu. Dla niego istotny jest fakt, że proces dołączający się do grupy informuje o tym swojego hosta. Albo hosty muszą informować swoje routery ° zmianach w przynależności do grupy, albo routery muszą odpytywać o to hosty okresowo. W obu przypadkach routery dowiadują się, które z ich hostów należą do poszczególnych grup. Routery iuformują o tym swoich sąsiadów, więc informacje propagują się w podsieci.
Na potrzeby routingu rozsyłania grupowego każdy router generuje swoje drzewo częściowe, obejmujące wszystkie pozostałe routery. Na przykład na rysunku 5.15 (a) mamy dwie grupy o numerach 1 i 2. Część routerów jest połączonych z hostami, które należą do jednej lub obu grup, jak widać na rysunku. Drzewo częściowe pierwszego routera z lewej przedstawia rysunek 5.15 (b).
RYSUNEK 5.15. (a) Sieć. (b) Drzewo częściowe pierwszego routera z lewej, (c) Drzewo rozsyłania grupowego dla grupy 1. (d) Drzewo rozsyłania grupowego dla grupy 2.
Gdy proces wysyła pakiet do grupy, pierwszy router sprawdza swoje drzewo częściowe i „okrawa je", usuwając wszystkie linie nieprowadzące do hostów należących do grupy. W naszym przykładzie rysunek 5.15 (c) przedstawia przycięte drzewo częściowe dla grupy 1., a rysunek 5.15 (d) dla grupy 2. Pakiety grupowe są przekazywane dalej tylko wzdłuż odpowiedniego drzewa grupowego.
Istnieją różne metody okrawania drzewa częściowego. Najprostsza z nich może zostać użyta w przypadku wykorzystania routingu z użyciem stanu łączy i jeśli każdy router zna pełną topologię, łącznie z przynależnością hostów do grup. Drzewo częściowe może wtedy zostać przycięte, zaczynając od końca każdej ścieżki w stronę korzenia, przez usuwanie każdego routera, który nie należy do danej grupy.
W routingu z użyciem wektorów odległości można użyć innej strategii okrawania. Podstawowym algorytmem jest przekazywanie z braniem pod uwagę odwrotnej ścieżki. Jednakże za każdym razem, gdy router nie obsługuje hostów zainteresowanych konkretną grupą i nie mający połączeń z innymi takimi routerami odbiera komunikat przeznaczony dla takiej grupy, router taki odpowiada komunikatem PRUNE (okrawaj) mówiącym nadawcy, że nie powinien przekazywać dodatkowych transmisji grupowych dla tej grupy. Gdy router niemający wśród swoich hostów członków tej grupy otrzyma taki komunikat na wszystkich swoich liniach wejściowych, to również może odpowiedzieć komunikatem PRUNE. W ten sposób podsieć jest okrawana rekurencyjnie.
Jedną z wad tego algorytmu jest nienajlepsza skalowalność w dużych sieciach. Załóżmy, że sieć ma n grup, z których każda ma średnio m członków. Dla każdej grupy należy pamiętać m okrojonych drzew częściowych, co daje łącznie mn drzew. Wszędzie, gdzie istnieją duże grupy, potrzeba spor miejsca w pamięci do zapisania wszystkich drzew.
Alternatywne rozwiązanie wykorzystuje drzewa centrowane (ang. core-based tree) — Ballardie i innni (1993). Tutaj wyliczane jest jedno drzewo częściowe z korzeniem (centrum) w pobliżu środka grupy. Aby rozesłać komunikat grupowy, host wysyła go do centrum, które następnie rozsyła komunikat wzdłuż drzewa częściowego. Wprawdzie takie drzewo nie jest optymalne dla wszystkich źródeł, lecz redukcja kosztów z m drzew na jedno drzewo na grupę jest sporą oszczędnością.
Miliony użytkowników korzystają dziś z komputerów przenośnych i, ogólnie, większość z nich chce czytać pocztę i korzystać ze swoich systemów plików niezależnie od punktu na kuli ziemskiej, w którym się znajduje. Takie hosty mobilne wprowadzają nową komplikację — aby znaleźć trasę do hosta mobilnego, sieć najpierw musi znaleźć samego hosta. Zagadnienie łączenia hostów mobilnych z siecią jest bardzo świeże, lecz w tym punkcie przedstawimy w zarysie kilka problemów i ich możliwe rozwiązania.
Model świata, używany zwykle przez projektantów sieci, przedstawia rysunek 5.16. Mamy na nim sieć rozległą (WAN) składającą się z routerów i hostów. Z siecią WAN łączą się sieci lokalne i miejskie oraz komórki sieci bezprzewodowych, które omówiliśmy w rozdziale 2.
RYSUNEK 5.16. Sieć rozległa, do której podłączone są sieci lokalne, miejskie i komórki bezprzewodowe
Hosty, które nigdy się nie przenoszą uznajemy za stacjonarne. Są one połączone z siecią kablami miedzianymi lub światłowodami. Z drugiej strony możemy rozróżnić dwa inne typy hostów. Hosty migrujące są zasadniczo hostami stacjonarnymi, które od czasu do czasu przenoszą się z jednego stałego miejsca na drugie, lecz używają sieci tylko wtedy, gdy są z nią połączone fizycznie. Hosty wędrowne działają „w trasie" i chcą utrzymywać połączenia podczas podróży. Dla obu kategorii będziemy używać określenia hosty mobilne, oznaczającego hosty wymagające dostępu do sieci z dala od domu.
Dla wszystkich hostów zakładamy lokalizację macierzystą, która nigdy się nie zmienia. Hosty mają też stałe adresy macierzyste, które mogą posłużyć do ustalenia ich lokalizacji macierzystej, Podobnie jak numer telefoniczny 1-212-5551212 wskazuje na USA (kod kraju 1) i Manhattan (212). Zadaniem routingu w systemach z hostami mobilnymi jest umożliwienie przesyłania pakietów do hostów mobilnych z użyciem ich adresów macierzystych i efektywnego docierania do nich pakietów niezależnie od bieżącego położenia. Cała sztuka polega oczywiście na znalezieniu tych hostów.
W modelu z rysunku 5.16 świat jest podzielony (geograficznie) na małe jednostki. Nazwijmy je obszarami; obszarem będzie zwykle LAN lub komórka bezprzewodowa. Każdy obszar ma jednego lub więcej agentów zewnętrznych, które są procesami śledzącymi wszystkie hosty mobilne obecne w obszarze. Oprócz tego każdy obszar ma agenta macierzystego rejestrującego hosty, dla których dany obszar jest macierzysty, lecz które w danej chwili znajdują się w innym obszarze.
Gdy w obszarze pojawia się nowy host, albo przez włączenie się do niego (tzn. przez podłączenie się do LAN), albo przez wejście do komórki, komputer ten musi zarejestrować się w lokalnym agencie zewnętrznym. Procedura rejestracji zwykle wygląda tak:
Każdy agent zewnętrzny okresowo rozgłasza pakiet oznajmiający jego istnienie i adres. Przybyły właśnie host mobilny może czekać na jeden z tych komunikatów, lecz gdy żaden nie pojawi się wystarczająco szybko, host mobilny może rozgłosić pakiet z pytaniem, czy w okolicy znajdują się jakieś agenty zewnętrzne.
Host mobilny rejestruje się w agencie zewnętrznym, podając mu swój adres macierzysty, bieżący adres warstwy łącza danych i pewne informacje związane z zabezpieczeniami.
Agent zewnętrzny kontaktuje się z agentem macierzystym hosta mobilnego i informuje go, że znajduje się tu jeden z jego hostów. Komunikat od agenta zewnętrznego do agenta macierzystego zawiera adres sieciowy agenta zewnętrznego oraz informacje zabezpieczające, aby przekonać agenta macierzystego, że host mobilny naprawdę jest tutaj.
Agent macierzysty sprawdza informacje zabezpieczające, które zawierają znacznik czasowy, udowadniając, że zostały wygenerowane w ciągu kilku ostatnich sekund. Jeśli zadowolą go te informacje, powiadamia agenta zewnętrznego, że może iść dalej.
Gdy agent zewnętrzny otrzyma potwierdzenie od agenta macierzystego, wprowadza wpis do swoich tablic i informuje hosta mobilnego, że został zarejestrowany.
W warunkach idealnych host opuszczający obszar również powinien zgłosić chęć wyrejestrowania, lecz wielu użytkowników po prostu wyłącza komputer po skończeniu pracy.
Pakiet wysyłany do hosta mobilnego jest kierowany do macierzystej sieci LAN tego hosta, ponieważ tak każe adres docelowy, jak widać w kroku 1. z rysunku 5.17. Tutaj nadawca z Seattle w północno-zachodniej części USA chce wysłać pakiet do hosta, który standardowo mieści się po drugiej stronie kontynentu, w Nowym Jorku. Pakiety wysyłane do hosta mobilnego w jego lokalnej sieci macierzystej w Nowym Jorku są przechwytywane przez mieszczącego się tam agenta macierzystego. Ten następnie szuka nowej (tymczasowej) lokalizacji mobilnego hosta i znajduje adres agenta zewnętrznego, który go obsługuje, w Los Angeles.
Agent macierzysty robi wówczas dwie rzeczy. Po pierwsze kapsułkuje pakiet w polu ładunku użytecznego zewnętrznego pakietu i wysyła do agenta zewnętrznego (krok 2. na rysunku 5.17). Ten mechanizm nosi nazwę tunelowania; przyjrzymy mu się bardziej szczegółowo później. Po otrzymaniu kapsułkowanego pakietu agent zewnętrzny pobiera oryginalny pakiet z pola ładunku użytecznego i wysyła go do hosta mobilnego jako ramkę łącza danych.
Po drugie agent macierzysty mówi nadawcy, aby od tej pory wysyłał pakiety do hosta mobilnego przez kapsułkowanie ich w ładunku roboczym pakietów zaadresowanych wprost do agenta zewnętrznego zamiast na adres macierzysty hosta mobilnego (krok 3.). Następne pakiety będzie można kierować wprost do hosta poprzez agenta zewnętrznego (krok 4.), całkowicie pomijając macierzystą lokalizację.
Różne proponowane metody różnią się pod kilkoma względami. Po pierwsze, trzeba zdecydować, za jak dużą część tego protokołu odpowiadają routery, a za jaką hosty, a w przypadku hostów, która warstwa. Po drugie, w kilku technikach routery na całej trasie rejestrują mapowane adresy, aby mogły przechwycić transmisję i przekierować, zanim w ogóle dotrze do lokalizacji macierzystej. Po trzecie, w niektórych metodach każdy gość otrzymuje unikatowy adres tymczasowy; w innych adres tymczasowy dotyczy agenta, który obsługuje łączność z wszystkimi gośćmi.
Po czwarte, schematy różnią się sposobem, w jaki umożliwiają doręczenie do innego celu pakietu zaadresowanego gdzieś indziej. Jedna z metod polega na zmianie adresu docelowego i retransmisj zmodyfikowanego pakietu. W innej cały pakiet, łącznie z adresem macierzystym, jest kapsułkowam w polu ładunku innego pakietu, wysłanego na tymczasowy adres. Na koniec metody różnią się zabezpieczeniami. Ogólnie mówiąc, gdy host lub router otrzymuje komunikat typu „Od tej pory proszę kierować całą pocztę użytkownika X do mnie", to może kwestionować, z kim rozmawia i czy zgoda na to będzie dobrym pomysłem. Kilka protokołów hostów mobilnych omówili i porównali Hac i Guo (2000) Perkins (1998a), Snoeren i Balakrishnan (2000), Solomon (1998) oraz Wang i Chen (2001).
Zobaczyliśmy już, jak wygląda routing w przypadku, gdy hosty są mobilne, lecz routery stacjonarne Jeszcze bardziej ekstremalnym przypadkiem jest ten, w którym same routery też są mobilne. Dc możliwych zastosowań należą:
Pojazdy wojskowe na polu bitwy bez istniejącej infrastruktury.
Flota na morzu.
Ekipy ratunkowe w miejscu dotkniętym trzęsieniem ziemi, które zniszczyło infrastrukturę.
Zgromadzenie osób z notebookami w obszarze bez 802.11.
We wszystkich tych przypadkach i im podobnych każdy węzeł składa się z routera i hosta, zwykle w tym samym komputerze. Sieci węzłów, które po prostu znalazły się obok siebie, noszą nazwę sieci ad hoc lub MANET (Mobile Ad hoc NETworks). Przyjrzyjmy się im pokrótce. Więcej informacji podaje Perkins (2001).
Sieci ad hoc różnią się od sieci kablowych tym, że wszystkie standardowe reguły dotyczące stałych topologii, stałych i znanych sąsiadów, stałych związków pomiędzy adresem IP i lokalizacja itp. nagle poleciały na śmietnik. Routery mogą znikać i pojawiać się w nowych miejscach w każdej chwili. Gdy w sieci kablowej router zna działającą ścieżkę do jakiegoś miejsca przeznaczenia, ścieżka ta pozostaje dostępna przez czas nieokreślony (z wyjątkiem jakichś awarii systemu). W sieciach ad hoc topologia może zmieniać się cały czas, więc przydatność, a nawet poprawność ścieżek, może zmieniać się nagle i bez ostrzeżenia. To oczywiste, że routing w takich warunkach musi znacznie różnić się od routingu w stacjonarnych odpowiednikach takich sieci.
Powstało wiele propozycji algorytmów routingu. Jednym z ciekawszych jest AODV (Ad hoc On-demand Distance Vector) (Perkins i Royer, 1999). Jest on dalekim krewnym algorytmu wektorów odległości Bellmana-Forda, lecz został dostosowany do pracy w środowisku mobilnym i bierze pod uwagę ograniczone pasmo i czas życia baterii, mające spore znaczenie w tym środowisku. Inna jego nietypowa cecha polega na tym, że jest algorytmem na żądanie (ang. on-demand). czyli ustala trasę do jakiegoś miejsca przeznaczenia dopiero wtedy, gdy ktoś będzie chciał wysłać pakiet do tego celu. Zobaczmy, co to oznacza.
Sieć ad hoc można w każdej chwili opisać grafem węzłów (routerów i hostów). Dwa węzły są połączone (łukiem grafu), jeśli mogą komunikować się bezpośrednio drogą radiową. Ponieważ jeden z nich może mieć nadajnik o większej mocy niż drugi, to możliwe jest, że A jest połączony z B, lecz B nie jest połączony z A. Jednakże dla uproszczenia założymy, że wszystkie połączenia są symetryczne. Należy też zauważyć, że sam fakt pozostawania dwóch urządzeń w swoim zasięgu nie oznacza, że są połączone. Budynki, wzgórze i inne przeszkody mogą blokować komunikację.
Algorytm opiszemy na podstawie rysunku 5.18, na którym proces w węźle A chce wysłać pakiet do węzła /. Algorytm AODV utrzymuje w każdym węźle tablicę indeksowaną przez miejsca przeznaczenia, która zawiera informacje o miejscu docelowym, łącznie z tym, przez którego sąsiada należy wysłać pakiet, aby dotrzeć do tego celu. Załóżmy, że A nie znajduje w swojej tablicy wpisu dla /, więc musi odkryć trasę do tego węzła. Ta właściwość odkrywania tras tylko wtedy, gdy są potrzebne, powoduje że algorytm działa „na żądanie".
RYSUNEK 5.18. (a) Zasięg transmisji węzła A. (b) Sytuacja po odebraniu transmisji A przez B i D. (c) Po odebraniu transmisji A przez C, F i G. (d) Po odebraniu transmisji A przez E, H i I. Zacieniowane węzły są nowymi odbiorcami. Strzałki przedstawiają możliwe trasy w drugą stronę
Aby znaleźć I, węzeł A tworzy specjalny pakiet ROUTE REQUEST i rozgłasza go. Pakiet dociera do B i D, jak na rysunku 5.18 (a). W rzeczy samej B i D są połączone w grafie z A dlatego, że potrafią odbierać transmisje od A. Inne węzły, na przykład F, nie są połączone łukami z A, ponieważ nie dociera do nich sygnał radiowy z A. Dlatego też F nie ma połączenia z A.
RYSUNEK 5.19. Format pakietu
ROUTE REQUEST
Format pakietu ROUTE REQUEST przedstawia rysunek 5.19. Pakiet ten zawiera adresy źródła i celu, zwykle ich adresy IP, które identyfikują, kto kogo szuka. Oprócz nich pakiet zawiera identyfikator żądania, który jest lokalnym licznikiem utrzymywanym niezależnie przez każdy węzeł i inkrementowany za każdym razem, gdy zostaje rozgłoszony ROUTE REOUEST. Adres źródłowy razem z identyfikatorem żądania w sposób jednoznaczny identyfikują pakiet ROUTE REOUEST, co pozwala węzłom odrzucać wszelkie odebrane duplikaty.
Oprócz licznika ID żądania każdy węzeł utrzymuje też drugi licznik sekwencji, inkrementowany za każdym razem, gdy zostaje wysłany pakiet ROUTE REOUEST (lub odpowiedź na ROUTE REOUEST kogoś innego). Funkcjonuje trochę jak zegar kontrolny i służy do odróżniania nowych tras od starych. Czwarte pole pakietu z rysunku 5.19 zawiera licznik sekwencji węzła A; piąte pole zawiera najświeższą wartość numeru sekwencyjnego I, który A widział (0, jeśli nigdy). Zastosowania tych pól wyjaśnią się za chwilę. Ostatnie pole (licznik przeskoków) rejestruje, ile przeskoków dokonał pakiet. Wartość początkowa wynosi 0.
Gdy pakiet ROUTE REOUEST dociera do węzła (w tym przypadku B i D), jest przetwarzany następująco:
Para (Adres źródłowy, ID żądania) jest wyszukiwana w lokalnej tablicy historii, aby sprawdzić, czy to żądanie nie zostało już odebrane i przetworzone. Jeśli jest duplikatem, zostaje odrzucone i przetwarzanie się kończy. W przeciwnym razie para zostaje wprowadzona do tablicy, aby umożliwić odrzucanie przyszłych duplikatów, a przetwarzanie trwa dalej.
Odbiornik sprawdza adres docelowy w swojej tablicy routingu. Jeśli zna świeżą trasę do celu. odsyła do źródła pakiet ROUTE REPLY informujący, jak tam się dostać (czyli w zasadzie mówi: „skorzystaj ze mnie"). „Świeża" oznacza, że Docelowy nr sekwencyjny zapisany w tablicy routingu jest równy lub wyższy od tego samego numeru w pakiecie ROUTE REOUEST. Jeśli jest niższy, zapisana trasa jest starsza od poprzedniej, którą węzeł źródłowy miał do docelowego, więc wykonywane są działania z kroku 3.
Ponieważ odbiornik nie zna świeżej trasy do celu, więc inkrementuje pole Liczba przeskoków i ponownie rozgłasza pakiet ROUTE REOUEST. Oprócz tego wydobywa dane z pakietu i zapisuje je w swojej tablicy tras zwrotnych. Informacje te posłużą do utworzenia trasy zwrotnej, ab) odpowiedź mogła później dotrzeć do źródła. Strzałki na rysunku 5.18 służą do konstruowanie trasy zwrotnej. Zostaje też uruchomiony czasomierz dla utworzonego właśnie wpisu tras) zwrotnej. Po upłynięciu limitu czasu wpis jest usuwany.
B i D nie znają położenia I, więc każdy z nich tworzy wpis trasy zwrotnej wskazujący z powrotem do A, co pokazują strzałki na rysunku 5.18, i rozgłasza pakiet z wartością 1 w liczniku prze skoków. Rozgłoszenie z B trafia do C i D. C tworzy dla niego wpis w swojej tablicy tras wstecznych i ponownie rozgłasza pakiet, natomiast D odrzuca pakiet jako duplikat. Analogicznie rozgłoszenie węzła D zostaje odrzucone przez B, jednakże zostaje przyjęte przez G i F i zapamiętane, jak na rysunki 5-18 (c). Po odebraniu rozgłoszenia przez E, H i I pakiet ROUTE REOUEST w końcu dociera do celu który zna położenie I, czyli do samego węzła I, jak na rysunku 5.18 (d). Uwaga: mimo że przed stawiliśmy rozgłoszenia w trzech dyskretnych krokach, rozgłoszenia poszczególnych węzłów ni są w żaden sposób koordynowane.
W odpowiedzi na przychodzące żądanie I buduje pakiet ROUTE REPLY, wyglądający jak na rysunku 5.20. Pola Adres źródłowy, Adres docelowy i Liczba przeskoków są kopiowane z przychodzącego żądania, lecz pole Docelowy nr sekwencyjny bierze się z licznika w pamięci I. Pole Liczb
przeskoków jest zerowane. Pole Czas życia ustala, jak długo trasa będzie poprawna. Ten pakiet zostaje przesłany pojedynczo do węzła, z którego przyszło żądanie ROUTE REOUEST, w naszym przypadku G, a następnie podąża trasą zwrotną do A. W każdym węźle pole Liczba przeskoków jest inkrementowane, co pozwala poznać odległość od celu (I).
W każdym pośrednim węźle po drodze z powrotem pakiet jest sprawdzany i zostaje wprowadzony do lokalnej tablicy routingu jako trasa do I, jeśli jest spełniony przynajmniej jeden z poniższych warunków:
Nie jest znana trasa do I.
Numer sekwencyjny dla I w pakiecie ROUTE REPLY jest wyższy niż wartość w tablicy routingu.
Numery sekwencyjne są równe, lecz nowa trasa jest krótsza.
W ten sposób wszystkie węzły na trasie zwrotnej poznają za darmo trasę I jako produkt uboczny odkrywania trasy przez A. Węzły, które otrzymały oryginalnie pakiet ROUTE REOUEST, lecz nie znalazły się na trasie zwrotnej (B, C, E, F i H w naszym przykładzie) odrzucają wpis w tablicy tras zwrotnych po upłynięciu limitu czasowego.
W dużych sieciach algorytm ten generuje wiele rozgłoszeń, nawet dla pobliskich celów. Liczbę rozgłoszeń można zredukować w następujący sposób:
Czas życia (TTL) pakietu IP jest inicjalizowany przez nadajnik i zawiera wartość równą spodziewanej średnicy sieci. Licznik jest dekrementowany po każdym przeskoku. Gdy dojdzie do 0, pakiet zostaje odrzucony zamiast dalszego rozgłaszania.
Proces odkrywania jest teraz nieco odmienny. Aby zlokalizować cel, nadajnik rozgłasza pakiet ROUTE REOUEST z wartością TTL równą 1. Jeśli w rozsądnym czasie nie przyjdzie odpowiedź, zostaje wysłany kolejny pakiet, tym razem z TTL = 2. Kolejne próby używają wartości 3, 4, 5 itd. W ten sposób wyszukiwanie najpierw odbywa się lokalnie, a później w coraz szerszych kręgach.
Ponieważ węzły mogą się przenosić lub być wyłączane, topologia może się zmienić samorzutnie. Na przykład, jeśli wyłączymy G na rysunku 5.18, A nie zorientuje się, że używana przez ten węzeł trasa do I (ADGI) przestała być sprawna. Algorytm musi sobie z tym jakoś radzić. Każdy węzeł okresowo rozgłasza komunikat Heli o, na który powinien odpowiedzieć każdy sąsiad. Jeśli odpowiedź nie nadchodzi, węzeł rozgłaszający orientuje się, że sąsiad wyszedł poza zasięg i nie jest już z nim połączony. Podobnie jeśli próbuje wysłać pakiet do sąsiada, który nie odpowie, węzeł uznaje, że ten sąsiad przestał być dostępny.
Informacje te służą do usuwania tras, które już nie działają. Dla każdego możliwego celu każdy węzeł N utrzymuje informacje o swoich sąsiadach, którzy przesłali do niego pakiet w ciągu ostatnich AT sekund. Są to tzw. aktywne węzły sąsiadujące N dla tego miejsca docelowego. JV utrzymuje tablicę routingu indeksowaną po celach i zawierającą w każdym wpisie węzeł wyjściowy służący do osiągnięcia tego celu, liczbę przeskoków do celu, najświeższy docelowy numer sekwencyjny i listę aktywnych węzłów sąsiadujących dla danego celu. Możliwą tablicę routingu dla węzła D w topologii z naszego przykładu przedstawia rysunek 5.21 (a).
Gdy dowolny z sąsiadów N staje się nieosiągalny, /V sprawdza w swojej tablicy routingu, do których węzłów docelowych trasy używały tego nieobecnego już sąsiada. Dla każdej z tych tras aktywni sąsiedzi są informowani, że ich trasa przez N stała się nieważna i muszą ją usunąć ze swoich tablic routingu. Te z kolei informują swoich aktywnych sąsiadów i tak dalej, rekurencyjnie, dopóki wszystkie trasy wykorzystujące nieobecny już węzeł zostaną usunięte z wszystkich tablic routingu.
Jako przykład utrzymania tras rozważmy nasz poprzedni przykład, lecz teraz nagle wyłączymy G. Zmienioną topologię przedstawia rysunek 5.21 (b). Gdy D odkrywa, że G jest nieobecny, przegląda swoją tablicę routingu i stwierdza, że G był używany w trasach do E, G i /. Sumą aktywnych sąsiadów dla tych węzłów docelowych jest zbiór {A, B}. Inaczej mówiąc, A i B są zależne od G dla części swoich tras, więc muszą zostać poinformowane, że te trasy już nie działają. D informuje je, wysyłając do nich pakiety, przez które odpowiednio zaktualizują swoje tablice routingu. D również usuwa wpisy dla E, G i / ze swojej tablicy routingu.
Może to nie wynikać z naszego opisu w sposób oczywisty, lecz krytyczna różnica pomiędzy algorytmami AODV i Bellmana-Forda polega na tym, że w pierwszym z nich węzły nie wysyłają okresowo rozgłoszeń zawierających całe swoje tablice routingu. Ta różnica oszczędza zarówno pasmo, jak i czas życia akumulatorów.
AODV potrafi również przeprowadzać routing rozgłoszeńiowy i grupowy. Szczegóły przedstawiają Perkins i Royer (2001). Routing ad hoc jest wyjątkowo aktywnym obszarem badań. Związane z nim zagadnienia poruszają Chen i innni (2002), Hu i Johnson (2001), Li i innni (2001), Raju i Garcia-Luna-Aceves (2001), Ramanathan i Redi (2002), Royer i Toh (1999), Spohn i Garcia-Luna-Aceves (2001), Tseng i inni (2001) oraz Zadeh i inni (2002).
Stosunkowo nowym zjawiskiem są sieci równorzędne (inaczej „każdy z każdym"), w których duża liczba użytkowników, zwykle mających stałe kablowe połączenie z Internetem, kontaktuje się w celu wymiany zasobów. Pierwsze rozpowszechnione zastosowanie tej technologii pomogło popełnić masowe przestępstwo: 50 milionów użytkowników Napstera wymieniało między sobą utwory chronione prawami autorskimi, dopóki Napster nie został zamknięty przez sądy w nader kontrowersyjnych rozprawach. Mimo to technologia sieci równorzędnych ma wiele ciekawych i całkiem legalnych zastosowań. Występuje też w niej coś w rodzaju problemu routingu, mimo że nie do końca przypomina te, które poznaliśmy do tej pory. Warto jednak przyjrzeć im się pobieżnie.
Ciekawą cechą systemów równorzędnych jest to, że są całkowicie rozproszone. Wszystkie węzły są symetryczne i nie istnieje żadne centralne sterowanie ani hierarchia. W typowym systemie równorzędnym każdy użytkownik ma jakieś informacje, które mogą być interesujące dla innych użytkowników. Może to być darmowe oprogramowanie (public domain), muzyka, fotografie i tak dalej. Jeśli użytkowników jest wielu, to nie znają się nawzajem i nie wiedzą gdzie znaleźć poszukiwane informacje. Jednym możliwych rozwiązań jest duża centralna baza danych, lecz to może być z jakiegoś powodu nie do zrealizowania (na przykład nikt nie chce utrzymywać tej bazy). Wobec tego problem sprowadza się do tego, jak użytkownik może znaleźć węzeł zawierający poszukiwane informacje, nie dysponując żadną centralną bazą danych czy choćby centralnym indeksem.
Załóżmy, że każdy użytkownik ma jedną lub kilka pozycji danych, takich jak utwory muzyczne, fotografie, programy, pliki itp., z które inni użytkownicy chcieliby pobrać. Każda pozycja ma nazwę w postaci łańcucha ASCII. Potencjalny użytkownik zna jedynie ten łańcuch i chce odkryć, czy jacyś inni użytkownicy mają kopię pliku, a jeśli tak, jakie są ich adresy IP.
Wyobraźmy sobie na przykład rozproszoną bazę danych genealogicznych. Każdy genealog ma jakieś rekordy online swoich przodków i krewnych, być może zawierające fotografie, nagrania mowy lub nawet wideo każdej osoby. Wiele osób może mieć wspólnego prapradziadka, więc dla niego mogą istnieć rekordy w wielu węzłach. Nazwą rekordu jest nazwisko osoby w jakiejś kanonicznej postaci. Genealog może pewnego dnia odkryć w archiwum testament swojego prapradziadka, w którym ten pozostawił złoty zegarek swojemu siostrzeńcowi. Genealog zna teraz nazwisko i imię siostrzeńca i chce sprawdzić, czy inny genealog ma dla niego rekord. Jak bez centralnej bazy danych możemy znaleźć, czy ktoś (ktokolwiek) ma rekordy?
Zaproponowano różnorodne algorytmy rozwiązania tego problemu. My zajmiemy się systemem Chord (Dąbek i in., 2001a, Stoica i in., 2001). W uproszczeniu działa on następująco: system Chord składa się z n uczestniczących użytkowników, z których każdy może mieć jakieś zapisane rekordy i każdy jest gotów przechowywać fragmenty indeksu dla innych użytkowników. Każdy węzeł użytkownika ma adres IP, który może zostać przekształcony na /w-bitową liczbę z użyciem funkcji mieszającej (hash). Do tego celu Chord używa SHA-1. Ta technika jest stosowana w kryptografii i przyjrzymy się jej w rozdziale 8. Na razie wystarczy powiedzieć, że jest to funkcja biorąca jako argument ciąg bajtów o zmiennej długości i generująca wysoce losową 160-bitową liczbę. Wobec tego możemy przekształcić każdy adres IP na 160-bitową liczbę zwaną identyfikatorem węzła.
Ideowo wszystkie identyfikatory węzłów (w liczbie 2160) są uporządkowane rosnąco w wielki okrąg. Część z nich odpowiada uczestniczącym węzłom, lecz większość nie. Rysunek 5.22 (a) przedstawia krąg identyfikatorów dla m = 5 (na razie zignorujemy obszar w środku kręgu). W tym przykładzie węzły o identyfikatorach 1, 4, 7, 12, 15, 20 i 27 odpowiadają faktycznym węzłom i są zacieniowane; pozostałe nie istnieją.
Zdefiniujmy teraz funkcję successor(k) jako identyfikator węzła dla pierwszego rzeczywistego węzła następującego po k w kręgu w kierunku ruchu wskazówek zegara. Na przykład successor(6) = 7, successor(8) = 12 i successor(22) = 27.
Nazwy rekordów (nazwy piosenek, imiona przodków itp.) również są przekształcane funkcją mieszającą hash (tzn. SHA-1), aby wygenerować 160-bitowy numer zwany kluczem. Aby więc przekształcić nazwę ASCII rekordu (name) na klucz (key), użyjemy key = hash(name). To obliczenie jest po prostu wywołaniem procedury lokalnej hash. Jeśli osoba posiadająca rekord genealogiczny dla name chce udostępnić go wszystkim, najpierw buduje dwójkę złożoną z nazwy i swojego adresu IP (name, my-IP-address), a następnie wywołuje successor(hash(name)), aby zapisać tę dwójkę. Jeśli istnieje więcej rekordów z tą samą nazwą (w innych węzłach), ich dwójki będą wszystkie zapisane w tym samym węźle. W ten sposób indeks jest losowo rozpraszany pomiędzy węzłami. Dla odporności na błędy można użyć p różnych funkcji mieszających, aby zapisać każdą dwójkę w p węzłów, lecz nie będziemy się tym tutaj zajmować.
Gdy jakiś użytkownik chce wyszukać nazwę, mieszają, aby otrzymać klucz key, a następnie za pomocą successor(key) wyszukuje adres IP węzła przechowującego jego dwójkę indeksu. Pierwszy krok jest łatwy; drugi już nie. Aby umożliwić znalezienie adresu IP węzła odpowiadającego określonemu kluczowi, każdy węzeł musi utrzymywać pewne struktury danych. Jedną z nich jest adres IP węzła następcy (successor) w kręgu identyfikatorów węzłów. Na przykład na rysunku 5.22 następcą węzła 4 jest 7, a następcą 7 jest 12.
Teraz może się odbyć wyszukiwanie: węzeł zgłaszający żądanie wysyła do swojego następcy pakiet zawierający swój adres IP i klucz, którego szuka. Pakiet propaguje się po okręgu, dopóki nie znajdzie następcy szukanego identyfikatora węzła. Węzeł ten sprawdza, czy ma jakieś informacje pasujące do klucza, a jeśli tak, zwraca je bezpośrednio do węzła żądającego, którego adres IP otrzymał.
Pierwsza optymalizacja może polegać na tym, że każdy węzeł będzie pamiętać adresy IP swojego poprzednika i następcy, dzięki czemu zapytania będzie można kierować w kierunku zgodnym lub przeciwnym do ruchu wskazówek zegara, zależnie od tego, która trasa będzie krótsza. Na przykład węzeł 7 z rysunku 5.22 może pójść w kierunku ruchu wskazówek zegara, aby znaleźć identyfikator węzła 10, lecz w kierunku przeciwnym, aby znaleźć identyfikator węzła 3.
Nawet przy dostępnych dwóch kierunkach liniowe przeszukiwanie wszystkich węzłów jest bardzo niewydajne w dużych systemach równorzędnych, ponieważ średnia liczba węzłów wymaganych
w wyszukiwaniu wynosi n/2. Aby znacznie przyspieszyć szukanie, każdy węzeł utrzymuje też tablicę nazywaną w Chord tablicą strzałek (ang. finger table). Tablica strzałek zawiera m wpisów, indeksowanych od 0 do m - 1, z których każdy wskazuje na inny rzeczywisty węzeł. Każdy wpis zawiera dwa pola: start i adres IP następcy, czyli successor(start), jak w trzech przykładach z rysunku 5.22 (b). Wartości pól dla wpisu i w węźle k są następujące:
start =k + 2i (modulo2m)
adres IP węzła successor(start[i])
Proszę zwrócić uwagę, że każdy węzeł przechowuje adres IP stosunkowo niewielkiej liczby węzłów i że większość z nich jest stosunkowo blisko, jeśli idzie o identyfikatory węzłów.
Przy użyciu tablicy strzałek wyszukiwanie klucza w węźle k wygląda następująco: jeśli klucz mieści się od A do successor(k), węzłem przechowującym informacje o kluczu key jest successor(k) i wyszukiwanie się kończy. W przeciwnym razie tablica strzałek jest przeszukiwana, aby znaleźć wpis, którego pole start jest najbliższym poprzednikiem key. Wówczas wprost pod adres IP ze wpisu w tablicy strzałek zostaje wysłane żądanie kontynuacji wyszukiwania. Ponieważ jest on bliżej key, lecz nadal poniżej, jest duża szansa na to, że będzie mógł zwrócić odpowiedź po niewielkiej liczbie dodatkowych zapytań. W istocie, ponieważ każde wyszukiwanie zmniejsza pozostałą odległość do celu
0 połowę, możemy wykazać, że średnia liczba wyszukiwań będzie wynosić log2n.
Jako pierwszy przykład weźmy szukanie key = 3 w węźle nr 1. Ponieważ węzeł 1 wie, że 3 leży pomiędzy nim a jego następcą 4, pożądanym węzłem jest 4 i szukanie kończy się, zwracając adres IP węzła 4.
Drugim przykładem niech będzie szukanie key = 14 w węźle 1. Ponieważ 14 nie leży pomiędzy
1 i 4, sprawdzana jest tablica strzałek. Najbliższym poprzednikiem 14 jest 9, więc żądanie zostaje przekazane pod adres IP dla wpisu 9, czyli do węzła 12. Węzeł 12 stwierdza, że 14 mieści się pomiędzy nim samym a jego następcą (15), więc zwraca adres IP węzła 15.
Jako trzeci przykład rozważmy szukanie key = 16 w węźle 1. Ponownie zapytanie zostaje wysłane do węzła 12, lecz tym razem 12 nie zna odpowiedzi. Szukając węzła najbliżej poprzedzającego 16 znajduje 14, co daje adres IP węzła 15. Zapytanie zostaje wysłane pod ten adres. Węzeł 15 spostrzegą że 16 leży pomiędzy nim samym i następcą 16 (2), więc zwraca adres IP 20, który wraca do węzła 1.
Ponieważ węzły mogą w każdej chwili pojawić się lub opuścić sieć, Chord potrzebuje sposobu na obsługę tych operacji. Zakładamy, że gdy system zaczyna działać, jest na tyle mały, że węzły mogą po prostu wymieniać informacje bezpośrednio, tworząc pierwszy krąg i tablice strzałek. Do dalszego działania potrzebna jest zautomatyzowana procedura: gdy nowy węzeł r chce się dołączyć, to musi skontaktować się z istniejącym węzłem i zapytać o adres IP swojego następcy successor(r). Następnie nowy węzeł pyta successor(r) o jego poprzednika, po czym żąda od obu węzłów wstawienia do kręgu siebie pomiędzy te dwa węzły. Na przykład, gdy 24 z rysunku 5.22 zechce dołączyć się do sieci, zapyta dowolny węzeł o wyszukanie successor(24) i otrzyma wartość 27. Następnie zapyta 27 o jego poprzednika (20). Po poinformowaniu obu o swoim istnieniu węzeł 20 użyje 24 jako swojego następcę, a 27 jako poprzednika. Oprócz tego węzeł 27 przekaże do 24 klucze z zakresu od 21 do 24, które od tej pory będą należeć do 24. Po tej operacji 24 będzie w pełni włączony do kręgu.
Jednakże teraz wiele tablic strzałek zawiera błędne informacje. Aby je poprawić, w każdym węźle uruchomiony jest proces tła, który okresowo odtwarza tablice strzałek przez wywołanie successor. Gdy któreś z tych zapytań trafi na nowy węzeł, odpowiadająca mu strzałka zostanie zaktualizowana.
Gdy węzeł opuszcza sieć w sposób kontrolowany, przekazuje klucze do swojego następcy i informuje poprzednika o swoim odejściu, aby ten mógł powiązać się z następcą odchodzącego węzła. Gdy węzeł pada, pojawia się problem, ponieważ jego poprzednik przestaje mieć poprawnego następcę.
Aby złagodzić ten problem, każdy węzeł pamięta nie tylko swojego bezpośredniego następcę, lecz również s jego bezpośrednich następców, co pozwala pominąć s - 1 kolejnych niesprawnych węzłów i połączyć okrąg na nowo.
Chord posłużył do utworzenia rozproszonego systemu plików (Dąbek i in., 200lb) i innych aplikacji, a badania nad nim nadal trwają. Inny system równorzędny, Pastry, oraz jego zastosowania opisują Rowstron i Druschel (2001a i 2001b). Trzeci system równorzędny, Freenet, przedstawili Ciarkę i inni (2002), a czwarty Ratnasamy i inni (2001).
Gdy zbyt wiele pakietów pojawia się w podsieci lub jej części, wydajność systemu spada. Sytuacja taka nosi nazwę przeciążenia. Rysunek 5.23 przedstawia jego objawy. Gdy liczba pakietów wrzuconych do podsieci przez hosty mieści się w granicach nośności podsieci, wszystkie zostają doręczone (z wyjątkiem kilku uszkodzonych przez błędy transmisji), a liczba pakietów doręczonych jest proporcjonalna do liczby wysłanych. Jednakże gdy ruch zanadto wzrośnie, routery przestaną sobie z nim radzić i zaczną tracić pakiety. To dalej pogarsza sprawę. Przy bardzo dużym ruchu wydajność załamuje się całkowicie i prawie żadne pakiety nie są doręczane.
RYSUNEK 5.23. Gdy ruch jest zbyt duży, pojawia się przeciążenie i wydajność szybko spada
Przeciążenia może powodować kilka czynników. Jeśli nagle strumienie pakietów zaczną przychodzić na trzech lub czterech liniach wejściowych i wszystkie będą wymagały tej samej linii wyjściowej, powstanie kolejka. Jeżeli w pamięci braknie miejsca na wszystkie te dane, pakiety zaczną się gubić. Rozbudowa pamięci może do pewnego punktu pomóc, lecz Nagle (1987) odkrył, że gdyby routery miały nieskończoną pojemność pamięci, przeciążenia stałyby się większe, a nie mniejsze, ponieważ do czasu dotarcia do początku kolejki pakiety traciłyby ważność (raz za razem) i źródło wysyłałoby duplikaty. Wszystkie te pakiety zostałyby doręczone do następnego routera, zwiększając obciążenie linii na całej trasie aż do celu.
Przeciążenia mogą też być powodowane przez wolne procesory. Jeśli CPU routerów zbyt Powoli wykonują wymagane od nich zadania administracyjne (kolejkowanie buforów, aktualizację tablic itp.), kolejki mogą rosnąć mimo wystarczającej z nadmiarem przepustowości linii. Przeciążenia mogą powodować też linie o niskiej przepustowości. Modernizacja linii bez modernizacji procesorów, lub vice versa, często trochę pomaga, lecz równie często po prostu przenosi wąskie gardło w inne miejsce. Prawdziwym problemem bywa często niedopasowanie elementów systemu. Problem będzie się utrzymywał, dopóki wszystkie komponenty nie zostaną zrównoważone.
Warto tu wprost wyjaśnić różnicę pomiędzy kontrolą przeciążeń i sterowaniem przepływem, ponieważ ich związek jest dość subtelny. Kontrola przeciążeń ma gwarantować, że podsieć będzie w stanie przenieść cały wprowadzany do niej ruch. Jest to problem globalny, obejmujący zachowanie wszystkich hostów, wszystkich routerów, przekazywanie z buforowaniem wewnątrz routerów i wszystkie inne czynniki, które mogą ograniczyć nośność sieci.
Z drugiej strony sterowanie przepływem dotyczy ruchu dwupunktowego pomiędzy danym nadajnikiem i danym odbiornikiem. Jego zadaniem jest gwarantowanie, że szybki nadajnik nie będzie stale wysyłał danych szybciej, niż odbiornik będzie mógł je przyjmować. Sterowanie przepływem często obejmuje przesyłanie pewnych informacji zwrotnych z odbiornika do nadajnika mówiących nadajnikowi, jak wygląda sytuacja po drugiej stronie.
Aby zrozumieć różnicę pomiędzy tymi dwoma mechanizmami, wyobraźmy sobie sieć światłowodową o nośności 1000 Gb/s, w której superkomputer próbuje przesłać plik do komputera osobistego z szybkością 1 Gb/s. Wprawdzie przeciążenie nie wystąpi (sieć nie ma kłopotów), lecz potrzebne będzie sterowanie przepływem, aby zmuszać superkomputer do częstych postojów, dających komputerowi osobistemu szansę odetchnąć.
Drugą skrajnością może być np. sieć z buforowaniem mająca łącza 1 Mb/s i 1000 dużych komputerów, z których połowa usiłuje przesyłać pliki z szybkością 100 kb/s do drugiej połowy. Tutaj problem nie polega na przytłaczaniu odbiornika przez szybki nadajnik, lecz przekroczenie przez całkowity oferowany ruch możliwości sieci.
Powodem częstego mylenia sterowania przepływem i kontroli przeciążeń jest fakt, że niektóre algorytmy kontroli przeciążeń działają przez odsyłanie do różnych źródeł komunikatów mówiących, aby spowolniły transmisję, gdy sieć ma kłopoty. Wobec tego host może otrzymać komunikat „zwolnij" albo dlatego, że odbiornik nie radzi sobie z obciążeniem, albo dlatego, że nie radzi sobie sieć. Wrócimy do tej kwestii później.
Zaczniemy analizę kontroli przeciążeń od spojrzenia na ogólny model radzenia sobie z przeciążeniami. Następnie przyjrzymy się ogólnym metodom zapobiegania przeciążeniom. W końcu przedstawimy kilka algorytmów dynamicznych radzących sobie z przeciążeniem, które już powstało.
Na wiele problemów w złożonych systemach, takich jak sieci komputerowe, można patrzeć z punktu widzenia teorii sterowania. Podejście takie prowadzi do dzielenia wszystkich rozwiązań na dwie grupy: z pętlą otwartą i z pętlą zamkniętą. Metody z pętlą otwartą usiłują rozwiązać problem przede wszystkim przez dobry projekt, aby zapewnić, że problem w ogóle nie wystąpi. Po uruchomieniu systemu nie dokonuje się bieżących korekt.
Do narzędzi dostępnych w sterowaniu w pętli otwartej należą decyzje, kiedy akceptować nowe transmisje, kiedy i które pakiety odrzucać oraz decyzje o szeregowaniu w różnych punktach sieci. Wszystkie łączy fakt, że decyzje podejmowane są bez zważania na aktualny stan sieci.
Z drugiej strony rozwiązania z pętlą zamkniętą opierają się na idei pętli sprzężenia zwrotnego. Podejście to w przypadku kontroli przeciążeń składa się z trzech elementów:
Monitorowanie sytemu w celu wykrywania, kiedy i gdzie występują przeciążenia.
Przekazanie tych informacji w miejsca, gdzie mogą zostać podjęte odpowiednie działania.
Regulacja pracy systemu, aby naprawić problem.
Do monitorowania podsieci w poszukiwaniu przeciążeń może posłużyć szereg różnych miar. Najważniejsze z nich to odsetek pakietów odrzuconych z braku miejsca w buforach, średnia długość kolejki, liczba pakietów, dla których upływa czas oczekiwania i wymagają retransmisji, średnie opóźnienie pakietu i odchylenie standardowe opóźnienia pakietu. We wszystkich przypadkach rosnące wartości wskazują na rosnące przeciążenie.
Drugim krokiem w pętli sprzężenia zwrotnego jest przekazanie informacji o przeciążeniu z miejsca, gdzie zostało wykryte, do miejsca, gdzie coś można na nie poradzić. Najbardziej oczywiste rozwiązanie polega na tym, że router wykrywa przeciążenie i wysyła pakiet do źródła lub źródeł transmisji, informując o problemie. Oczywiście te dodatkowe pakiety zwiększają obciążenie w dokładnie tym momencie, gdy dodatkowe obciążenie jest niemile widziane, czyli podczas przeciążenia sieci.
Istnieją też jednak inne możliwości. Na przykład w każdym pakiecie może być zarezerwowany bit lub pole, które router wypełnia po przekroczeniu przez przeciążenie jakiegoś ustalonego poziomu. Gdy router wykrywa taki stan przeciążenia, wypełnia pole we wszystkich pakietach, aby ostrzec sąsiadów.
Jeszcze inne podejście polega na okresowym wysyłaniu przez hosty lub routery pakietów próbkujących, wprost pytających o stan przeciążenia. Informacje te mogą zostać następnie użyte do kierowania ruchu z ominięciem problemowych obszarów. Niektóre stacje radiowe wykorzystują helikoptery, które krążą nad miastem i informują o korkach drogowych, co pozwala mobilnym słuchaczom kierować swoje pakiety (samochody) dookoła zatorów.
We wszystkich metodach ze sprzężeniem zwrotnym liczy się na to, że wiedza o przeciążeniu spowoduje podjęcie przez hosty odpowiednich działań zmniejszających przeciążenie. Aby taka metoda działała poprawnie, zależności czasowe muszą być dokładnie regulowane. Gdyby po każdym dotarciu dwóch pakietów pod rząd router krzyczał „Stop!", a po każdym okresie bezczynności routera wynoszącym 20 µs krzyczał „Dalej!", system oscylowałby gwałtownie i nigdy nie ustabilizował się. Gdyby z drugiej strony czekał 30 minut na nabranie pewności przed powiedzeniem czegokolwiek, mechanizm kontroli przeciążeń reagowałby zbyt ślamazarnie, aby do czegokolwiek się nadawał. Aby algorytm działał skutecznie, potrzebna jest jakaś metoda uśredniania, lecz znalezienie odpowiednich stałych czasowych nie jest takie proste.
Istnieje wiele algorytmów kontroli przeciążeń. Aby usystematyzować je w jakiś rozsądny sposób, Yang i Reddy (1995) opracowali taksonomię dla tych algorytmów. Zaczęli od podziału wszystkich algorytmów na stosujące pętlę otwartą i zamkniętą, jak pokazaliśmy powyżej. Następnie podzielili algorytmy z pętlą otwartą na działające od strony źródła i celu. Algorytmy z pętlą zamkniętą również zostały podzielone na dwie podkategorie: z jawnym i niejawnym sprzężeniem zwrotnym. W algorytmach z jawnym (bezpośrednim) sprzężeniem zwrotnym pakiety są odsyłane z miejsca przeciążenia, aby ostrzec źródło transmisji. W algorytmach z niejawnym sprzężeniem zwrotnym źródło wnioskuje istnienie przeciążenia przez dokonywanie lokalnych spostrzeżeń, na przykład czasu potrzebnego na powrót potwierdzenia pakietu.
Obecność przeciążenia oznacza, że obciążenie jest (chwilowo) wyższe niż zasoby (w danej części systemu) mogą obsłużyć. Na myśl przychodzą dwa rozwiązania: zwiększenie zasobów lub zmniejszenie obciążenia. Na przykład, podsieć może zacząć wykorzystywać linie telefoniczne, aby tymczasowo zwiększyć przepustowość pomiędzy dwoma określonymi punktami. W systemach satelitarnych zwiększenie mocy transmisji często daje wyższą przepustowość. Podział ruchu na kilka tras zamiast korzystania zawsze z tej samej również może zwiększyć wypadkowe pasmo. Na koniec można włączyć do eksploatacji zapasowe routery, które zwykle używane są jako zapasowe (aby zwiększyć odporność systemu na awarie), w celu zwiększenia przepustowości w przypadku poważnych przeciążeń.
Jednakże czasem zwiększenie przepustowości jest niemożliwe lub już zostało dokonane do granic możliwości. Wówczas jedynym sposobem pokonania przeciążenia może być zmniejszenie obciążenia. Istnieje kilka metod redukcji obciążenia, między innymi odmowa usług dla określonych użytkowników, obniżenie jakości usług dla wszystkich użytkowników lub planowanie żądań użytkowników w bardziej przewidywalny sposób.
Kilka z tych metod, które poznamy za chwilę, najlepiej nadaje się do obwodów wirtualnych. W sieciach używających wewnętrznie obwodów wirtualnych metody te mogą zostać zastosowane w warstwie sieciowej. W podsieciach datagramowych również mogą być jednak używane czasem w połączeniach warstwy transportowej. W niniejszym rozdziale skoncentrujemy się na ich zastosowaniu w warstwie sieciowej. W następnym zobaczymy, co można zdziałać w warstwie transportowej, aby uniknąć przeciążeń.
Zacznijmy poznawanie metod kontroli przeciążeń od systemów z pętlą otwartą. Systemy te są tak projektowane, by, po pierwsze, minimalizować przeciążenia, zamiast pozwalać na nie i reagować po fakcie, próbując osiągnąć swoje cele przez stosowanie odpowiednich zasad na różnych poziomach. Tabela 5.2 przedstawia różne zasady warstw łącza danych, sieciowej i transportowej, które mogą wpływać na przeciążenia (Jain, 1990).
TABELA 5.2.
Zasady wpływające na przeciążenia
Warstwa | Zasady |
---|---|
Transportowa | • Zasady retransmisji • Zasady buforowania niezgodnie z kolejnością • Zasady potwierdzeń • Zasady sterowania przepływem • Ustalanie limitów czasowych |
Sieciowa | • Wybór obwodów wirtualnych lub datagramów w podsieci • Zasady usług i kolejkowania pakietów • Zasady odrzucania pakietów • Algorytmy routingu • Zarządzanie czasem życia pakietów |
Łącza danych | • Zasady retransmisji • Zasady buforowania niezgodnie z kolejnością • Zasady potwierdzeń • Zasady sterowania przepływem |
Zaczniemy od warstwy łącza danych i będziemy posuwać się stopniowo w górę. Zasady retransmisji określają, jak szybko upływa czas oczekiwania nadajnika oraz co nadajnik wysyła po upłynięciu tego czasu. „Nerwowy" nadajnik, w którym czas oczekiwania upływa szybko i który ponownie wysyła wszystkie zaległe pakiety z użyciem metody „wróć do n", obciąża system znacznie poważniej niż nadajnik „zrelaksowany", używający powtórzeń selektywnych. Bliski związek mają z tym zasady buforowania. Jeśli routery rutynowo odrzucają wszystkie pakiety docierające nie po kolei, to pakiety te trzeba będzie przesłać później jeszcze raz, co spowoduje dodatkowe obciążenie. Z punktu widzenia kontroli przeciążeń powtórzenia selektywne są zdecydowanie lepsze niż „wróć do n".
Zasady potwierdzeń również mają wpływ na kontrolę przeciążeń. Jeśli każdy pakiet jest natychmiast potwierdzany, pakiety potwierdzeń generują dodatkowy ruch w sieci. Jeśli jednak potwierdzenia czekają na podwiezienie „na barana" w pakietach kierowanych w przeciwną stronę, mogą pojawić się dodatkowe przeterminowane pakiety i retransmisje. Rygorystyczna metoda sterowania przepływem (tzn. małe okno) redukuje szybkość transmisji danych i pomaga walczyć z przeciążeniami.
W warstwie sieciowej wybór pomiędzy obwodami wirtualnymi i datagramami wpływa na przeciążenia ponieważ wiele algorytmów kontroli przeciążeń współpracuje tylko z podsieciami obwodów wirtualnych. Zasady usług i kolejkowania pakietów dotyczą tego, czy routery mają osobną kolejkę dla każdej linii wejściowej, osobną dla każdej linii wyjściowej czy też jedno i drugie. Wiąże się to również z kolejnością przetwarzania pakietów (tzn. cykliczną lub opartą na priorytetach). Zasady odrzucania mówią, które pakiety zostaną odrzucone przy braku miejsca. Dobre zasady mogą pomóc w redukcji przeciążeń, a złe pogorszyć problem.
Dobry algorytm routingu może pomóc w unikaniu przeciążeń, dzieląc ruch na wszystkie linie, podczas gdy zły może wysłać zbyt wiele danych liniami, które już są przeciążone. Na koniec zarządzanie czasem życia pakietów wiąże się z tym, jak długo pakiet może istnieć przed porzuceniem. Jeśli czas życia będzie zbyt długi, utracone pakiety mogą zatykać system na długi czas, lecz zbyt krótki czas życia może czasem powodować, że pakiet wygaśnie przed dojściem do celu, powodując retransmisje.
W warstwie transportowej występują te same problemy co w warstwie łącza danych, lecz oprócz tego ustalenie interwału oczekiwania jest trudniejsze, ponieważ czas przejścia przez sieć jest mniej przewidywalny niż przejścia przez kabel pomiędzy dwoma routerami. Jeśli będzie zbyt długi, przeciążenia zostaną ograniczone, lecz czas odpowiedzi ucierpi z powodu traconych pakietów.
Opisane powyżej metody kontroli przeciążeń opierają się zasadniczo na pętli otwartej: usiłują zapobiec występowaniu przeciążeń, zamiast walczyć z nimi po fakcie. W tym punkcie opiszemy kilka sposobów podejścia do dynamicznej kontroli przeciążeń w podsieciach obwodów wirtualnych. W dwóch następnych przyjrzymy się technikom, które mogą zostać użyte w dowolnej podsieci.
Jedną z technik powszechnie stosowanych do utrzymywania w ryzach przeciążeń, które już wystąpiły, jest kontrola wstępu. Pomysł jest prosty: od chwili, gdy zostanie zasygnalizowane przeciążenie, nie można zestawiać żadnych nowych obwodów wirtualnych, póki problem nie minie. Oznacza to, że próby nawiązania nowych połączeń w warstwie transportowej zakończą się niepowodzeniem. Wpuszczanie kolejnych użytkowników pogorszyłoby tylko sprawę. Wprawdzie ta metoda jest dość toporna, lecz zarazem prosta i łatwa do wprowadzenia. Systemy telefoniczne również stosują kontrolę wstępu, nie dając sygnału gotowości w przypadku przeciążenia przełącznika.
Rozwiązanie alternatywne polega na dopuszczeniu nowych obwodów wirtualnych, lecz z takim doborem trasy, że nowe obwody omijają problemowe obszary. Spójrzmy na przykład na podsieć z rysunku 5.24 (a), w której przeciążone są dwa routery (oznaczone na rysunku).
Załóżmy, że host podłączony do routera A chce nawiązać połączenie z hostem podłączonym do routera B. Zwykle połączenie to przechodziłoby przez jeden z przeciążonych routerów. Aby uniknąć takiej sytuacji, możemy narysować podsieć na nowo, jak na rysunku 5.24 (b), pomijając przeciążone routery i wszystkie ich linie. Linia przerywana przedstawia możliwą trasę dla obwodu wirtualnego unikającą przeciążonych routerów.
Inna strategia związana z obwodami wirtualnymi polega na negocjowaniu umowy pomiędzy hostem i podsiecią w chwili zestawiania obwodu wirtualnego. Umowa taka zwykle określa objętość i kształt ruchu, wymaganą jakość usług i inne parametry. Aby wypełnić swoją stronę umowy, podsieć zwykle rezerwuje zasoby wzdłuż trasy zestawianego obwodu wirtualnego. Do zasobów tych może zaliczać się miejsce w tablicach i buforach routerów oraz pasmo przepustowości linii. Dzięki temu wystąpienie przeciążenia jest mało prawdopodobne w nowych obwodach wirtualnych, ponieważ dostępność niezbędnych zasobów jest gwarantowana.
Rezerwację można przeprowadzać zawsze jako standardową procedurę lub tylko wtedy, gdy podsieć jest przeciążona. Rezerwowanie w każdych warunkach ma tę wadę, że zwykle marnuje zasoby. Jeśli tym samym fizycznym łączem 6 Mb/s przebiega sześć obwodów wirtualnych mogących wykorzystywać 1 Mb/s każdy, to linia musi zostać oznaczona jako pełna, mimo to, że rzadko wszystkie sześć obwodów nadaje jednocześnie z pełną szybkością. Wobec tego ceną kontroli przeciążenia jest marnowanie (niewykorzystywanie) pasma w normalnych warunkach.
Przejdźmy teraz do pewnych metod, które mogą zostać użyte w podsieciach datagramowych (jak również w podsieciach obwodów wirtualnych). Każdy router może z łatwością monitorować wykorzystanie swoich linii i innych zasobów. Na przykład może przypisać do każdej linii zmienną rzeczywistą w z przedziału od 0,0 do 1,0, której wartość odzwierciedla aktualne wykorzystanie danej linii. Aby zachować dokładne szacunki u, można okresowo próbkować chwilowe wykorzystanie linii, równe f(0 lub 1) i aktualizować u zgodnie ze wzorem:
Unowe = austare + (1 - a)f
gdzie stała a decyduje, jak szybko router zapomina historię.
Za każdym razem, gdy u przekroczy ustaloną granicę, linia wyjściowa wchodzi w stan ostrzeżenia. Każdy przybyły do routera pakiet jest sprawdzany, czyjego wyjściowa linia jest w stanie ostrzeżenia. Jeśli tak, zostaje podjęte jakieś działanie. Alternatywnych możliwości działania jest kilka i omówimy je poniżej.
Stara architektura DECNET sygnalizowała stan ostrzeżenia przez wysyłanie specjalnego bitu w nagłówku pakietu. Podobnie robi Frame Relay. Gdy pakiet docierał do celu, jednostka transportowa kopiowała bit do następnego potwierdzenia odsyłanego do źródła, po czym źródło ograniczało transmisję.
Router pozostający w stanie ostrzeżenia cały czas wysyłał bity ostrzegawcze, co oznaczało, że źródło odbierało potwierdzenia z tym bitem aktywnym. Źródło monitorowało odsetek potwierdzeń z ustawionym bitem ostrzegawczym i odpowiednio regulowało swoją szybkość transmisji. Tak długo, jak bity ostrzegawcze nadchodziły nieustannie, źródło zwalniało szybkość transmisji. Gdy ich napływ malał, źródło przyspieszało transmisję. Ponieważ każdy router na trasie mógł ustawić bit ostrzegawczy, ruch wzrastał tylko wtedy, gdy żaden z routerów nie miał problemów.
Poprzedni algorytm kontroli przeciążeń jest dość subtelny i używa okrężnej metody informowania źródła, aby spowolniło transmisję. Czemu nie mielibyśmy powiedzieć mu tego wprost? W tej metodzie router wysyła pakiet tłumienia (ang. choke packet) z powrotem do hosta źródłowego, podając mu cel transmisji znaleziony w pakiecie. Pierwotny pakiet zostaje oznaczony przez włączenie bitu w nagłówku, aby nie generował kolejnych pakietów tłumienia po drodze, a następnie zostaje przekazany dalej, jak zwykle.
Gdy host źródłowy otrzymuje pakiet tłumienia, wymaga się od niego redukcji ruchu wysyłanego do wskazanego celu o A" procent. Ponieważ inne pakiety przeznaczone w to samo miejsce już przypuszczalnie są w drodze i wygenerują jeszcze więcej pakietów tłumienia, host powinien przez określony czas ignorować pakiety tłumienia dotyczące tego celu. Po upłynięciu tego okresu host przez kolejny okres nasłuchuje, czy pojawią się kolejne pakiety tłumienia. Jeśli jakiś przyjdzie, to oznacza, że linia nadal jest przeciążona, więc host jeszcze bardziej redukuje przepływ i ponownie zaczyna ignorować pakiety tłumienia. Jeśli podczas okresu nasłuchiwania nie przyjdzie żaden pakiet tłumienia, host może ponownie zwiększyć przepływ danych. Sprzężenie zwrotne działające w pośredni sposób w tym protokole może pomagać w zapobieganiu przeciążeniom, nie dławiąc zarazem żadnego przepływu, dopóki nie pojawią się problemy.
Hosty mogą redukować ruch, na przykład, przez regulację parametrów swoich zasad rozmiaru okna. Zwykle pierwszy pakiet tłumiący powoduje zredukowanie szybkości transmisji danych do połowy poprzedniej wartości, następny do 0,25 i tak dalej. Zwiększanie przepływu odbywa się w mniejszych krokach, aby zapobiec szybkiemu ponownemu wystąpieniu przeciążenia.
Pojawiło się kilka propozycji odmian tego algorytmu kontroli przeciążeń. Na przykład routery mogą utrzymywać kilka poziomów. W zależności od tego, który poziom został przekroczony, pakiet tłumienia może zawierać łagodne ostrzeżenie, poważne ostrzeżenie lub ultimatum.
Kolejna odmiana polega na użyciu jako sygnału wyzwalającego długości kolejki lub stopnia wykorzystania buforów zamiast wykorzystania linii. Oczywiście przy użyciu tej miary może być wykorzystane takie samo wykładnicze ważenie jak dla u.
Przy dużych szybkościach i długich dystansach wysłanie pakietu tłumiącego do źródła nie sprawdza się zbyt dobrze, ponieważ reakcja jest zbyt powolna. Weźmy na przykład hosta z San Francisco (router A na rysunku 5.25), który wysyła transmisję do hosta w Nowym Jorku (router D z rysunku 5.25) z szybkością 155 Mb/s. Jeśli w hoście nowojorskim zacznie brakować buforów, to dotarcie pakietu tłumienia z powrotem do San Francisco, żądającego spowolnienia transmisji zajmie około 30 milisekund. Propagację pakietu tłumienia przedstawiają drugi, trzeci i czwarty) krok z rysunku 5.25 (a). Podczas tych 30 ms zostało wysłanych kolejne 4,6 megabita danych. Nawe jeśli host w San Francisco natychmiast przestanie nadawać, te 4,6 megabita w kanale nadal będzie napływać i trzeba będzie sobie z nimi poradzić. Dopiero na siódmym schemacie z rysunku 5.25 (a router z Nowego Jorku zauważy wolniejszy napływ danych.
Alternatywne rozwiązanie polega na tym, że pakiet tłumienia zaczyna działać już w każdym przeskoku, jak na rysunku 5.25 (b). Tutaj natychmiast po dotarciu pakietu tłumienia do F od tego rutera żąda się redukcji przepływu do D. Będzie to wymagało poświęcenia przez F dodatkowych buforów na tę transmisję, ponieważ źródło nadal pracuje na pełnych obrotach, lecz przynosi D natychmiastową ulgę (jak lekarstwo od bólu głowy z reklam telewizyjnych). W następnym kroku pakiet tłumienia dociera do E, co każe E ograniczyć przepływ do F. Zwiększa to zapotrzebowanie na bufory routera E, lecz natychmiast odciąża F. Na koniec pakiet tłumienia dociera do A i przepływ autentycznie maleje.
W sumie ten schemat tłumienia skok po skoku (ang. hop-by-hop) zapewnia szybkie odciążenie w punkcie przeciążenia kosztem zużycia dodatkowego miejsca w buforach w poprzednich węzłach na trasie transmisji. W ten sposób przeciążenie może zostać stłumione w zarodku bez tracenia jakichkolwiek pakietów. Ideę tę omówili szczegółowo razem z wynikami symulacji Mishra i Kanakia (1992).
Gdy żadna z powyższych metod nie spowoduje zniknięcia przeciążenia, routery mogą wytoczyć ciężkie działa — zrzut obciążenia (ang. load shedding). To określenie jest eleganckim sposobem powiedzenia, że routery zalane pakietami, których nie są w stanie obsłużyć, po prostu wyrzucają te pakiety. Termin wziął się ze świata elektroenergetyki, gdzie oznacza rozmyślne odłączanie pewnych obszarów, aby uchronić całą sieć przed zapaścią w porach, gdy zapotrzebowanie na energię znacznie przekracza dostępne zasoby.
Router tonący w pakietach może po prostu wybierać losowo pakiety do odrzucenia, lecz zwykle potrafi wybierać lepiej. Wybór pakietu do odrzucenia może zależeć od uruchomionych aplikacji. W transferze plików stary pakiet ma większą wartość niż nowy, ponieważ odrzucenie pakietu nr 6 i zachowanie pakietów od 7 do 10 spowoduje powstanie luki u odbiorcy, która może zmusić do retransmisji pakietów od 6 do 10 (jeśli odbiornik rutynowo odrzuca pakiety przychodzące poza kolejnością). W pliku zajmującym 12 pakietów odrzucenie pakietu nr 6 może wymagać retransmisji od 6 do 12, podczas gdy odrzucenie pakietu nr 10 może wymagać retransmisji tylko od 10 do 12. Z drugiej strony w multimediach nowy pakiet jest ważniejszy od starego. Pierwsza zasada (starszy lepszy od nowego) nazywana jest często winem, a druga (nowy lepszy od starego) to mleko.
Dalsze zwiększenie inteligencji algorytmu wymaga współpracy nadajników. Dla wielu aplikacji niektóre pakiety są ważniejsze od innych. Na przykład niektóre algorytmy kompresji wideo okresowo przesyłają całą klatkę, a następnie wysyłają kolejne klatki w postaci różnic w stosunku do ostatniej pełnej klatki. W tym przypadku odrzucenie pakietu niosącego informacje różnicowe będzie lepsze niż odrzucenie tego, który jest częścią pełnej klatki. Innym przykładem może być transmisja dokumentu zawierającego tekst ASCII i obrazy. Utrata linii pikseli w obrazie jest znacznie mniej szkodliwa niż utrata wiersza tekstu.
Aby zaimplementować inteligentną zasadę odrzucania pakietów, aplikacje muszą oznaczać swoje pakiety klasami priorytetu, by wskazać ich ważność. W takich warunkach, gdy zajdzie potrzeba odrzucenia pakietu, routery najpierw mogłyby odrzucać pakiety z najniższej klasy, następnie kolejnej o stopień wyższej i tak dalej. Oczywiście nikt tego nie zrobi, jeśli nie znajdzie się jakaś istotna zachęta do oznaczania ważności pakietów inaczej niż „BARDZO WAŻNY — NIE WYRZUCAĆ POD ŻADNYM POZOREM!".
Zachęta może być finansowa — transmisja pakietów o niskim priorytecie może być tańsza. Zamiast tego nadajnikom można też pozwalać na wysyłanie pakietów o niskim priorytecie przy małym obciążeniu sieci, lecz ze wzrostem obciążenia będą odrzucane, co zachęci użytkowników do zaprzestania ich wysyłania.
Inna opcja może polegać na zezwoleniu hostom na przekraczanie limitu ustalonego w umowie negocjowanej podczas zestawiania obwodu wirtualnego (tzn. będą mogły korzystać z większego pasma niż dozwolone), lecz pod warunkiem, że cały dodatkowy ruch zostanie oznaczony jako mający niski priorytet. Taka strategia jest niegłupia, ponieważ pozwala znacznie skuteczniej wykorzystać bezczynne zasoby. Hosty mają prawo ich używać, dopóki nikt inny nie jest nimi zainteresowany, lecz bez nabywania prawa do nich w okresach dużego obciążenia.
Dobrze wiadomo, że zareagowanie na przeciążenie natychmiast po wykryciu jest bardziej skuteczne niż wtedy, gdy pozwolimy mu narobić bigosu i dopiero wtedy będziemy próbować poradzić sobie z nim. To spostrzeżenie doprowadziło do powstania pomysłu odrzucania pakietów jeszcze przed całkowitym wyczerpaniem miejsca w buforach. Popularny służący do tego algorytm nosi nazwę RED (Random Early Detection — losowe wczesne wykrywanie) (Floyd i Jacobson, 1993). W niektórych protokołach transportowych (również w TCP) w odpowiedzi na utratę pakietów źródło spowalnia nadawanie. Do zastosowania takiej metody doprowadziło rozumowanie, że TCP został zaprojektowany dla sieci kablowych, które są bardzo niezawodne, więc pakiety tracą się głównie z powodu przepełnienia buforów, a nie błędów transmisji. Ten fakt można wykorzystać do walki z przeciążeniami.
Odrzucanie przez routery pakietów jeszcze zanim sytuacja stanie się beznadziejna (stąd „wczesne" wykrywanie w nazwie) oznacza, że jest czas na podjęcie działania, zanim będzie za późno. Aby zdecydować, kiedy przychodzi pora zacząć odrzucać pakiety, routery rejestrują na bieżąco średnią wartość długości swoich kolejek. Gdy średnia długość kolejki w jakiejś linii przekracza ustaloną granicą uznaje się, że linia jest przeciążona i router podejmuje jakieś działania.
Ponieważ router nie może raczej odróżnić, które źródło powoduje najwięcej kłopotów, wybranie pakietu na oślep z kolejki, która zainicjowała działanie, jest chyba równie dobrym rozwiązaniem jak każde inne.
Jak router może poinformować źródło o problemie? Jedna z metod, opisana przed chwilą polega na odesłaniu do niego pakietu tłumiącego. Problem z takim podejściem tkwi w tym, że jeszcze bardziej obciąża i tak przeciążoną sieć. Inna strategia polega po prostu na odrzuceniu pakietu bez zgłaszania tego faktu. Źródło w końcu zauważy brak potwierdzenia i podejmie jakieś działanie. Ponieważ wie, że pakiety tracą się głównie z powodu przeciążeń i odrzucania, zareaguje przez spowolnienie transmisji zamiast bardziej usilnego ponawiania prób. Taka pośrednia forma sprzężenia zwrotnego działa tylko wtedy, gdy źródła reagują na utratę pakietów spowalnianiem swojej transmisji. W sieciach bezprzewodowych, gdzie większość strat bierze się z zakłóceń w łączu radiowym, takiego podejścia nie można stosować.
W zastosowaniach takich jak strumieniowe przesyłanie dźwięku i wideo, nie liczy się, czy doręczenie pakietu zajmie 20 czy 30 milisekund, dopóki czas podróży pozostaje stały. Wahania (tzn. odchylenie standardowe) czasów docierania pakietów noszą nazwę fluktuacji (mg.jitter). Wysokie fluktuacje, na przykład docieranie jednych pakietów po 20 ms, a innych po 30 ms, powodują nierówną jakość dźwięku i obrazu. Fluktuacje przedstawia rysunek 5.26. Z drugiej strony ustalenie, że 99% pakietów będzie doręczonych z opóźnieniem w zakresie od 24,5 ms do 25,5 ms, może być do przyjęcia.
Wybrany zakres musi być oczywiście realny. Musi brać pod uwagę czas podróży zależny od szybkości światła, minimalne opóźnienia w routerach i być może zostawić trochę luzu na jakieś nieuniknione opóźnienia.
Fluktuacje można ograniczyć przez obliczenie spodziewanego czasu podróży dla każdego przeskoku na trasie. Gdy pakiet dociera do routera, ten sprawdza, o ile pakiet jest przyspieszony
RYSUNEK 5.26. (a) Wysokie fluktuacje, (b) Niskie fluktuacje
lub opóźniony względem planu. Informacje te są zapisywane w pakiecie i aktualizowane po każ dym przeskoku. Jeśli pakiet dotarł przed czasem, zostaje wstrzymany wystarczająco długo, b; wrócił do harmonogramu. Jeśli jest spóźniony, router próbuje wysłać go jak najszybciej.
W istocie algorytm ustalania, który z kilku pakietów rywalizujących o linię wyjściową powinien pójść następny, może zawsze wybierać pakiet najbardziej spóźniony względem harmonogramu. W ten sposób pakiety, które przyszły przed czasem, zostają spowolnione, a pakiety spóźnione są przyspieszane, co w obu przypadkach redukuje poziom fluktuacji.
W niektórych aplikacjach, na przykład wideo na żądanie, fluktuację można wyeliminować przez buforowanie w odbiorniku, a następnie pobieranie danych do wyświetlania z bufora zamiast brania ich w czasie rzeczywistym z sieci. Jednakże w innych zastosowaniach, zwłaszcza wymagających interakcji w czasie rzeczywistym pomiędzy użytkownikami, na przykład w telefonii internetowej i wideokonferencjach, opóźnienie nieuniknione przy buforowaniu jest nie do przyjęcia.
Kontrola przeciążeń jest obszarem, w którym prowadzi się intensywne badania. Najświeższy stan wiedzy podsumowują Gevros i inni (2001).
Techniki, które przedstawiliśmy w poprzednich punktach, służą do redukowania przeciążeń i poprawienia wydajności sieci. Jednakże rozwój multimedialnych zastosowań sieci powoduje, że takie doraźne środki nie wystarczają. Potrzebne są poważne próby zagwarantowania jakości usług przez konstrukcję sieci i protokołów. W poniższych punktach będziemy kontynuować analizę wydajności sieci, lecz z większym naciskiem na metody zapewnienia jakości usług dopasowanych d potrzeb aplikacji. Należy jednak z góry zastrzec, że wiele z tych idei nadal ulega zmianom.
Strumień pakietów ze źródła do celu nosi nazwę przepływu (ang. flow). W sieci połączeniowej wszystkie pakiety należące do przepływu podążają tą samą trasą; w sieci bezpołączeniowej mogą podążać różnymi trasami. Potrzeby każdego przepływu można opisać przez cztery podstawowe parametry: niezawodność, opóźnienie, fluktuację i pasmo. Łącznie określają jakość usługi (QoS — Quality of Service) wymaganą przez przepływ. Tabela 5.3 przedstawia kilka typowych zastosowań i rygorystyczność ich wymogów.
TABELA 5.3.
Rygorystyczność różnych wymogów jakości usług
Aplikacja | Niezawodność | Opóźnienie | Fluktuacja | Pasmo |
---|---|---|---|---|
Wysoka | Niska | Niska | Niska | |
Transfer plików | Wysoka | Niska | Niska | Średnia |
Dostęp do WWW | Wysoka | Średnia | Niska | Średnia |
Zdalne logowanie | Wysoka | Średnia | Średnia | Niska |
Audio na żądanie | Niska | Niska | Wysoka | Średnia |
Wideo na żądanie | Niska | Niska | Wysoka | Wysoka |
Telefonia | Niska | Wysoka | Wysoka | Niska |
Wideokonferencje | Niska | Wysoka | Wysoka | Wysoka |
Pierwsze cztery aplikacje kładą duży nacisk na niezawodność. Żaden bit nie powinien być błędny. Cel ten osiąga się zwykle przez dodanie sumy kontrolnej do każdego pakietu i jej weryfikację u celu. Jeśli pakiet został po drodze uszkodzony, nie jest potwierdzany i w końcu zostanie ponownie przesłany. Taka strategia zapewnia wysoką niezawodność. W czterech pozostałych aplikacjach (audio i wideo) błędy są tolerowane, więc sumy kontrolne nie są obliczane ani weryfikowane.
Aplikacje wymagające przesyłu plików, łącznie z pocztą elektroniczną i wideo, nie są wrażliwe na opóźnienia. Jeśli wszystkie pakiety opóźnią się jednakowo o kilka sekund, nie stanie się nic złego. Aplikacje interaktywne, takie jak przeglądanie WWW i zdalne logowanie, są bardziej wrażliwe na opóźnienia. Zastosowania w czasie rzeczywistym, takie jak telefonia i wideokonferencje, mają ścisłe wymogi co do opóźnień. Gdyby wszystkie słowa w rozmowie telefonicznej były opóźnione o dokładnie 2,000 sekundy, użytkownicy uznaliby połączenie za nie do przyjęcia. Z drugiej strony odtwarzanie plików audio lub wideo z serwera nie wymaga niskiego opóźnienia.
Pierwsze trzy aplikacje nie są wrażliwe na docieranie pakietów w nieregularnych odstępach czasu. Zdalne logowanie w pewnym stopniu jest na to wrażliwe, ponieważ znaki na ekranie pojawiałyby się paczkami w razie poważnych fluktuacji w połączeniu. Wideo, a zwłaszcza audio, jest wyjątkowo wrażliwe na fluktuacje. Gdy użytkownik ogląda wideo przez sieć i ramki są opóźnione o dokładnie 2,000 sekundy, to niczemu nie przeszkadza. Lecz gdyby czas transmisji wahał się losowo od 1 do 2 sekund, efekt byłby okropny. W przypadku dźwięku słyszalne są fluktuacje trwające nawet kilka milisekund.
Oprócz tego wszystkiego aplikacje różnią się zapotrzebowaniem na pasmo; e-mail i zdalne logowanie nie potrzebują wiele, lecz wideo we wszelkich postaciach wymaga bardzo dużego pasma.
W sieciach ATM przepływ dzielony jest na cztery ogólne kategorie, zależnie od wymogów QoS:
Stała szybkość transmisji bitów (np. telefonia).
Zmienna szybkość transmisji bitów w czasie rzeczywistym (np. wideokonferencje z kompresją).
Zmienna szybkość transmisji bitów nie w czasie rzeczywistym (np. oglądanie filmu przez Internet).
Dostępna szybkość transmisji (np. transfer plików).
Kategorie te przydają się również w innych zastosowaniach i innych sieciach. Stała szybkość transmisji jest próbą symulacji kabla zapewniającego stałą przepustowość i stałe opóźnienie. Zmienna szybkość transmisji występuje w przypadku kompresji wideo, w której niektóre klatki są bardziej skompresowane od innych. Inaczej mówiąc, przesłanie klatki zawierającej mnóstwo szczegółów może wymagać przesłania wielu bitów, podczas gdy obraz białej ściany może dać się doskonal skompresować. Dostępna szybkość transmisji jest przeznaczona dla aplikacji takich jak e-mai niewrażliwych na opóźnienia i fluktuacje.
Wiemy już coś o wymogach QoS, więc pora na pytanie, jak je spełnić? No cóż, zacznijmy od tego że nie istnieje żadna pojedyncza technika, która zapewnia wydajne i niezawodne QoS w optymalny sposób. Zamiast tego opracowano szereg różnych technik, przy czym praktyczne rozwiązania często łączą dwie lub więcej metod. Przyjrzyjmy się teraz kilku technikom, których projektanci systemów używają do otrzymania jakości usług.
Łatwym rozwiązaniem jest zapewnienie takiej wydajności routerów, miejsca w buforach i pasma że pakiety będą przechodzić z łatwością. Problemem są koszty. W miarę upływu czasu i lepszego orientowania się przez projektantów, ile zasobów wystarcza, ta technika może nawet stać się praktyczna. Do pewnego stopnia system telefoniczny jest przewymiarowany. Rzadko zdarza się, że pod niesiemy słuchawkę i nie usłyszymy natychmiast sygnału. System ma po prostu na tyle dużą pojemność, że żądanie może zostać zawsze spełnione.
Przepływy mogą być przed doręczeniem buforowane po stronie odbiornika. Buforowanie ich nie wpływa na niezawodność i przepustowość, zwiększa opóźnienie, lecz zarazem wygładza fluktuacje. W audio i wideo na żądanie fluktuacje są głównym problemem, więc ta technika jest bardzo efektywna.
Widzieliśmy różnicę pomiędzy wysokimi i niskimi fluktuacjami na rysunku 5.26. Rysunek 5.27 przedstawia strumień pakietów dostarczanych ze znacznymi fluktuacjami. Pakiet 1 został wysłany z serwera w chwili t = 0 s i dotarł do klienta w chwili t = 1 s. Pakiet 2 miał większe opóźnienie i dotarł po 2 sekundach. Przychodzące pakiety są buforowane w komputerze klienckim.
RYSUNEK 5 .27. Wygładzanie strumienia wyjściowego przez buforowanie pakietów
W chwili t = 10 s zaczyna się odtwarzanie. W tym momencie w buforze są już pakiety od 1 do 6, więc mogą być wyjmowane z bufora w stałych odstępach czasu, aby zapewnić płynne odtwarzanie. Niestety, pakiet 8 został tak opóźniony, że nie jest dostępny w chwili, gdy nadchodzi pora jego odtworzenia, więc odtwarzanie musi się zatrzymać, co powoduje irytującą przerwę w muzyce lub filmie. Ten problem można złagodzić przez jeszcze większe opóźnienie odtwarzania, aczkolwiek wymaga to większego bufora. Komercyjne strony WWW zawierające audio lub wideo korzystają z odtwarzaczy, które przed rozpoczęciem odtwarzania buforują około 10 sekund.
W powyższym przykładzie źródło wysyłało pakiety w jednakowych odstępach czasu, lecz w innych przypadkach pakiety mogą być nadawane nieregularnie, co może powodować przeciążenia sieci. Niejednorodna transmisja zdarza się często, gdy serwer obsługuje jednocześnie wiele strumieni, pozwalając zarazem na inne działania, na przykład szybkie przewijanie w przód i w tył, uwierzytelnianie użytkowników i tak dalej. Ponadto zastosowane tu podejście (buforowanie) nie zawsze jest możliwe, na przykład w wideokonferencjach. Gdyby jednak można było coś zrobić, aby serwer (ogólnie host) nadawał ze stałą szybkością jakość usługi poprawiłaby się. Przyjrzymy się teraz technice zwanej kształtowaniem ruchu, która wygładza ruch po stronie serwera, a nie klienta.
Kształtowanie ruchu oznacza regulację przeciętnej szybkości (i impulsowości) transmisji danych. W przeciwieństwie do niego protokoły z oknem przesuwnym, które poznaliśmy wcześniej, ograniczają objętość danych będących w danej chwili w drodze, a nie szybkość wysyłania. Po nawiązaniu połączenia użytkownik i podsieć (czyli klient i operator) uzgadniają określony wzorzec transmisji (czyli kształt) dla tego obwodu. Czasem nazywamy to umową o poziomie usług (ang. sernice level agreement). Dopóki klient trzyma się swojej strony umowy i wysyła pakiety tylko zgodnie z ustalonym kontraktem, operator obiecuje doręczenie ich wszystkich rozsądnie szybko. Kształtowanie ruchu zmniejsza przeciążenia i pomaga operatorowi wypełnić te zobowiązania. Umowy tego typu nie są ważne przy przesyłaniu plików, lecz mają ogromne znaczenie przy transmisji danych w czasie rzeczywistym, takich jak połączenia audio i wideo, które mają surowe wymogi względem jakości usług.
Przez kształtowanie ruchu klient mówi do operatora: „Mój wzorzec transmisji wygląda tak i tak, potrafisz sobie z nim poradzić?". Jeśli operator zgodzi się, pojawia się problem, jak ma sprawdzić, czy klient postępuje zgodnie z umową i co zrobić, jeśli nie. Monitorowanie przepływu transmisji nosi nazwę nadzoru ruchu (ang. trafficpolicing). Zgoda na kształt ruchu i późniejszy nadzór nad nim są łatwiejsze w podsieciach obwodów wirtualnych niż w podsieciach datagramowych. Jednak nawet w podsieciach datagramowych można zastosować te same idee do połączeń w warstwie transportowej.
Wyobraźmy sobie wiadro z niewielkim otworkiem w dnie, jak na rysunku 5.28 (a). Nieważne, jak szybko woda wlewa się do wiadra, wypływ odbywa się ze stałą szybkością p, gdy w wiadrze jest woda, lub zerową gdy wiadro jest puste. Poza tym, gdy wiadro jest pełne, dodatkowa wlewana do niego woda przeleje się brzegiem i zostanie utracona (tzn. nie pojawi się w wylotowym strumyku).
Tę samą ideę można zastosować do pakietów, jak na rysunku 5.28 (b). Ideowo każdy host jest podłączony do sieci przez interfejs zawierający dziurawe wiadro, tzn. wewnętrzną kolejkę o skończonej długości. Gdy pakiet przychodzi do pełnej kolejki, zostaje odrzucony. Inaczej mówiąc, gdy jeden lub więcej procesów w hoście usiłuje wysłać pakiet, gdy w kolejce znajduje się już ich maksymalna liczba, to nowy pakiet zostaje bezceremonialnie wyrzucony. Taki mechanizm może być wbudowany w interfejs sprzętowy lub symulowany przez system operacyjny hosta. Został on po raz pierwszy zaproponowany przez Turnera (1986) i nosi nazwę algorytmu cieknącego wiadra (ang. leaky bucket algorithm). W rzeczywistości nie jest to nic innego niż jednoserwerowy system kolejkowania ze stałym czasem usługi.
Host ma prawo wysłać w sieć jeden pakiet na takt zegara. Ponownie może to wymuszać karta sieciowa lub system operacyjny. Taki mechanizm przekształca nierówny przepływ pakietów pochodzących z procesów użytkownika w hoście na równy przepływ pakietów do sieci, wygładzając impulsy i poważnie zmniejszając ryzyko przeciążeń.
Gdy pakiety mają tę samą wielkość (np. komórki ATM), algorytm może być używany jak w powyższym opisie. Jeśli jednak używane są pakiety o różnej długości, często lepiej jest zezwalać na stałą liczbę bajtów na takt, zamiast jeden pakiet. Wobec tego, jeżeli reguła będzie mówić o 1024 bajtach na takt, to w jednym takcie będzie mógł zostać wysłany jeden 1024-bajtowy pakiet, dwa 512-bajtowe, cztery 256-bajtowe i tak dalej. Jeśli liczba pozostałych bajtów jest zbyt niska, kolejny pakiet musi czekać na następny takt.
Implementacja oryginalnego algorytmu cieknącego wiadra jest łatwa. Cieknące wiadro składa się ze skończonej kolejki. Gdy przychodzi pakiet, to jeśli jest miejsce w kolejce, zostaje do niej dołączony; w przeciwnym razie jest odrzucany. W każdym takcie zegara zostaje wysłany jeden pakiet (o ile kolejka nie jest pusta).
Algorytm cieknącego wiadra z liczeniem bajtów jest implementowany niemal identycznie. W każdym takcie zegara inicjuje się licznik z wartością n. Jeśli pierwszy pakiet w kolejce ma mniej bajtów niż wynosi bieżąca wartość licznika, to zostaje wysłany, a licznik jest dekrementowany o tę liczbę bajtów. Dodatkowe pakiety mogą być wysyłane, dopóki licznik ma wystarczająco wysoką wartość. Gdy jego wartość spadnie poniżej długości następnego pakietu w kolejce, transmisja jest wstrzymywana aż do następnego taktu, gdy wartość licznika pozostających bajtów jest przywracana do n i przepływ może odbywać się dalej.
Aby lepiej zrozumieć przykład cieknącego wiadra, wyobraźmy sobie, że komputer potrafi generować dane z szybkością 25 milionów bajtów na sekundę (200 Mb/s) i że sieć również działa z tą szybkością. Jednakże routery mogą przyjmować dane tak szybko tylko przez krótki czas (zasadniczo dopóki nie zapełnią się im bufory). Na dłuższą metę najlepiej działają z szybkością nieprzekraczającą2 milionów bajtów na sekundę. Załóżmy teraz, że dane przychodzą w paczkach po 1 milionie bajtów, jedna paczka o długości 40 ms na sekundę. Aby ograniczyć średnią szybkość transmisji do 2 Mb/s, musielibyśmy użyć cieknącego wiadra o p = 2 MB/s i pojemności C równej 1 MB. Oznacza to, że paczki danych do 1 MB mogą być obsługiwane bez utraty danych i że zostaną rozłożone na 500 ms każda, niezależnie od szybkości, z którą przychodzą.
Rysunek 5.29 (a) przedstawia wprowadzenie danych do dziurawego wiadra przez 40 ms z szybko-ścią25 MB/s. Na rysunku 5.29 (b) dane wypływają ze stałą szybkością 2 Mb/s przez 500 ms.
RYSUNEK 5.29. (a) Wejście do cieknącego wiadra, (b) Wyjście z cieknącego wiadra. Wyjścia z wiader żetonów o pojemności (c) 250 kB, (d) 500 kB i (e) 750 kB. (f) Wyjście z wiadra żetonów 500 kB przez cieknące wiadro 10 MB/s
Algorytm cieknącego wiadra wymusza stały wzorzec wysyłania danych ze średnią prędkością, niezależnie od tego, jak impulsowy charakter ma ruch wchodzący. W wielu zastosowaniach lepiej jest pozwolić na pewne przyspieszenie transmisji, gdy przychodzą duże paczki danych, więc potrzebny jest bardziej elastyczny algorytm, najlepiej taki, który nigdy nie traci danych. Jednym z takich algorytmów jest algorytm wiadra żetonów (ang. token bucket algorithm). W nim cieknące wiadro zawiera żetony generowane przez zegar z szybkością 1 żeton na AT sekund. Na rysunku 5.30 (a) widać wiadro zawierające trzy żetony oraz pięć pakietów czekających na transmisję. Aby pakiet mógł zostać wysłany, musi przechwycić i zniszczyć jeden żeton. Na rysunku 5.30 (b) widzimy, że trzy pakiety przeszły, lecz dwa dalej czekają na wygenerowanie żetonów.
RYSUNEK 5.30. Algorytm wiadra żetonów: (a) przed, (b)po
Algorytm wiadra żetonów umożliwia kształtowanie ruchu w inny sposób niż algorytm cieknącego wiadra. Algorytm cieknącego wiadra nie pozwala bezczynnym hostom oszczędzać uprawnień do późniejszego wysłania dużej porcji danych. Algorytm wiadra żetonów pozwala na oszczędzanie aż do maksymalnej pojemności wiadra n. Właściwość ta oznacza, że można za jednym razem wysłać wiązkę maksymalnie n pakietów, co pozwala na pewną impulsowość strumienia wyjściowego i zapewnia szybszą reakcję na nagłe porcje danych.
Druga różnica pomiędzy tymi dwoma algorytmami polega na tym, że algorytm wiadra żetonów odrzuca żetony (czyli zdolność przepustową), gdy wiadro przepełni się, lecz nigdy nie odrzuca pakietów, w przeciwieństwie do algorytmu cieknącego wiadra.
Tutaj również możliwa jest drobna modyfikacja, w której każdy żeton reprezentuje prawo do wysłania nie jednego pakietu, lecz k bajtów. Pakiet może zostać przesłany tylko wtedy, gdy dostępna jest wystarczająca liczba żetonów pokrywająca jego długość w bajtach. Cząstkowe żetony zostają zachowane do przyszłego wykorzystania.
Oba algorytmy mogą też posłużyć do wygładzenia ruchu pomiędzy routerami, nie tylko regulacji wyjścia hostów, jak w naszych przykładach. Jednakże jedna wyraźna różnica polega na tym, że wiadro żetonów regulujące hosta może zatrzymać nadawanie z hosta, gdy tak zdecydują reguły. Rozkazanie routerowi, aby przestał nadawać, podczas gdy na wejście przychodzą kolejne pakiety, może spowodować utratę danych.
Implementacja podstawowego algorytmu wiadra żetonów wymaga zaledwie zmiennej liczącej żetony. Licznik jest inkrementowany co AT\ dekrementowany przy wysłaniu każdego pakietu. Gdy licznik dojdzie do zera, pakietów nie można wysyłać. W odmianie z liczeniem bajtów licznik jest zwiększany o k bajtów co A7M dekrementowany o długość każdego wysłanego pakietu.
Wiadro żetonów pozwala na wiązki pakietów, lecz tylko do ustalonej maksymalnej długości. Spójrzmy na przykład na rysunek 5.29 (c). Mamy tu wiadro żetonów o pojemności 250 kB. Żetony przychodzą z szybkością pozwalającą na wysyłanie danych z 2 MB/s. Zakładając, że wiadro żetonów jest pełne w chwili dotarcia porcji 1 MB, może opróżniać się z pełną szybkością 25 MB/s przez około 11 ms. Następnie musi ograniczyć transmisję do 2 MB/s, dopóki cała porcja danych nie zostanie wysłana.
Obliczenie długości wiązki nadawanej z maksymalną szybkością jest nieco podchwytliwe. Nie wystarczy podzielić 1 MB przez 25 MB/s, ponieważ w trakcie wysyłania wiązki przychodzą kolejne żetony. Jeśli oznaczymy długość wiązki w sekundach literą S, pojemność wiadra C bajtów, szybkość generowania żetonów p bajtów na sekundę, a maksymalną szybkość wyjściową transmisji M bajtów/s, to widać, że wiązka wyjściowa zawiera maksymalnie C + pS bajtów. Wiemy też, że liczba bajtów w wiązce o długości 5 i maksymalnej szybkości transmisji wynosi MS. Stąd mamy:
C+pS=MS
Możemy przekształcić to równanie, aby otrzymać S = C/(M- p). Dla naszych parametrów: C = 250 kB, M = 25 MB/s i p = 2 MB/s, otrzymamy czas wiązki około 11 ms. Rysunki 5.29 (d) i (e) przedstawiają wiadro żetonów o pojemności, odpowiednio, 500 kB i 750 kB.
Potencjalny problem z algorytmem wiadra żetonów polega na tym, że ponownie pozwala na duże wiązki danych, mimo że maksymalny czas trwania wiązki można regulować przez odpowiedni dobór p i M. Często pożądane jest ograniczenie szczytowej szybkości, lecz bez wracania do niskiej wartości z algorytmu cieknącego wiadra.
Jednym ze sposobów wygładzenia transmisji jest wstawienie cieknącego wiadra po wiadrze żetonów. Przepustowość cieknącego wiadra powinna być wyższa niż p wiadra żetonów, ale niższa od maksymalnej szybkości sieci. Rysunek 5.29 (f) przedstawia wyjście z wiadra żetonów 500 kB, po którym następuje cieknące wiadro 10 MB/s.
Nadzór nad tymi wszystkimi schematami może być trochę kłopotliwy. Krótko mówiąc, sieć musi symulować algorytm i sprawdzać, czy host nie wysyła więcej pakietów lub bajtów niż ma prawo. Mimo to narzędzia te pozwalają formować ruch w sieci w przebiegi łatwiejsze do opanowania, aby wspomóc spełnianie wymogów jakości usług.
Zdolność do regulowania kształtu wchodzącego ruchu jest dobrym punktem wyjścia do zagwarantowania jakości usługi. Jednakże skuteczne wykorzystanie tych informacji oznacza w domyśle, że wszystkie pakiety przepływu powinny podążać tą samą trasą. Swobodne rozrzucenie ich po routerach utrudnia gwarantowanie czegokolwiek. W konsekwencji trzeba zestawić coś w rodzaju obwodu wirtualnego ze źródła do celu i wszystkie pakiety należące do przepływu muszą podążać tą trasą.
Gdy już otrzymamy konkretną trasę dla przepływu, staje się możliwe rezerwowanie zasobów wzdłuż trasy, aby zagwarantować dostępność wymaganej przepustowości. Potencjalnie rezerwować można trzy typy zasobów:
Pasmo.
Miejsce w buforach.
Czas procesora.
Pierwszy zasób (pasmo) jest najbardziej oczywisty. Jeśli przepływ wymaga 1 Mb/s, a linia wyjściowa ma zdolność przepustową 2 Mb/s, próba skierowania tą linią trzech takich przepływów nie uda się. Wobec tego rezerwowanie pasma oznacza, że nie należy zajmować żadnej linii wyjściowej większym przepływem niż może obsłużyć.
Drugim zasobem, którego często brakuje, jest miejsce w buforach. Przychodzący pakiet jest zwykle składowany w karcie sieciowej przez sam sprzęt. Następnie oprogramowanie routera musi skopiować go do bufora w pamięci RAM i wstawić do kolejki do wysłania wybraną linią wyjściową. Gdy żaden bufor nie jest dostępny, pakiet musi zostać odrzucony, ponieważ nigdzie nie ma na niego miejsca. Aby zapewnić dobrą jakość usługi, można zarezerwować bufory dla konkretnego przepływu, aby przepływ ten nie musiał rywalizować z innymi o miejsce w buforach. Gdy przepływ będzie potrzebował miejsca w buforze, zawsze będzie dostępne aż do jakiegoś określonego maksimum.
Czas procesora też jest cennym zasobem. Router wymaga pewnego czasu CPU, aby przetworzyć pakiet, więc może przetwarzać tylko określoną liczbę pakietów na sekundę. Zapewnienie, że procesor nie będzie przeciążony, jest niezbędne do szybkiego obsłużenia każdego pakietu.
Na pierwszy rzut oka może się wydawać, że jeśli przetworzenie pakietu zajmuje np. 1 µs, router może obsłużyć milion pakietów na sekundę. Obserwacja ta nie jest prawdziwa, ponieważ zawsze wystąpią jakieś okresy bezczynności z uwagi na statystyczne fluktuacje obciążenia. Jeśli CPU potrzebuje każdego swojego cyklu, aby wykonać swoją pracę, to utrata nawet kilku cykli z powodu okazyjnej bezczynności tworzy zaległości, których procesor nigdy nie nadrobi.
Jednakże nawet przy obciążeniu nieco niższym od teoretycznej wydajności kolejki mogą rosnąć i opóźnienia mogą występować. Spójrzmy na sytuację, w której pakiety przychodzą losowo ze średnią szybkością λ pakietów na sekundę. Czas procesora niezbędny do obsłużenia pakietu również jest losowy, a średnia wydajność przetwarzania wynosi u. pakietów na sekundę. Przy założeniu, że pakiety przychodzą i są obsługiwane z rozkładem Poissona, można udowodnić z użyciem teorii kolejek, że średnie opóźnienie T pakietu wynosi:
gdzie p = λ/µ jest wykorzystaniem procesora. Pierwszy czynnik, l/µ, jest czasem obsługi w przypadku braku rywalizacji. Drugi czynnik określa spowolnienie spowodowane przez rywalizację z innymi przepływami. Na przykład, jeśli λ= 950 000 pakietów na sekundę a µ = 1 000 000 pakietów na sekundę, to p = 0, 95 i średnie opóźnienie każdego pakietu będzie wynosić 20 µs zamiast 1 µs. Do czasu tego wlicza się zarówno kolejkowanie jak i obsługa, co widać z sytuacji, gdy obciążenie jest bardzo małe (λ/µ ~ 0). Jeśli na trasie przepływu będzie, powiedzmy, 30 routerów, to samo kolejkowanie wniesie 600µs opóźnienia.
Jesteśmy teraz na etapie, gdzie ruch wejściowy z jakiegoś przepływu jest dobrze ukształtowany i może Potencjalnie podążać jedną trasą, na której możemy z góry zarezerwować zasoby routerów. Gdy taki przepływ przychodzi do routera, ten musi zdecydować na podstawie swoich mocy przerobowych i zobowiązań, które już podjął wobec innych przepływów, czy przyjąć ten przepływ, czy odrzucić.
Decyzja o przyjęciu lub odrzuceniu przepływu nie jest prostą kwestią porównania pasma, buforów i czasu procesora, żądanych przez przepływ, z wolnymi mocami przerobowymi routera w tych trzech dziedzinach. To trochę bardziej skomplikowane. Zacznijmy od tego, że wprawdzie niektóre aplikacje mogą znać swoje zapotrzebowanie na pasmo, lecz niewiele spośród nich wie cokolwiek o czasie procesora, więc potrzebujemy przynajmniej innego sposobu opisania przepływów. Po drugie, niektóre aplikacje są o wiele bardziej tolerancyjne na spóźnienie od czasu do czasu niż inne. Na koniec, niektóre aplikacje mogą być gotowe do targowania się o parametry przepływu, a inne nie. Na przykład osoba oglądająca film, który zwykle ma 30 klatek na sekundę, może zgodzić się na zejście do 25 klatek na sekundę, jeśli nie ma pasma wystarczającego na 30 klatek/s. Podobnie można regulować liczbę pikseli na ramkę, pasmo sygnału dźwiękowego i inne właściwości.
Ponieważ w negocjowanie przepływu może być zaangażowanych wiele stron (nadawca, odbiorca i wszystkie routery po drodze), przepływ musi zostać precyzyjnie opisany pod względem konkretnych parametrów, które mogą być negocjowane. Zbiór takich parametrów nosi nazwę specyfikacji przepływu. Zwykle nadawca (tzn. serwer wideo) tworzy specyfikację przepływu, proponując parametry, których chciałby użyć. W trakcie podróży tej specyfikacji przez całą trasę każdy router sprawdzają i w razie potrzeby zmienia. Zmiany mogą polegać tylko na ograniczeniu przepływu, a nie na zwiększeniu (np. użycie niższej szybkości transmisji danych, a nie wyższej). Po dotarciu specyfikacji do końca trasy parametry mogą zostać ustalone.
Jako przykład tego, co może znaleźć się w specyfikacji przepływu, rozważmy sytuację z tabeli 5.4, która opiera się na RFC 2210 i 2211. Specyfikacja zawiera pięć parametrów, z których pierwszy, przepustowość wiadra żetonów, oznacza liczbę bajtów na sekundę umieszczanych w wiadrze. Jest to maksymalna długotrwała szybkość transmisji, jaką może utrzymać nadajnik, uśredniana dla dłuższego okresu.
TABELA 5.4.
Przykład specyfikacji przepływu
Parametr | Jednostka |
---|---|
Przepustowość wiadra żetonów | Bajty/s |
Pojemność wiadra żetonów | Bajty |
Szczytowa szybkość transmisji | Bajty/s |
Minimalny rozmiar pakietu | Bajty |
Maksymalny rozmiar pakietu | Bajty |
Drugi parametr oznacza rozmiar wiadra w bajtach. Jeśli, na przykład, przepustowość wiadra wynosi 1 Mb/s, a rozmiar wiadra 500 kB, wiadro może napełniać się w sposób ciągły przez 4 sekundy (jeśli nie występują transmisje). Każdy żeton wysłany po 4 sekundach będzie stracony.
Trzeci parametr, szczytowa szybkość transmisji, oznacza maksymalną tolerowaną szybkość transmisji, nawet przez bardzo krótkie okresy. Nadajnik nigdy nie może przekroczyć tej szybkości.
Dwa ostatnie parametry określają minimalną i maksymalną wielkość pakietu, łącznie z nagłówkami warstw transportowej i sieciowej (na przykład TCP i IP). Wielkość minimalna jest ważną ponieważ obsłużenie każdego pakietu, nawet najkrótszego, wymaga pewnego czasu. Router może poradzić sobie z 10 000 pakietów o wielkości 1 kB każdy na sekundę, lecz nie da rady obsłużyć w ciągu sekundy 100 000 pakietów po 50 bajtów, mimo że te reprezentują niższą szybkość transmisji danych. Maksymalna wielkość pakietu jest istotna z uwagi na wewnętrzne ograniczenia sieci, których nie można przekroczyć. Na przykład, jeśli część trasy przebiega przez Ethernet, maksymalny rozmiar pakietu będzie ograniczony do 1500 bajtów, niezależnie od możliwości reszty sieci.
Interesujące może być pytanie, jak router tworzy ze specyfikacji przepływu zbiór określonych rezerwacji zasobów. Mapowanie to jest zależne od implementacji i nie istnieją dla niego standardy, i Załóżmy, że router potrafi obsłużyć 100 000 pakietów na sekundę. Jeśli zostanie do niego zgłoszony'
przepływ 1 MB/s z minimalnym i maksymalnym rozmiarem pakietu równym 512 bajtów, to router może obliczyć, że z tego przepływu może otrzymać 2048 pakietów na sekundę. W takim przypadku musi zarezerwować na ten przepływ 2% czasu procesora, w miarę możliwości więcej, aby uniknąć długich opóźnień kolejkowania. Jeśli wewnętrzne zasady routera zabraniają przydzielania więcej niż 50% CPU (co oznacza dwukrotne przedłużenie opóźnień), i jeśli 49% jest już zajętych, to ten przepływ musi zostać odrzucony. Podobne obliczenia potrzebne są dla innych zasobów.
Im bardziej ścisła specyfikacja przepływu, tym większą ma użyteczność dla routerów. Jeśli specyfikacja mówi, że przepływ potrzebuje przepustowości wiadra żetonów równej 5 MB/s, lecz pakiety mogą mieć rozmiar od 50 do 1500 bajtów, to szybkość przesyłania pakietów może wahać się od 3500 do 105 000 pakietów na sekundę. Router może spanikować na widok tej drugiej liczby i odrzucić przepływ, podczas gdy przy minimalnym rozmiarze pakietu równym 1000 bajtów przepływ 5 MB/s mógłby zostać przyjęty.
Większość algorytmów routingu usiłuje znaleźć najlepszą trasę do każdego celu i wysyłać cały ruch do tego celu tą wybraną trasą. Inne podejście zaproponowane, aby zapewnić wyższą jakość usług, polega na dzieleniu ruchu do każdego celu na kilka tras. Ponieważ routery zwykle nie dysponują wiedzą o ruchu na skalę całej sieci, to jedynym realnym sposobem podziału ruchu na kilka tras jest wykorzystanie informacji dostępnych lokalnie. Prostą metodą może być podzielenie ruchu po równo lub zależnie od zdolności przepustowej wychodzących łączy. Są jednak też dostępne bardziej wyrafinowane algorytmy (Nelakuditi i Zhang, 2002).
Gdy router obsługuje dwa lub więcej przepływów, istnieje niebezpieczeństwo, że jeden przywłaszczy sobie zbyt dużo mocy przerobowych i trwale zablokuje wszystkie pozostałe przepływy. Przetwarzanie pakietów w kolejności przychodzenia oznacza, że agresywny nadajnik może przechwycić większość przepustowości routerów, przez które przechodzą jego pakiety, co pogorszy jakość usług dla innych. Aby udaremnić takie próby, opracowano szereg różnych algorytmów szeregowania pakietów (Bhatti i Crowcroft, 2000).
Jednym z pierwszych był algorytm równomiernego kolejkowania (ang. fair gueueing) (Nagle, 1987). Podstawowe założenie tego algorytmu polega na tym, że routery mają osobne kolejki dla każdej linii wyjściowej, po jednej na przepływ. Gdy linia zwalnia się, router skanuje kolejki cyklicznie, biorąc pierwszy pakiet z następnej kolejki. W ten sposób, gdy n hostów rywalizuje o daną linię wyjściową, każdy ma szansę wysłać jeden pakiet na n wysyłanych łącznie. Nadesłanie większej liczby pakietów nie poprawi tej proporcji.
Wprawdzie jest to jakiś początek, ale problem tego algorytmu polega na przyznawaniu większego pasma hostom wysyłającym duże pakiety. Demers i inni (1990) zasugerowali ulepszenie, w którym cykliczność odbywa się w sposób symulujący cykliczne nadawanie bajt po bajcie, a nie pakiet po pakiecie. Ta poprawiona wersja skanuje kolejki raz za razem, bajt po bajcie, dopóki nie znajdzie miejsca, w którym kończy się każdy pakiet. Następnie pakiety są sortowane według zakończeń i wysyłane w tej kolejności. Algorytm został zilustrowany na rysunku 5.31.
Na rysunku 5.31 (a) widzimy pakiety o długości od 2 do 6 bajtów. W pierwszym takcie (wirtualnym) zegara zostaje wysłany pierwszy bajt pakietu z linii A. Następny idzie pierwszy bajt Pakietu z linii B i tak dalej. Pierwszy kończy pakiet C po ośmiu taktach. Kolejność po posortowaniu przedstawia rysunek 5.31 (b). Jeśli nie przyjdą nowe pakiety, to te pakiety zostaną wysłane w przedstawionej kolejności, od C do A.
Problem z tym algorytmem polega na tym. że wszystkim hostom nadaje ten sam priorytet. W wielu sytuacjach dobrze jest przyznać serwerom wideo większe pasmo niż zwykłym serwerom plików, aby mogły wysyłać dwa lub więcej bajtów na takt. Ten zmodyfikowany algorytm nosi nazwę ważonego kolejkowania równomiernego (ang. weightedfair ąueueing) i jest stosowany powszechnie. Czasem waga jest równa liczbie przepływów wychodzących z komputera, dzięki czemu każdy proces otrzymuje równe pasmo. Wydajną implementację tego algorytmu opisali Shreedhar i Varghese (1995). Faktyczne przekazywanie pakietów przez router lub przełącznik coraz częściej odbywa się w sprzęcie (Elhanany i in., 2001).
W latach od 1995 do 1997 IETF włożył mnóstwo wysiłku w opracowanie architektury dla strumieniowego przesyłania multimediów. Prace te zaowocowały ponad dwoma tuzinami dokumentów RFC, zaczynając od RFC 2205 - 2210. Ogólne nazwy tych prac to: algorytmy oparte na przepływie (ang. flow-based algorithms) i usługi zintegrowane (ang. integrated semices). Zostały one przeznaczone zarówno dla aplikacji emisji pojedynczych, jak i grupowych. Przykładem pierwszej może być pojedynczy użytkownik pobierający strumieniowo wideo ze strony z wiadomościami. Drugim zastosowaniem może być grupa stacji telewizji cyfrowej nadających swoje programy jako strumienie pakietów IP dla wielu odbiorców w różnych lokalizacjach. Poniżej skupimy się na emisji grupowej, ponieważ pojedyncza jest specjalnym przypadkiem grupowej.
W wielu aplikacjach z transmisją grupową przynależność do grup może zmieniać się dynamicznie, na przykład użytkownik może dołączyć się do konferencji wideo, znudzić i przełączyć na brazylijską telenowelę lub kanał sportowy. W tych warunkach podejście polegające na rezerwowaniu z góry pasma przez nadajnik nie sprawdza się zbyt dobrze, ponieważ wymagałoby od każdego nadajnika śledzenia wszystkich zdarzeń dołączenia się lub opuszczenia przez widza kanału. W systemie zaprojektowanym do transmisji programu telewizyjnego do milionów abonentów ta metoda w ogóle nie nadawałaby się do użytku.
Głównym protokołem IETF dla architektury usług zintegrowanych jest RSVP (Resource reSerVation Protocol — protokół rezerwacji zasobów). Służy on do dokonywania rezerwacji; inne protokoły służą do wysyłania danych. RSVP umożliwia nadawanie przez wiele nadajników transmisji do licznych grup odbiorców, pozwala poszczególnym odbiorcom dowolnie przełączać kanały i optymalizuje wykorzystanie pasma, eliminując zarazem przeciążenia.
W najprostszej postaci protokół ten używa routingu rozsyłania grupowego z użyciem drzew częściowych, który przedstawiliśmy wcześniej. Każdej grupie jest przydzielany adres grupowy. Aby nadawać do grupy, nadajnik umieszcza jej adres w swoich pakietach. Następnie standardowy algorytm routingu rozsyłania grupowego tworzy drzewo częściowe obejmujące wszystkich członków grupy. Jedyna różnica w porównaniu ze zwykłym rozsyłaniem grupowym polega na odrobinie dodatkowych informacji rozsyłanych okresowo do grupy i informujących routery, aby utrzymywały w swojej pamięci pewne struktury danych.
Weźmy na przykład sieć z rysunku 5.32 (a). Hosty 1 i 2 są nadawcami grupowymi, a hosty 3. 4 i 5 odbiorcami transmisji grupowych. W tym przykładzie hosty nadające i odbierające są rozłączne, lecz w ogólnym przypadku te dwa zbiory mogą się nakładać. Drzewa rozsyłania grupowego dla hostów 1 i 2 przedstawiają odpowiednio rysunki 5.32 (b) i 5.32(c).
RYSUNEK 5.32. (a) Sieć. (b) Drzewo częściowe rozsyłania grupowego dla hosta 1. (c) Drzewo częściowe rozsyłania grupowego dla hosta 2
Aby zapewnić lepszy odbiór i eliminować przeciążenia, każdy odbiornik w grupie może wysłać komunikat rezerwujący w górę drzewa do nadajnika. Komunikat jest propagowany za pomocą algorytmu przekazywania z użyciem ścieżki powrotnej omówionego wcześniej. W każdym przeskoku router odnotowuje rezerwację i rezerwuje niezbędne pasmo. Jeśli nie dysponuje wystarczającymi wolnymi zasobami, zgłasza niepowodzenie. W chwili, gdy komunikat wraca do źródła, pasmo jest już zarezerwowane na całej trasie od nadajnika do odbiornika zgłaszającego żądanie.
Przykład takiej rezerwacji przedstawia rysunek 5.33 (a). Tutaj host 3 zażądał kanału do hosta 1. Po utworzeniu kanału pakiety mogą przepływać z 1 do 3 bez przeciążeń. Zobaczmy teraz, co stanie się, gdy host 3 zarezerwuje kanał do drugiego nadawcy, hosta 2, aby użytkownik mógł oglądać jednocześnie dwa programy telewizyjne. Zostaje zarezerwowana druga trasa, jak na rysunku 5.33 (b). Zwróćmy uwagę, że potrzebne są dwa odrębne kanały od hosta 3 do routera E, ponieważ nadawane są dwa niezależne strumienie.
Z powyższych powodów IETF opracował prostszy system zapewniania jakości usług, który może być w dużym stopniu zaimplementowany lokalnie w każdym routerze bez wstępnej konfiguracji i bez angażowania całej ścieżki. Podejście to nosi nazwę jakości usług opartej na klasach (ang. class-based), w przeciwieństwie do opartej na przepływach. IETF stworzy! standard architektury dla tej metody, nazwany usługami zróżnicowanymi (ang. dijferentiated services) i opisany w RFC 2474. 2475 i wielu innych. Omówimy go poniżej.
Usługi zróżnicowane może świadczyć zbiór routerów tworzących domenę administracyjną (np. dostawcy usług internetowych lub kompanii telekomunikacynej). Administracja definiuje zbiór klas usług z odpowiadającymi im regułami przekazywania dalej. Gdy klient zapisuje się na świadczenie usług zróżnicowanych, jego pakiety wchodzące do domeny mogą zawierać pole Typ usługi, przy czym niektórym klasom (np. usługa premium) są oferowane lepsze usługi niż innym. Od ruchu w obrębie klasy może być wymagana zgodność z jakimś określonym kształtem, takim jak cieknące wiadro z określoną szybkością opróżniania. Operator ze smykałką do interesów może pobierać dodatkową opłatę za każdy przesłany pakiet w usłudze premium lub pozwalać na przesłanie do N takich pakietów miesięcznie za stałą dodatkową opłatą. Taki mechanizm nie wymaga konfiguracji połączeń z góry, rezerwowania zasobów ani czasochłonnej negocjacji pomiędzy końcami połączenia dla każdego przepływu, jak było w usługach zintegrowanych. Dzięki temu usługi zróżnicowane są łatwe do zaimplementowania.
Usługi oparte na klasach występują też w innych branżach. Na przykład, firmy kurierskie często oferują dostawę w ciągu jednego, dwóch lub trzech dni. Linie lotnicze oferują klasę pierwszą klasę business i klasę „puszka śledzi,,. Nawet paryskie metro oferuje dwie klasy usług. W przypadku pakietów klasy mogą różnić się np. opóźnieniem, fluktuacjami i prawdopodobieństwem odrzucenia w przypadku przeciążenia (lecz raczej nie będą oferowane większe ramki Ethernet).
Aby wyraźniej odróżnić jakość usług opartą na przepływie od opartej na klasach, spójrzmy na przykład telefonii internetowej. W schemacie opartym na przepływie każda rozmowa telefoniczna otrzymuje własne zasoby i gwarancje. W schemacie opartym na klasach wszystkie równoczesne rozmowy telefoniczne otrzymują zbiorowo zasoby zarezerwowane dla klasy telefonii. Zasobów tych nie mogą zabrać pakiety z klasy przesyłu plików lub innych klas, lecz żadna rozmowa telefoniczna nie otrzymuje prywatnych zasobów zarezerwowanych tylko dla niej.
Wybór klas usług należy do każdego operatora z osobna, lecz ponieważ pakiety są często przekazywane pomiędzy podsieciami obsługiwanymi przez różnych operatorów, IETF pracuje nad definicją klas usług niezależnych od sieci. Najprostszą klasą jest przekazywanie ekspresowe (ang. expedited forwarding), opisane w RFC 3246, więc zaczniemy od niej.
Idea przekazywania ekspresowego jest bardzo prosta. Dostępne są dwie klasy usług: zwykła i ekspresowa. Zdecydowana większość ruchu powinna należeć do pierwszej z tych klas, lecz niewielki odsetek pakietów wysyła się ekspresowo. Pakiety takie powinny być zdolne do przejścia przez podsieć tak, jakby nie było w niej żadnych innych pakietów. Symbolicznie system ten został przedstawiony na rysunku 5.34 jako dwa kanały. Proszę pamiętać, że linia fizyczna nadal jest tylko jedna. Dwa logiczne kanały przedstawione na rysunku reprezentują sposób rezerwacji pasma, a nie dwa fizyczne łącza.
Strategię tę można zaimplementować, na przykład, programując routery tak, że dla każdej linii wyjściowej będą dwie kolejki. Przychodzący pakiet zostaje wprowadzony do odpowiedniej kolejki. Szeregowanie pakietów powinno przypominać ważone kolejkowanie równomierne. Na przykład, jeśli 10% ruchu ma charakter ekspresowy, a 90% zwykły, dla ruchu ekspresowego można poświęcić 20% pasma, a dla zwykłego resztę. W ten sposób ruch ekspresowy otrzyma dwukrotnie więcej pasma niż potrzebuje, co zapewni mu niskie opóźnienia. Taki przydział można osiągnąć przez wysyłanie jednego pakietu ekspresowego na każde cztery zwykłe pakiety (zakładając, że rozkład wielkości pakietów w obu klasach jest podobny). W ten sposób możemy mieć nadzieję, że z punktu widzenia pakietów ekspresowych podsieć nie będzie obciążona, nawet jeśli w rzeczywistości obciążenie jest wysokie.
Nieco bardziej złożony schemat zarządzania klasami usług nosi nazwę przekazywania gwarantowanego (ang. assuredforwarding). Zostało ono opisane w RFC 2597 i określa, że powinny występować cztery klasy priorytetów, z których każda ma własne zasoby. Oprócz tego schemat definiuje trzy prawdopodobieństwa odrzucenia pakietu w razie przeciążenia: niskie, średnie i wysokie. Razem te dwa czynniki definiują 12 klas usług.
Rysunek 5.35 przedstawia jeden ze sposobów przetwarzania pakietów w przekazywaniu gwarantowanym. Krok pierwszy polega na podziale pakietów na cztery klasy priorytetów. Krok ten może wykonać host nadający pakiety (jak na rysunku) lub router wejściowy (pierwszy). Klasyfikacja w wysyłającym hoście ma tę zaletę, że dysponuje większą ilością informacji o tym, które pakiety należą do konkretnych przepływów.
RYSUNEK 5.35. Możliwa implementacja przepływu danych w przekazywaniu gwarantowanym
Krokiem drugim jest oznaczenie pakietów zgodnie z klasą. Do tego celu potrzebne jest pole nagłówka. Na szczęście w nagłówku IP dostępne jest 8-bitowe pole Typ usługi, jak zobaczymy wkrótce. RFC 2597 określa, że sześć z tych bitów ma służyć dla klasy usługi, co pozostawia dość miejsca na historyczne i przyszłe klasy usług.
Krok trzeci polega na przekazaniu pakietów przez filtr kształtujący i odrzucający, który może opóźnić lub odrzucić część z nich, aby nadać czterem strumieniom dopuszczalne kształty, na przykład przez użycie cieknącego wiadra lub wiadra żetonów. Jeśli pakietów jest zbyt wiele, część z nich może tu zostać odrzucona, zgodnie z kategorią odrzucania. Możliwe są też bardziej wyrafinowane schematy wykorzystujące pomiary lub sprzężenie zwrotne.
W naszym przykładzie te trzy kroki zostały wykonane w hoście nadającym pakiety, więc strumień wejściowy jest przekazywany teraz do routera wejściowego. Warto zanotować, że kroki te może wykonywać specjalne oprogramowanie sieciowe lub nawet system operacyjny, aby uniknąć zmian w istniejących aplikacjach.
Podczas gdy IETF pracował nad usługami zintegrowanymi i zróżnicowanymi, kilku producentów routerów pracowało nad lepszymi metodami przekazywania. Prace te skupiały się na dodaniu etykiety z przodu każdego pakietu i prowadzeniu routingu na podstawie etykiety, a nie adresu docelowego. Zrobienie z etykiet indeksu wewnętrznej tablicy powoduje, że znalezienie właściwej linii wyjściowej jest jedynie kwestią wyszukania w tablicy. Przy użyciu tej techniki routing może odbywać się bardzo szybko i na trasie można rezerwować wszelkie niezbędne zasoby.
Oczywiście etykietowanie przepływów w ten sposób zbliża się niebezpiecznie do obwodów wirtualnych. X.25, ATM, Frame Relay i wszelkie inne sieci z podsiecią obwodów wirtualnych również umieszczają etykietę (tzn. identyfikator obwodu wirtualnego) w każdym pakiecie, wyszukują ją w tablicy i kierują pakiet na podstawie wpisu w tablicy. Mimo to, że wiele osób w społeczności Internetu czuje dużą niechęć do sieci połączeniowych, idea ta wyraźnie co jakiś czas powraca, tym razem, aby zapewnić szybki routing i jakość usług. Jednakże sposoby konstruowania tras w Internecie i w sieciach połączeniowych różnią się znacząco, więc ta technika z pewnością nie jest tradycyjną komutacją obwodów.
Ta „nowa" idea komutacji ma różne (własne) nazwy, w tym label switching (komutacja etykiet) i tag switching (komutacja znaczników). W końcu IETF zaczął standaryzować technikę pod nazwą MPLS (MultiProtocol Label Switching — wieloprotokołowa komutacja etykiet), opisaną w RFC 3031 i wielu innych. Będziemy ją od tej pory nazywać MPLS.
Nawiasem mówiąc, niektórzy ludzie odróżniają routing i switching {komutacje). Routing oznacza proces wyszukiwania adresu docelowego w tablicy, aby ustalić, gdzie wysłać pakiet, natomiast komutacja używa etykiety wziętej z pakietu jako indeksu do tablicy przekazywania. Te definicje sąjednak dalekie od uniwersalności.
Pierwszym problemem jest kwestia, gdzie umieścić etykietę. Ponieważ pakiety IP nie zostały zaprojektowane dla obwodów wirtualnych, w nagłówku IP nie ma miejsca na numer obwodu wirtualnego. Z tego powodu trzeba było dodać nowy nagłówek MPLS z przodu nagłówka IP. W linii pomiędzy dwoma routerami, używającej PPP jako protokołu ramkowania, format ramki obejmujący nagłówki PPP, MPLS, IP i TCP wygląda jak na rysunku 5.36. Wobec tego MPLS jest w pewnym sensie warstwą 2,5.
Ogólny nagłówek MPLS ma cztery pola, z których najważniejszym jest Etykieta, mieszcząca indeks. Pole QoS wskazuje klasę usługi. Pole S wiąże się z łączeniem kaskadowym większej liczby etykiet w sieciach hierarchicznych (co omówimy poniżej). Pole TTL oznacza czas życia pakietu i jest dekrementowane po każdym przeskoku. Gdy dojdzie do 0, pakiet jest odrzucany. Ta funkcja zapobiega nieskończonym pętlom w przypadku niestabilności routingu.
RYSUNEK 5.36. Transmisja segmentu TCP z użyciem IP, MPLS i PPP
Ponieważ nagłówki MPLS nie są częścią pakietu warstwy sieciowej ani ramki warstwy łącza danych, MPLS w dużym stopniu jest zależna od obu warstw. Ta właściwość oznacza między innymi, że można konstruować przełączniki MPLS przekazujące zarówno pakiety IP, jak i ramki ATM, w zależności od tego, co przyjdzie. Stąd „wieloprotokołowość" w nazwie.
Gdy pakiet (lub komórka) rozszerzony o dane MPLS dociera do routera obsługującego MPLS, etykieta zostaje użyta jako indeks do tablicy w celu ustalenia linii wyjściowej i nowej etykiety. Taka zamiana etykiet występuje we wszystkich podsieciach obwodów wirtualnych, ponieważ etykiety mają znaczenie tylko lokalnie i dwa różne routery mogą przekazać do innego routera niezależne pakiety o tej samej etykiecie, aby zostały wysłane tą samą linią wyjściową. Aby można było je rozróżnić na drugim końcu, etykiety muszą być mapowane na nowo w każdym przeskoku. Widzieliśmy ten mechanizm w akcji na rysunku 5.3. MPLS używa tej samej techniki.
Jedną z różnic w porównaniu z tradycyjnymi obwodami wirtualnymi jest poziom agregacji. Z pewnością możliwe jest używanie przez każdy przepływ własnego zbioru etykiet. Jednakże znacznie częściej routery grupują większą liczbę przepływów, które kończą się w określonym routerze lub LAN i używają dla nich jednej etykiety. Mówi się, że przepływy zgrupowane pod jedną etykietą należą do jednej klasy FEC (Forwarding Equivalence Class — klasa zgodności przekazywania). Klasa ta nie tylko obejmuje miejsce, do którego kierowane są pakiety, lecz również ich klasę usługi (w sensie usług zróżnicowanych), ponieważ wszystkie ich pakiety są traktowane w przekazywaniu tak samo.
W tradycyjnym routingu obwodów wirtualnych nie można zebrać kilku różnych ścieżek z różnymi punktami końcowymi pod jednym identyfikatorem obwodu wirtualnego, ponieważ nie byłoby jak odróżnić ich na końcu trasy. W MPLS pakiety oprócz etykiety nadal zawierają ostateczny adres docelowy, więc na końcu trasy etykietowanej nagłówek z etykietą można usunąć i przekazywanie dalej będzie odbywać się tradycyjnie, z użyciem sieciowego adresu docelowego.
Istotną różnicą pomiędzy MPLS i konwencjonalnymi technikami VC jest budowa tablicy przekazywania. Gdy w tradycyjnych sieciach z obwodami wirtualnymi użytkownik chce nawiązać połączenie, do sieci zostaje wysłany pakiet tworzący trasę i wpisy w tablicach przekazywania. MPLS nie działa w ten sposób, ponieważ nie istnieje tu faza tworzenia każdego połączenia (wymagałoby to zmian w zbyt dużej ilości istniejącego oprogramowania internetowego).
Zamiast tego wpisy w tablicy przekazywania tworzone są na dwa sposoby. W metodach sterowanych danymi po przyjściu pakietu pierwszy router, na który ten pakiet trafi, kontaktuje się z kolejnym routerem na trasie, którą musi podążyć pakiet, i żąda od niego wygenerowania etykiety. Ta metoda jest stosowana rekurencyjnie i w rzeczywistości tworzy obwody wirtualne na żądanie.
Protokoły zajmujące się tą propagacją kładą duży nacisk na unikanie pętli. Często używają tzw. metody kolorowych nitek (ang. colored threads). Propagację wsteczną FEC można porównać do przeciągania przez podsieć kolorowej nitki. Gdy router zobaczy kolor, który już ma u siebie, stwierdza istnienie pętli i podejmuje czynności zapobiegawcze. Metoda sterowana danymi jest używana głównie w sieciach, w których jako transport jest używany ATM (jak np. w dużej części systemu telefonicznego).
Druga metoda, używana w sieciach nieopartych na ATM, jest sterowana kontrolą i istnieje w kilku odmianach. Jedna z nich działa następująco: router po uruchomieniu sprawdza, dla których tras jest celem końcowym (tzn. jakie hosty ma w swojej sieci lokalnej). Następnie tworzy dla nich jedną lub więcej FEC, przypisuje etykietę do każdej i przekazuje te etykiety do swoich sąsiadów. Ci z kolei wprowadzają te etykiety do swoich tablic przekazywania i wysyłają nowe etykiety do swoich sąsiadów, dopóki wszystkie routery nie otrzymają trasy. W trakcie konstrukcji tras mogą być też rezerwowane zasoby, aby zagwarantować odpowiednią jakość usług.
MPLS może działać jednocześnie na kilku poziomach. Na najwyższym poziomie każdego operatora można uznać za coś w rodzaju metaroutera, z trasą od źródła do celu używającą metarouterów. Trasa ta może korzystać z MPLS. Jednakże każdy operator w swojej sieci również może używać MPLS, co prowadzi do utworzenia drugiego poziomu etykiet. W istocie pakiet może zawierać cały stos etykiet. Bit S z rysunku 5.36 informuje router usuwający etykietę, czy pozostały jeszcze jakieś inne dodatkowe etykiety. Dla etykiety na samym spodzie ma wartość 1, a dla wszystkich pozostałych 0. W praktyce służy to głównie do implementacji wirtualnych sieci prywatnych i rekurencyjnych tuneli.
Wprawdzie podstawowe założenia MPLS są proste, lecz szczegóły są wyjątkowo skomplikowane, z wieloma odmianami i optymalizacjami, więc nie będziemy się więcej zajmować tym tematem. Dodatkowych informacji dostarczają Davie i Rekhter (2000), Lin i inni (2002), Pepelnjak i Guichard (2001) oraz Wang(2001).
Jak dotąd milcząco zakładaliśmy, że mamy do czynienia z jedną jednorodną siecią w której wszystkie urządzenia używają w każdej warstwie tych samych protokołów. Niestety, to założenie jest nadmiernie optymistyczne. Istnieje wiele różnych typów sieci lokalnych, miejskich i rozległych. W każdej warstwie używane są powszechnie różne protokoły. W tym podrozdziale przyjrzymy się problemom powstającym, gdy dwie lub więcej sieci łączy się w sieć złożoną (internet z małej litery).
Spore kontrowersje budzi pytanie, czy dzisiejsza rozmaitość typów sieci jest stanem tymczasowym, który zniknie, gdy wszyscy zdadzą sobie sprawę z genialności [tu wpisz swoją ulubioną sieć], czy też jest nieuniknionym i stałym elementem krajobrazu. Istnienie różnych sieci nieodmiennie oznacza istnienie różnych protokołów.
Naszym zdaniem zawsze będą stosowane różne typy sieci (więc i różne protokoły) z powodów przedstawionych poniżej. Po pierwsze, baza zainstalowanych sieci różnego typu jest ogromna. Niemal wszystkie komputery osobiste używają TCP/IP. Wiele dużych firm posiada komputery mainframe korzystające z SNA firmy IBM. Znacząca liczba firm telefonicznych eksploatuje sieci ATM. Niektóre sieci lokalne z komputerami osobistymi nadal używają NCP/IPX Novella i AppleTalk. Na dodatek obszarem szybko rozwijającym się są sieci bezprzewodowe z mnogością protokołów. Ten trend utrzyma się przez lata z uwagi na problemy z użytkowaniem przestarzałych technologii, nowymi technologiami i fakt, że nie wszyscy producenci uważają za korzystne, by ich klienci mogli z łatwością migrować do systemów innych producentów.
Po drugie, komputery i sieci stają się coraz tańsze, więc miejsce podejmowania decyzji o zakupach przenosi się w organizacjach w dół. W USA wiele firm stosuje zasadę, że zakupy powyżej miliona dolarów muszą być aprobowane przez najwyższe kierownictwo, zakupy do 100 000 dolarów przez kierownictwo średniego szczebla, lecz zakupów poniżej 100 000 dolarów może dokonywać kierownictwo poszczególnych działów bez zgody wyższych władz. Może to z łatwością prowadzić do sytuacji, gdy dział techniczny zainstaluje uniksowe stacje robocze z TCP/IP, a marketing komputery Macintosh z AppleTalk.
Po trzecie, różne sieci (ATM i bezprzewodowe) stosują radykalnie odmienne technologie, więc nie powinno zaskakiwać, że w miarę rozwoju nowego sprzętu będzie tworzone nowe oprogramowanie, dopasowane do niego. Na przykład przeciętny dom przypomina przeciętne biuro sprzed dziesięciu lat —jest pełen skomputeryzowanych urządzeń, które nie potrafią się ze sobą komunikować. W przyszłości może będzie normą, że telefon, telewizor i inne sprzęty domowe będą połączone w sieć, co pozwoli sterować nimi zdalnie. Taka nowa technologia z pewnością przyniesie nowe sieci i nowe protokoły.
RYSUNEK 5.37. Zbiór połączonych ze sobą sieci
Przykład, jak mogą być połączone różne sieci, przedstawia rysunek 5.37. Mamy tu sieć przedsiębiorstwa z wieloma lokalizacjami połączonymi ze sobą siecią ATM. W jednym miejscu światłowodowa sieć szkieletowa łączy ze sobą Ethernet, bezprzewodową sieć lokalną 802.11 i sieć SNA komputerów mainframe centrum danych korporacji.
Sieci łączone są ze sobą wzajemnie, aby pozwolić użytkownikom w dowolnej z nich komunikować się z użytkownikami pozostałych sieci i korzystać z danych mieszczących się w dowolnej sieci. Osiągnięcie tego celu wymaga przesyłania pakietów pomiędzy różnymi sieciami. Ponieważ pomiędzy sieciami często występują istotne różnice, przekazanie pakietu z jednej do drugiej nie zawsze jest takie łatwe, jak zobaczymy za chwilę.
Sieci mogą różnić się od siebie na wiele sposobów. Niektóre różnice, na przykład w technikach modulacji i formacie ramek, występują w warstwach fizycznej i łącza danych. Te różnice nie będą nas interesować. Przedstawiliśmy za to w tabeli 5.5 rozbieżności występujące w warstwie sieciowej. Właśnie one powodują, że łączenie sieci jest o wiele trudniejsze niż eksploatacja sieci pojedynczej.
Gdy pakiety wysłane ze źródła w jednej sieci muszą przejść przez jedną lub więcej obcych sieci, zanim dotrą do sieci docelowej (która też może różnić się od źródłowej), na interfejsach pomiędzy sieciami może wystąpić wiele problemów. Zacznijmy od tego, że gdy pakiety z sieci połączeniowej muszą przejść przez sieć bezpołączeniową, mogą zostać przemieszane, czego nadajnik się nie spodziewa, a odbiornik nie potrafi sobie z tym poradzić. Często potrzebna będzie konwersja protokołu, która może być trudna, jeśli nie można zrealizować wymaganej funkcjonalności. Konwersja adresów również będzie potrzebna, co może wymagać jakiegoś systemu katalogowego. Przenoszenie pakietów adresowanych grupowo przez sieć nieobsługującą rozsyłania grupowego wymaga wygenerowania osobnego pakietu dla każdego adresu docelowego.
TABELA 5.5.
Kilka spośród możliwych różnic pomiędzy sieciami
Cecha
Niektóre z możliwości
Oferowane usługi
Protokoły
Adresowanie
Transmisje grupowe
Rozmiar pakietu
Jakość usług
Obsługa błędów
Sterowanie przepływem
Kontrola przeciążeń
Bezpieczeństwo
Parametry
Rozliczanie
Połączeniowe albo bezpołączeniowe.
IP, IPX, SNA, ATM, MPLS, AppleTalk itp.
Płaskie (802) albo hierarchiczne (IP).
Obecne lub nieobecne (podobnie jak rozgłoszenia).
Każda sieć ma własne maksimum.
Gwarantowana lub nie; wiele różnych typów.
Doręczanie niezawodne, uporządkowane i nieuporządkowane.
Okno przesuwne, kontrola szybkości transmisji, inne lub brak.
Cieknące wiadro, wiadro żetonów, RED, pakiety tłumiące itp.
Zasady prywatności, szyfrowanie itp.
Różne zależności czasowe, specyfikacje przepływu itp.
Według czasu połączenia, według przesłanych pakietów lub bajtów albo nieobecne.
Poważną uciążliwością mogą być różnice w maksymalnych rozmiarach pakietów w różnych sieciach. Jak przesłać 8000-bajtowy pakiet przez sieć, w której maksymalny rozmiar pakietu wynosi 1500 bajtów? Różniące się jakości usług również stanowią problem, gdy pakiet wymagający doręczenia w czasie rzeczywistym przechodzi przez sieć nie oferującą żadnych gwarancji transmisji w czasie rzeczywistym.
Kontrola błędów i przeciążeń oraz sterowanie przepływem też różnią się w zależności od sieci. Jeśli zarówno źródło, jak i odbiorca transmisji spodziewają się doręczenia pakietów we właściwej kolejności i bez błędów, lecz pośrednicząca sieć po prostu odrzuca pakiety, gdy tylko z daleka wyczuje zbliżające się przeciążenie, wiele aplikacji nie będzie działać. Poza tym, jeśli pakiety mogą przez chwilę wędrować bez celu, a potem nagle pojawić się i zostać dostarczone, pojawi się problem, jeśli takie zachowanie nie było przewidziane i odpowiednio potraktowane. Kłopoty mogą powodować odmienne mechanizmy zabezpieczeń, ustawienia parametrów i reguły rozliczania, a nawet obowiązujące w różnych krajach przepisy dotyczące prywatności.
Sieci można łączyć różnymi urządzeniami, jak zobaczyliśmy w rozdziale 4. Przypomnijmy pokrótce te wiadomości. W warstwie fizycznej sieci możemy łączyć wzmacniakami i koncentratorami, które po prostu przenoszą bity z jednej sieci do drugiej, identycznej. Są to głównie urządzenia analogowe i nie rozumieją w ogóle protokołów cyfrowych, a jedynie regenerują sygnały.
Jedną warstwę wyżej znajdziemy mosty i przełączniki, które funkcjonują w warstwie łącza danych. Mogą przyjmować ramki, sprawdzać adresy MAC i przekazywać ramki do innej sieci, dokonując jednocześnie pomniejszej translacji protokołu, na przykład z sieci Ethernet do FDDI lub 802.11.
W warstwie sieciowej mamy routery, które mogą łączyć dwie sieci. Jeśli sieci te mają różniące się warstwy sieciowe, router może być zdolny do translacji formatu pakietów, aczkolwiek translację Pakietów spotyka się coraz rzadziej. Router mogący obsługiwać różne protokoły nazywamy routerem wieloprotokołowym.
W warstwie transportowej znajdziemy bramy warstwy transportowej, które mogą tworzyć interfejs pomiędzy dwoma połączeniami transportowymi. Na przykład brama transportowa może pozwalać na przepływ pakietów pomiędzy sieciami TCP i SNA mającymi odmienne protokoły transportowe, sklejając połączenie TCP z połączeniem SNA.
Na koniec w warstwie aplikacji bramy warstwy aplikacji dokonują translacji semantyki komunikatów. Na przykład bramy pomiędzy internetową pocztą e-mail (RFC 822) i pocztą X.400 muszą analizować składniowo wiadomości i zmieniać różne pola nagłówka.
RYSUNEK 5.38.
Dwie sieci Ethernet połączone przełącznikiem.
Dwie sieci Ethernet połączone routerami
W niniejszym rozdziale skupimy się na łączeniu sieci w warstwie sieciowej. Rysunek 5.38 pokazuje, czym to się różni od komutacji w warstwie łącza danych. Na rysunku 5.38 (a) komputer źródłowy S chce wysłać pakiet do komputera docelowego D. Komputery te znajdują się w osobnych sieciach Ethernet połączonych przełącznikiem. S kapsułkuje pakiet w ramkę i wysyła w drogę. Ramka dociera do przełącznika, który na podstawie adresu MAC z tej ramki ustala, że powinna pójść do LAN 2. Następnie przełącznik zdejmuje ramkę z LAN 1 i umieszczają w LAN 2.
Rozważmy teraz tę samą sytuację, gdy sieci Ethernet połączone są parą routerów zamiast przełącznika. Routery połączone są linią dwupunktową na przykład łączem dzierżawionym o długości kilku tysięcy kilometrów. Teraz ramka jest odbierana przez router, który wydobywa pakiet z jej pola danych, a następnie sprawdza adres w pakiecie (np. IP) i szuka go w swojej tablicy routingu. Na podstawie tego adresu decyduje o wysłaniu pakietu do odległego routera, potencjalnie kapsuł-kowanego w inny typ ramki, zależnie od protokołu łącza. Na drugim końcu pakiet zostaje umieszczony w polu danych ramki Ethernet i wprowadzony do LAN 2.
Zasadnicza różnica pomiędzy użyciem przełącznika (lub mostu) i routera jest następująca: w przełączniku (lub moście) cała ramka jest transportowana na podstawie zawartego w niej adresu MAC. W routerze pakiet zostaje wydobyty z ramki i do podjęcia decyzji, gdzie wysłać pakiet, zostaje użyty zawarty w nim adres. Przełączniki nie muszą rozumieć użytego protokołu warstwy sieciowej, aby komutować pakiety. Routery muszą.
Istnieją dwa style łączenia sieci: połączeniowe spinanie podsieci obwodów wirtualnych i styl data-gramów internetowych. Omówimy je po kolei, lecz najpierw kilka słów ostrzeżenia. W przeszłości większość sieci (publicznych) było typu połączeniowego (a Frame Relay, SNA,802.16 i ATM nadal są). Następnie, wraz z gwałtownym rozwojem Internetu, datagramy zrobiły się modne, jednakże pomyłką byłoby sądzić, że będą istnieć wiecznie. W tym biznesie wieczna jest tylko zmiana. Ponieważ sieci multimedialne nabierają coraz większego znaczenia, można przypuszczać, że orientacja na połączenia wróci w takiej lub innej formie, ponieważ łatwiej jest zagwarantować jakość usług z użyciem połączeń niż bez nich. Wobec tego poświęcimy poniżej trochę miejsca sieciom połączeniowym.
W modelu spinanych obwodów wirtualnych, przedstawionym na rysunku 5.39, połączenie z hostem w odległej sieci jest zestawiane podobnie jak zwykłe połączenia. Podsieć rozpoznaje, że adres docelowy jest zdalny i tworzy obwód wirtualny do routera położonego najbliżej sieci docelowej. Następnie tworzy obwód wirtualny z tego routera do zewnętrznej bramy (routera wieloprotokołowego). Ta brama (ang. gateway) rejestruje istnienie obwodu wirtualnego w swojej tablicy i przechodzi do tworzenia następnego obwodu wirtualnego do routera w następnej podsieci. Ten proces jest kontynuowany, dopóki nie zostanie osiągnięty host docelowy.
RYSUNEK 5.39. Międzysieć używająca spinanych obwodów wirtualnych
Gdy pakiety zaczną już przepływać utworzoną trasą, każda brama przekazuje niekompletne pakiety, dokonując w razie potrzeby konwersji formatu pakietów i numerów obwodów wirtualnych. Wszystkie pakiety danych muszą oczywiście podróżować przez te same bramy, więc sieć nigdy nie zmienia kolejności pakietów w przepływie.
Istotną cechą takiego podejścia jest to, że łańcuch obwodów wirtualnych jest zestawiany od źródła przez jedną lub więcej bram do celu. Każda brama utrzymuje tablice informujące, które obwody wirtualne przez nią przechodzą, dokąd mają być kierowane i jaki jest nowy numer obwodu wirtualnego.
Ta metoda działa najlepiej, gdy wszystkie sieci mają mniej więcej takie same właściwości. Na przykład, jeśli wszystkie gwarantują niezawodne doręczanie pakietów warstwy sieciowej, to jeśli pominąć ewentualne awarie routerów gdzieś na trasie, przepływ od źródła do celu również będzie niezawodny. Jeśli żaden nie gwarantuje niezawodnego doręczania, to złożenie obwodów wirtualnych też nie będzie niezawodne. Z drugiej strony, jeśli komputer źródłowy mieści się w sieci, która gwarantuje niezawodne doręczanie, lecz jedna z pośredniczących sieci może tracić pakiety, złożenie fundamentalnie zmieni charakter usługi.
Spinanie obwodów wirtualnych często spotyka się też w warstwie transportowej. Można zbudować potok bitowy z użyciem np. SNA, kończący się w bramie, a następnie połączyć tę bramę z kolejną za pomocą TCP. W ten sposób obwody wirtualne można łączyć koniec z końcem tak, że przejdą przez różne sieci i protokoły.
Alternatywnym rozwiązaniem jest model datagramowy pokazany na rysunku 5.40. W tym modelu jedyną usługą, jaką warstwa sieciowa oferuje warstwie transportowej, jest zdolność do wprowadzania datagramów do podsieci z nadzieją, że jakoś dotrą do celu. W warstwie sieciowej w ogóle
nie istnieje pojęcie obwodu wirtualnego, nie mówiąc już o sklejaniu obwodów. Model ten nie wymaga, aby wszystkie pakiety należące do jednego połączenia przechodziły przez tę samą sekwencję bram. Na rysunku 5.40 datagramy z hosta 1 do hosta 2 podróżują przez międzysieć różnymi trasami. Decyzje o wyborze trasy są podejmowane niezależnie dla każdego pakietu, często zależnie od ruchu w sieci w chwili wysłania pakietu. Ta strategia może wykorzystywać wiele tras i przez to osiągać wyższą przepustowość niż model ze spinanymi obwodami wirtualnymi. Z drugiej strony nie ma żadnej gwarancji, że pakiety dotrą do celu we właściwej kolejności, o ile dotrą w ogóle.,
Model z rysunku 5.40 nie jest taki prosty, na jaki wygląda. Po pierwsze, jeśli każda sieć ma własny protokół sieciowy, to pakiet z jednej sieci nie może przejść przez inną. Możemy wyobrazić sobie routery wieloprotokołowe usiłujące dokonać translacji z jednego formatu na drugi, lecz o ile oba formaty nie są blisko spokrewnione i nie zawierają tych samych pól, konwersje zawsze będą niepełne i często skazane na niepowodzenie. Z tego powodu rzadko próbuje się konwersji.
Drugi, bardziej poważny problem stanowi adresowanie. Wyobraźmy sobie prostą sytuację: host w Internecie usiłuje wysłać pakiet IP do hosta w przyległej sieci SNA. Adresy IP i SNA są różne Potrzebne byłoby mapowanie adresów IP na SNA i odwrotnie. Co więcej, idee tego, co można adresować, są odmienne. W IP adresami dysponują hosty (a właściwie karty sieciowe). W SNA adresy mogą mieć inne jednostki niż hosty, na przykład urządzenia sprzętowe. W najlepszym przypadku s będzie musiał utrzymywać bazę danych mapującą wszystko na wszystko, zasadniczo możliwe, lecz to byłoby stałym źródłem problemów.
Innym pomysłem może być zaprojektowanie uniwersalnego pakietu „międzysieciowego" i wymaganie, by rozpoznawały go wszystkie routery. Tym w istocie jest IP — pakiet zaprojektowany do przenoszenia przez wiele sieci. Oczywiście może się okazać, że IPv4 (aktualny protokół Internetu) wyprze z rynku wszystkie inne formaty, IPv6 (przyszły protokół Internetu) nigdy się nie przyjmie i nic więcej nie zostanie wynalezione, lecz historia uczy czegoś innego. Zmuszenie] wszystkich do zgody na wspólny format jest trudne, gdy firmy uznają że opłaca im się stosowanie własnego formatu, nad którym mają kontrolę.
Podsumujmy pokrótce dwa sposoby łączenia sieci. Model ze spinanymi obwodami wirtualnymi ma praktycznie te same zalety co obwody wirtualne w obrębie jednej podsieci: bufory można je rezerwować z góry, kolejność pakietów jest gwarantowana, można używać krótkich nagłówków i można uniknąć problemów powodowanych przez opóźnione duplikaty pakietów.
Ma też kilka wad: w routerach potrzebne jest miejsce w tablicach na każde otwarte połączenie, nie ma alternatywnego routingu pozwalającego unikać przeciążonych obszarów i połączenie jest wrażliwe na awarie routerów na trasie. Poza tym rozwiązanie to jest trudne, a nawet niemożliwe do zaimplementowania, gdy jedna z używanych sieci jest zawodną siecią datagramową.
Właściwości łączenia sieci metodą datagramową są praktycznie takie same jak podsieci datagaramowych — większe ryzyko przeciążeń, lecz jednocześnie łatwiejsza adaptacja do nich. niezawodność w przypadku awarii routerów, potrzebne są też dłuższe nagłówki. W międzysieciach można używać różnych adaptacyjnych algorytmów routingu, podobnie jak w pojedynczej sieci datagramowej.
Stosowanie datagramów w międzysieciach ma jedną zasadniczą zaletę — pozwala używać podsieci niestosujących wewnątrz obwodów wirtualnych. Do tej kategorii zalicza się wiele sieci LAN, sieci mobilnych (np. w lotnictwie i marynarce), a nawet niektóre sieci rozległe. Gdy międzysieć zawiera jedną z takich sieci, mogłyby wystąpić poważne problemy przy stosowaniu strategii opartej na obwodach wirtualnych.
Z ogólnym przypadkiem łączenia dwóch różnych sieci poradzić sobie jest wyjątkowo trudno. Istnieje jednak często spotykany przypadek specjalny, nad którym można zapanować. Jest to wypadek, gdy hosty źródłowy i docelowy są w sieciach tego samego typu, lecz pomiędzy nimi znajduje się inna sieć. Wyobraźmy sobie, na przykład, międzynarodowy bank z oddziałami w Paryżu i Londynie używającymi Ethernetu i TCP/IP, lecz połączonymi siecią rozległą innego typu (np. ATM), jak na rysunku 5.41.
RYSUNEK 5.41. Tunelowanie pakietu z Paryża do Londynu
Rozwiązaniem tego problemu jest technika zwana tunelowaniem. Aby wysłać pakiet IP do hosta 2, host 1 tworzy pakiet zawierający adres IP hosta 2, wkłada do ramki Ethernet zaadresowanej do wieloprotokołowego routera paryskiego i wysyła w Ethernet. Gdy router wieloprotokołowy odbiera ramkę, wydobywa z niej pakiet IP, wstawia do pola ładunku roboczego pakietu warstwy sieciowej WAN i adresuje ten pakiet w sieci WAN do routera wieloprotokołowego w Londynie. Gdy pakiet tam dociera, router londyński wydobywa pakiet IP i wysyła go do hosta 2 w ramce Ethernet.
WAN możemy wyobrazić sobie jako wielki tunel przebiegający z jednego routera wieloprotokołowego do drugiego. Pakiet IP po prostu podróżuje komfortowo tym tunelem w swoim wygodnym pudełku, nie musząc w ogóle zawracać sobie głowy siecią WAN. Hosty w obu Ethernetach również nie muszą przejmować się WAN. Tylko router wieloprotokołowy musi rozumieć pakiety IP i WAN. W efekcie cała trasa z wnętrza jednego routera wieloprotokołowego do wnętrza drugiego zachowuje się jak łącze szeregowe.
Możemy to wyjaśnić, wykorzystując analogię. Pomyślmy o osobie jadącej samochodem z Paryża do Londynu. W granicach Francji samochód porusza się o własnych siłach, lecz gdy dociera do kanału La Manche, zostaje załadowany na szybki pociąg i przewieziony do Anglii tunelem pod kanałem (zwanym Chunnel). Wobec tego samochód jest przewożony jak przesyłka towarowa (jak na rysunku 5.42). Po drugiej stronie samochód jest wypuszczany na brytyjskie drogi i ponownie może poruszać się o własnych siłach. Tunelowanie pakietów przez obcą sieć działa tak samo.
RYSUNEK. 5.42. Tunelowanie samochodu z Francji do Anglii
Routing przez sieć złożoną przypomina routing w obrębie jednej podsieci, lecz z pewnymi dodatkowymi komplikacjami. Weźmy na przykład sieć złożoną z rysunku 5.43 (a), w której pięć sieci jest połączonych sześcioma routerami (być może wieloprotokołowymi). Modelowanie tej sytuacji za pomocą grafu komplikuje fakt, że każdy router ma bezpośredni dostęp do każdego innego routera połączonego z dowolną siecią do której jest podłączony (tzn. może wysyłać do niego pakiety). Na przykład B na rysunku 5.43 (a) może bezpośrednio łączyć się z A i C przez sieć 2, oraz z D przez sieć 3. Otrzymujemy przez to graf z rysunku 5.43 (b).
RYSUNEK 5.43. (a) Międzysieć. (b) Graf międzysieci
Po zbudowaniu grafu można względem zbioru routerów wieloprotokołowych zastosować znane algorytmy routingu, na przykład wektorów odległości i stanów łączy. Daje to dwupoziomowy, algorytm routingu — wewnątrz każdej sieci używany jest protokół bram wewnętrznych (ang. interior gateway protocol), lecz pomiędzy sieciami stosuje się protokół bram zewnętrznych (ang. exterior gateway protocol). „Brama" (gateway) jest tu starszą nazwą routera. W istocie, gdyż każda sieć jest niezależna, może używać odmiennego algorytmu. Ponieważ w międzysieci każda sieć jest niezależna od wszystkich pozostałych, to często określana jest jako system autonomiczny (AS — Autonomous System).
Typowy pakiet międzysieciowy wyrusza ze swojej sieci LAN zaadresowany do lokalnego routera wieloprotokołowego (w nagłówku warstwy MAC). Gdy dostanie się do niego, kod warstwy sieciowej decyduje, do którego routera wieloprotokołowego przekazać pakiet, używając własnych tablic routingu. Jeśli do routera tego można dotrzeć z użyciem macierzystego protokołu sieciowe-go pakietu, to pakiet jest tam przekazywany bezpośrednio. W przeciwnym razie zostaje tam tunelowany po kapsułkowaniu w protokół wymagany przez pośredniczącą sieć. Proces ten jest powtarzany, dopóki pakiet nie dotrze do sieci docelowej.
Jedna z różnic pomiędzy routingiem międzysieciowym i wewnątrzsieciowym polega na tym, że routing między sieciami może wymagać przekraczania granic państw. Nagle w grę zaczynają wchodzić różne przepisy prawne, na przykład bardzo rygorystyczne prawo szwedzkie dotyczące eksportowania danych obywateli szwedzkich na zewnątrz kraju. Innym przykładem może być prawo kanadyjskie mówiące, że dane pochodzące z Kanady i przeznaczone dla Kanady nie mogą opuszczać kraju. Oznacza to, że transmisja z Windsoru w Ontario do Vancouver nie może być kierowana przez pobliskie Detroit, nawet gdyby trasa ta była najszybsza i najtańsza.
Kolejną różnicą pomiędzy routingiem wewnętrznym i zewnętrznym jest koszt. W obrębie jednej sieci zwykle obowiązuje pojedynczy algorytm pobierania opłat, jednakże różne sieci mogą należeć do różnych organizacji i jedna trasa może być tańsza od innej. Podobnie jakość usług oferowana przez różne sieci może być różna, co może być powodem do wybrania konkretnej trasy zamiast innej.
Każda sieć nakłada pewne ograniczenie na maksymalną wielkość pakietu. Ograniczenia te mają różne powody, na przykład:
Sprzęt (np. wielkość ramki Ethernet).
System operacyjny (np. wszystkie bufory mają po 512 bajtów).
Protokoły (np. liczba bitów w polu długości pakietu).
Zgodność ze standardami krajowymi i międzynarodowymi.
Chęć ograniczenia poziomu retransmisji powodowanych przez błędy.
Chęć zapobieżenia zbyt długiemu zajmowaniu kanału przez jeden pakiet.
Wszystkie te czynniki powodują, że projektanci sieci nie mają wolnej ręki przy wyborze maksymalnej długości pakietu. Maksymalny ładunek użyteczny waha się od 48 bajtów (komórki ATM) aż do 65 515 bajtów (pakiety IP), aczkolwiek rozmiar ładunku użytecznego w wyższych warstwach jest zwykle większy.
Pojawia się oczywisty problem, gdy duży pakiet chce przejść przez sieć, której maksymalny rozmiar pakietu jest zbyt mały. Jedne z rozwiązań polega na zagwarantowaniu, że problem w ogóle nie wystąpi. Inaczej mówiąc, międzysieć powinna używać algorytmu routingu, który unika wysyłania pakietów przez sieci niemogące ich obsłużyć. Jednakże to rozwiązanie nie jest żadnym rozwiązaniem. Co będzie, jeśli pierwotny pakiet źródłowy będzie za duży dla sieci docelowej? Algorytm routingu raczej nie powinien omijać sieci docelowej.
Zasadniczo jedynym rozwiązaniem problemu jest pozwolenie bramom na dzielenie pakietów na fragmenty i wysyłanie każdego fragmentu jako osobnego pakietu międzysieciowego. Jednakże, jak dobrze wiedzą wszyscy rodzice małych dzieci, podział obiektu na małe fragmenty jest znacznie łatwiejszy niż proces odwrotny (fizycy nawet nadali nazwę temu efektowi: „drugie prawo termodynamiki"). Sieci z komutacją pakietów również mają kłopoty z poskładaniem fragmentów z powrotem w całość.
Istnieją dwie przeciwstawne strategie ponownego składania fragmentów w pierwotny pakiet. Pierwsza polega na uczynieniu fragmentacji, spowodowanej przez sieć o małych pakietach, niewidocznej dla wszystkich kolejnych sieci, przez które pakiet musi przejść do ostatecznego celu. Opcję tę przedstawia rysunek 5.44 (a). W tym podejściu sieć o małych pakietach zawiera bramy (najczęściej wyspecjalizowane routery) łączące ją z innymi sieciami. Gdy do bramy dociera zbyt duży pakiet, jest dzielony przez bramę na fragmenty. Każdy fragment zostaje zaadresowany do tej samej bramy wyjściowej, w której kawałki zostają ponownie złożone razem. W ten sposób przejście przez sieć o małych pakietach odbyło się w sposób niewidoczny (przezroczysty). Kolejne sieci nie zdają sobie w ogóle sprawy, że wystąpiła fragmentacja. Sieci ATM na przykład zawierają specjalny sprzęt służący do przezroczystej fragmentacji pakietów na komórki i składania z powrotem komórek w pakiety. W świecie ATM fragmentacja jest nazywana segmentacją; idea jest ta sama, lecz różnice występują w szczegółach.
RYSUNEK 5.44. (a) Fragmentacja przezroczysta, (b) Fragmentacja nieprzezroczysta
Fragmentacja przezroczysta jest prosta w założeniach, lecz stwarza kilka problemów. Po pierwsze, brama wyjściowa musi wiedzieć, czy otrzymała wszystkie kawałki, więc potrzebne jest pole licznika lub bit „koniec pakietu". Po drugie, wszystkie fragmenty muszą wyjść przez tę samą ramę. Ponieważ nie pozwala się na przesyłanie do ostatecznego celu części fragmentów jedną trasą i pozostałych inną wydajność może nie być optymalna. Ostatnim problemem jest dodatkowe zużycie zasobów na powtarzające się dzielenie dużego pakietu na fragmenty i ponowne składanie, gdy pakiet en przechodzi przez kilka sieci o małych pakietach. ATM wymaga fragmentacji przezroczystej.
Druga strategia fragmentacji polega na powstrzymaniu się od rekombinacji fragmentów w bramach pośrednich. Po fragmentacji pakietu każdy fragment jest traktowany tak, jakby był oryginalnym pakietem. Wszystkie fragmenty są przekazywane przez bramę wyjściową (lub więcej bram), jak na rysunku 4.44 (b). Ponowne składanie odbywa się dopiero w hoście docelowym. Tak funk-jonuje IP.
Nieprzezroczysta fragmentacja też wiąże się z problemami. Na przykład, wymaga od każdego hosta umiejętności ponownego składania pakietów. Kolejny problem polega na tym, że po podziale dużego pakietu na fragmenty ogólne zużytkowanie zasobów rośnie, ponieważ każdy fragment musi mieć nagłówek. W pierwszej metodzie te dodatkowe informacje znikały w chwili wyjścia z sieci o małych pakietach, lecz w tej pozostają na całej reszcie trasy. Z drugiej strony przy użyciu nieprzezroczystej fragmentacji można użyć więcej niż jednej bramy wyjściowej i otrzymać przez to większą wydajność. Oczywiście jeśli stosowany jest model spinanych obwodów wirtualnych, ta zaleta jest bezużyteczna.
Gdy pakiet jest dzielony, fragmenty muszą zostać ponumerowane w sposób pozwalający odtworzyć oryginalny strumień danych. Jedna z metod numerowania fragmentów korzysta ze struktury drzewa. Jeśli trzeba podzielić pakiet 0., kawałki otrzymają numery 0.0, 0.1, 0.2 itp. Jeśli te fragmenty też trzeba będzie później podzielić, kawałki zostaną ponumerowane 0.0.0, 0.0.1. 0.0.0.2 ... 0.1.0. 0.1.1, 0.1.0.2 itp. Jeżeli w nagłówku zarezerwowano wystarczającą liczbę pól na najgorszy możliwy scenariusz i nigdzie nie będą wygenerowane duplikaty, ta metoda wystarcza do zapewnienia, że wszystkie kawałki zostaną poprawnie złożone razem u celu, niezależnie od kolejności, w której dotarły.
Jeśli jednak choćby jedna sieć traci lub odrzuca pakiety, potrzebne są retransmisje na całej drodze transmisji, co ma niefortunny wpływ na system numerowania. Załóżmy, że 1024-bitowy pakiet został początkowo podzielony na cztery fragmenty o równej długości: 0.0, 0.1, 0.2 i 0.3. Fragment 0.1 został utracony, lecz pozostałe części dotarły do celu. W końcu w źródle upływa czas oczekiwania i pierwotny pakiet zostaje retransmitowany. W tym momencie wkracza do dzieła prawo Murphy'ego i kieruje pakiet trasą przez sieć z 512-bitowym limitem, przez co zostają wygenerowane dwa fragmenty. Gdy nowy fragment o numerze 0.1 dotrze do celu, odbiornik uznaje, że wszystkie cztery kawałki się znalazły i błędnie rekonstruuje pakiet.
Całkowicie odmienny (i lepszy) system numerowania polega na tym, że protokół międzysieciowy definiuje wielkość elementarnego fragmentu wystarczająco małą, że każdy fragment elementarny przejdzie przez każdą sieć. Gdy pakiet jest dzielony na fragmenty, wszystkie kawałki mają taką samą wielkość z wyjątkiem ostatniego, który może być krótszy. Międzysieciowy pakiet może dla zwiększenia wydajności zawierać kilka fragmentów. Nagłówek międzysieciowy musi zawierać numer oryginalnego pakietu i numer (pierwszego) fragmentu elementarnego zawartego w pakiecie. Jak zwykle musi w nim znajdować się też bit wskazujący, czy ostatni fragment elementarny zawarty w pakiecie międzysieciowym jest ostatnim fragmentem oryginalnego pakietu.
Takie podejście wymaga dwóch pól sekwencyjnych w nagłówku międzysieciowym: numeru oryginalnego pakietu i numeru fragmentu. Widać, że występuje tu kompromis pomiędzy rozmiarem fragmentu elementarnego i liczbą bitów numeru fragmentu. Ponieważ zakłada się, że rozmiar fragment elementarny musi być do przyjęcia dla każdej sieci, dalszy podział pakietu międzysieciowego zawierającego kilka fragmentów nie sprawia problemu. Ostateczną granicą jest tu fragment elementarny o wielkości jednego bajta lub bitu, gdzie numer fragmentu jest przesunięciem bajta lub bitu w oryginalnym pakiecie, jak na rysunku 5.45.
Niektóre protokoły internetowe idą jeszcze dalej w tej metodzie i uznają całą transmisję w obwodzie wirtualnym za jeden gigantyczny pakiet, więc każdy fragment zawiera bezwzględny numer pierwszego bajta we fragmencie.
Zanim przejdziemy do szczegółów warstwy sieciowej w Internecie, warto przyjrzeć się zasadom, które kierowały jej projektowaniem w przeszłości i przyczyniły się do jej dzisiejszego sukcesu. Zdaje się, że zbyt wielu ludzi nie pamięta dziś o nich. Zasady te zostały wymienione w dokumencie RFC 1958, który jest zdecydowanie wart przeczytania
(i powinien być lekturą obowiązkową dla wszystkich projektantów protokołów — z egzaminem końcowym). Ten RFC czerpie wiele idei z prac Clarka (1988) oraz Saltzera i innych (1984). Podsumujemy teraz 10 zasad, które uznajemy za najważniejsze (od najbardziej do najmniej ważnej).
Upewnij się, że to działa. Projekt lub standard nie powinien być finalizowany, dopóki nie uda się pomyślnie skomunikować ze sobą wielu prototypów. Zbyt często autorzy zaczynają od napisania standardu na 1000 stron i uzyskania dla niego zatwierdzenia, by później odkryć, że zawiera poważne wady i nie nadaje się do użytku. Wtedy piszą wersję 1.1 standardu. Nie tak miało być.
Zachowaj prostotę. W razie wątpliwości należy użyć najprostszego rozwiązania. William Ockham zdefiniował tę regułę (tzw. brzytwę Ockhama) już w XIV wieku. We współczesnej wer-sji: zwalczaj funkcjonalność. Jeśli funkcja nie jest absolutnie niezbędna, należy ją pominąć, szczególnie jeśli ten sam efekt można osiągnąć przez połączenie innych funkcji.
Podejmuj zdecydowane decyzje. Jeśli coś można zrobić na kilka sposobów, należy wybrać jeden. Dwie lub więcej dostępnych metod wykonania jednej rzeczy prosi się o kłopoty. Standardy często zawierają wiele opcji, trybów i parametrów, ponieważ silne stronnictwa upierały się, że ich metoda jest najlepsza. Projektanci powinni opierać się tym tendencjom i po prostu odmawiać.
Wykorzystuj modularność. Ta reguła prowadzi prosto do idei stosowania stosów protokołów, w których każda warstwa jest niezależna od wszystkich pozostałych. W ten sposób, jeśli okoliczności będą wymagać zmiany jednego modułu lub warstwy, nie wpłynie to na pozostałe.
Spodziewaj się niejednorodności. W każdej dużej sieci wystąpią różne typy sprzętu, środków transmisji i aplikacji. Aby poradzić sobie z nimi, projekt sieci musi być prosty, ogólny i elastyczny.
Unikaj statycznych opcji i parametrów. Jeśli jakiegoś parametru nie da się uniknąć (np. maksymalnej wielkości pakietu), najlepiej będzie, gdy pozwoli się nadajnikowi i odbiornikowi negocjować wartość zamiast definiować stałe wartości do wyboru.
Dąż do uzyskania dobrego projektu; nie musi być doskonały. Często projektanci dysponują dobrym projektem, który nie radzi sobie z jakimś dziwnym przypadkiem specjalnym. Zamiast mieszać w projekcie projektant powinien pozostać przy dobrym rozwiązaniu i przenieść odpowiedzialność za pracę nad problemem na tego, kto zgłasza dziwne wymogi.
Stosuj ścisłe reguły przy nadawaniu i tolerancyjne przy odbiorze. Inaczej mówiąc, wysyłane pakiety muszą ściśle stosować się do standardów, lecz należy się spodziewać, że odbierane pakiety mogą nie do końca spełniać ich wymogi i starać się poradzić z nimi.
Pamiętaj o skalowalności. Jeśli system ma wydajnie obsługiwać miliony hostów i miliardy użytkowników, scentralizowane bazy danych są niedopuszczalne i obciążenie należy rozkładać na dostępne zasoby tak równo, jak to możliwe.
Bierz pod uwagę wydajność i cenę. Jeśli sieć ma marną wydajność lub skandaliczna cenę. nikt jej nie będzie używać.
Przejdźmy teraz z ogólnych zasad do szczegółów warstwy sieciowej Internetu. W warstwie tej Internet można uznać za zbiór połączonych ze sobą mniejszych sieci, inaczej systemów autonomicznych (AS — Autonomous System). Nie można wyróżnić konkretnej struktury, lecz istnieje kilka głównych sieci szkieletowych, zbudowanych z łączy o dużej przepustowości i szybkich routerów. Do sieci szkieletowych dołączone są sieci regionalne (średniego poziomu), a do tych sieci lokalne licznych uczelni, firm i dostawców usług internetowych. Rysunek 5.46 przestawię szkic tej niby-hierarchicznej struktury.
RYSUNEK 5.46. Internet jest zbiorem wielu połączonych ze sobą sieci
Cały Internet skleja w całość protokół warstwy sieciowej o nazwie IP (Internet Protocol W przeciwieństwie do starszych protokołów warstwy sieciowej został od początku zaprojektowany z myślą o łączeniu różnych sieci. Zadaniem warstwy sieciowej jest udostępnienie metody transport datagramów z wykorzystaniem dostępnych środków (tzn. bez gwarancji) ze źródła do celu, niezależnie od tego, czy komputery mieszczą się w tej samej sieci czy też pomiędzy nimi występują inne sieci.
Komunikacja w Internecie odbywa się następująco: warstwa transportowa pobiera strumienie danych i dzieli je na datagramy. W teorii każdy datagram może mieć do 64 kB, lecz w praktyce zwykle nie przekracza 1500 bajtów (aby zmieścić się w jednej ramce Ethernet). Każdy datagram jest przesyłany przez Internet, czasem po drodze dzielony na mniejsze jednostki. Gdy wszystkie kawałki w końcu dotrą do komputera docelowego, warstwa sieciowa składa je w pierwotny datagram, który przekazuje do warstwy transportowej. Ta z kolei wprowadza datagram do strumienia wejściowego procesu odbiornika. Jak widać z rysunku 5.46, pakiet pochodzący z hosta 1 musi przejść przez sześć sieci, aby dotrzeć do hosta 2.
W praktyce tych sieci często jest o wiele więcej niż sześć.
Właściwym punktem wyjścia do naszych studiów nad warstwą sieciową Internetu jest format datagramu IP. Datagram IP składa się z części nagłówka i części danych. Nagłówek ma część stałą o długości 20 bajtów i część opcjonalną o zmiennej długości. Format nagłówka przedstawia rysunek 5.47. Jest on przesyłany z malejącym porządkiem bitów — od lewej do prawej, przy czym najstarszy bit pola Wersja idzie pierwszy (SPARC używa malejącego porządku bitów; Pentium rosnącego). W komputerach z rosnącym porządkiem bitów niezbędna jest konwersja w oprogramowaniu, zarówno przy nadawaniu, jak i odbiorze.
RYSUNEK 5.47. Nagłówek protokołu IPv4 (Internet Protocol)
Pole Wersja rejestruje, do której wersji protokołu należy datagram. Zawarcie tego pola w każdym datagramie umożliwiło przechodzenie z jednej wersji na drugą trwające kilka lat, z częścią komputerów używających starej wersji i częścią używających nowej. Obecnie trwa przejście z IPv4 na IPv6, które już trwa od kilku lat i jest dalekie od ukończenia (Durand, 2001, Wiljakka, 2002, Waddington i Chang, 2002). Niektórzy sądzą, że to nigdy nie nastąpi (Weiser, 2001). Tak na marginesie, IPv5 był eksperymentalnym protokołem dla strumieni w czasie rzeczywistym, który nigdy nie wszedł do powszechnego użytku.
Ponieważ długość nagłówka nie jest stała, podaje ją pole IHL nagłówka, mierzoną w 32-bitowych słowach. Minimalna wartość wynosi 5 i dotyczy sytuacji, gdy nie są obecne żadne opcje. Maksynalna wartość tego czterobitowego pola wynosi 15, co ogranicza długość nagłówka do 60 bajtów, a pola Opcje do 40. Dla niektórych opcji, takich jak rejestrująca przebytą trasę pakietu, 40 bajtów to o wiele za mało, przez co opcja ta jest bezużyteczna.
Pole Typ usługi jest jednym z niewielu, które z upływem lat zmieniły swoje znaczenie (nieznacznie). Jego przeznaczeniem było i nadal jest odróżnianie różnych klas usług. Możliwe są różne kombinacje niezawodności i szybkości. W cyfrowym przesyłaniu głosu szybkie doręczanie jest znacznie ważniejsze od dokładnego. W transferze plików transmisja wolna od błędów jest ważniejsza od szybkiej.
Pierwotnie sześciobitowe pole zawierało (od lewej do prawej) trzybitowe pole Pierwszeństwo i trzy znaczniki D, T i R. Pole Pierwszeństwo ustalało priorytet, od 0 (zwykły) do 7 (pakiet sterujący siecią). Trzy bity znacznikowe pozwalały hostowi określić, co jest najważniejsze ze zbioru {opóźnienie, przepustowość, niezawodność}. W teorii pola te pozwalają routerom dokonywać wyboru pomiędzy np. łączem satelitarnym o dużej przepustowości (lecz wysokich opóźnieniach) i łączem dzierżawionym o małej przepustowości i małych opóźnieniach. W praktyce routery często całkowicie ignorują pole Typ usługi.
W końcu IETF poddał się i zmienił nieco znaczenie pola, pozwalając na obsługę usług zróżnicowanych. Sześć bitów służy do wskazania, do której z omówionych wcześniej klas usług należy każdy pakiet. Klasy te obejmują cztery priorytety kolejkowania, trzy prawdopodobieństwa odrzucenia i klasy historyczne.
Pole Długość całkowita oznacza cały datagram — nagłówek razem z danymi. Maksymalna długość pakietu wynosi 65 535 bajtów. W chwili obecnej górny limit jest do zaakceptowania, lecz w przyszłych sieciach gigabitowych będą prawdopodobnie potrzebne większe datagramy.
Pole Identyfikacja jest potrzebne, aby umożliwić hostowi docelowemu ustalenie, do którego datagramu należy otrzymany właśnie fragment. Wszystkie fragmenty jednego datagramu zawierają tę samą wartość Identyfikacja.
Następny jest niewykorzystany bit i dwa pola jednobitowe. DF oznacza Don 't Fragment (nie fragmentuj). Jest to polecenie dla routerów, aby nie dzieliły datagramu na fragmenty, ponieważ odbiorca nie jest w stanie składać kawałków w całość. Na przykład w chwili uruchomienia komputera jego ROM może zażądać obrazu pamięci wysłanego jako jeden datagram. Oznaczając datagram bitem DF, nadawca ma pewność, że informacja dotrze w jednym kawałku, nawet jeśli oznacza to, że datagram będzie musiał unikać sieci o małych pakietach obecnych na najlepszej trasie i wybrać trasę nieoptymalną. Od wszystkich urządzeń żąda się przyjmowania fragmentów o długości do 576 bajtów.
MF oznacza More Fragments (więcej fragmentów). Ten bit jest ustawiony we wszystkich fragmentach z wyjątkiem ostatniego. Jest potrzebny do ustalenia, czy dotarły wszystkie fragmenty datagramu.
Pole Pozycja fragmentu mówi, gdzie w bieżącym datagramie leży dany fragment. Wszystkie fragmenty datagramu z wyjątkiem ostatniego muszą mieć długość równą wielokrotności 8 bajtów, co jest elementarną jednostką fragmentacji. Ponieważ pole ma 13 bitów, datagram może mieć maksymalnie 8192 fragmenty, czyli 65 536 bajtów, o jeden więcej niż pozwala pole Długość całkowita.
Pole Czas życia zawiera licznik służący do ograniczania czasu życia pakietu. Powinien liczyć czas w sekundach, pozwalając na maksymalny czas życia równy 255 sekund. Musi być dekrementowany w każdym przeskoku i powinien być dekrementowany wielokrotnie, oczekując na wysłanie w długiej kolejce w routerze. W praktyce po prostu zlicza przeskoki. Gdy dochodzi do zera, pakiet jest odrzucany, a do hosta źródłowego zostaje wysłany pakiet ostrzegający. Ta funkcja zapobiega wiecznemu wędrowaniu datagramów po sieciach, co mogłoby się w przeciwnym razie zdarzyć w razie uszkodzenia tablic routingu.
Gdy warstwa sieciowa zbuduje kompletny datagram, musi wiedzieć, co z nim zrobić. Pole Protokół mówi, do którego procesu transportowego datagram należy. Może to być TCP, lecz również UDP i kilka innych protokołów. Numeracja protokołów jest globalna w całym Internecie. Protokoły i inne przydzielone numery były kiedyś zawarte w RFC 1700, lecz obecnie mieszczą się w bazie danych online w www.iana.org.
Suma kontrolna nagłówka weryfikuje tylko nagłówek. Taka suma kontrolna jest przydatna do wykrywania błędów generowanych przez uszkodzoną pamięć wewnątrz routera. Algorytm dodaje wszystkie 16-bitowe półsłowa w miarę nadchodzenia używając arytmetyki uzupełnień jedynkowych, a następnie bierze uzupełnienie jedynkowe wyniku. Na potrzeby tego algorytmu suma kontrolna nagłówka powinna mieć zero po przybyciu. Jest on bardziej niezawodny od zwykłego dodawania. Suma kontrolna nagłówka musi być obliczana na nowo po każdym przeskoku, ponieważ przynajmniej jedno pole (Czas życia) zawsze się zmienia, lecz obliczenia można przyspieszyć za pomocą pewnych sztuczek.
Adres źródłowy i Adres docelowy wskazują numer sieci i numer hosta. Adresy internetowe omówimy w następnym punkcie. Pole Opcje zostało zaprojektowane jako furtka pozwalająca przyszłym wersjom protokołu zawierać w nagłówku informacje nieobecne w pierwotnym protokole, eksperymentować z nowymi pomysłami i unikać przydzielania bitów nagłówka na informacje rzadko kiedy potrzebne. Opcje mają zmienną długość. Każda zaczyna się od jednobajtowego kodu identyfikującego opcję. W niektórych następny bajt określa długość opcji, a po nim następuje jeden lub więcej bajtów danych. Pole Opcje jest wypełniane do wielokrotności czterech bajtów. Początkowo zdefiniowanych było pięć opcji, które wymienia tabela 5.6, lecz od tamtego czasu dodano kilka nowych. Aktualna kompletna lista jest utrzymywana online pod adresem www.iana.org/ax.signments/ ip-parameters.
TABELA 5.6. | |
---|---|
Kilka opcji IP | |
Opcja | Opis |
Bezpieczeństwo | Określa poziom poufności datagramu |
Rygorystyczny routing wg nadawcy | Podaje pełną trasę, którą ma podążać datagram |
Swobodny routing wg nadawcy | Podaje listę routerów, które nie mogą zostać pominięte |
Rejestruj trasę | Powoduje dołączenie przez każdy router swojego adresu IP |
Znacznik czasowy | Powoduje dołączenie przez każdy router swojego adresu |
i znacznika czasowego |
Opcja Bezpieczeństwo określa, jak poufna jest informacja. W teorii wojskowy router może użyć tego pola, aby nie kierować datagramu przez określone kraje, uznane przez wojsko za „czarne charaktery". W praktyce wszystkie routery ignorują tę opcję, więc przydaje się jedynie szpiegom do łatwiejszego wyszukiwania ciekawych informacji.
Opcja Rygorystyczny routing wg nadawcy (ang. strict source routing) podaje pełną ścieżkę od źródła do celu jako sekwencję adresów IP. Od datagramu wymaga się, by podążał dokładnie tą trasą. Najbardziej przydaje się administratorom systemów do wysyłania pakietów awaryjnych w przypadku uszkodzenia tablic routingu oraz do pomiarów czasu.
Opcja Swobodny routing wg nadawcy (ang. loose source routing) wymaga od pakietu przejścia przez routery podane na liście i w kolejności określonej przez listę, lecz po drodze pakiet może przechodzić też przez inne routery. Zwykle w tej opcji podaje się tylko kilka routerów, aby wymusić konkretną trasę. Na przykład, aby zmusić pakiet przesyłany z Londynu do Sydney do pójścia na zachód zamiast na wschód, w tej opcji można wymienić routery w Nowym Jorku, Los Angeles i Honolulu. Przydaje się głównie wtedy, gdy kwestie polityczne lub ekonomiczne wymagają przechodzenia przez wskazane kraje lub unikania innych.
Opcja Rejestruj trasę każe routerom na całej trasie dołączać swój adres IP do pola opcji. Pozwala to administratorom systemów wyszukiwać błędy w algorytmach routingu („Dlaczego pakiety z Houston do Dallas idą przez Tokio?"). Gdy uruchamiano ARPANET, żaden pakiet nie przechodził nigdy przez więcej niż dziewięć routerów, więc 40 bajtów na opcje wystarczało. Jak już wspomniano, dzisiaj to za mało.
Na koniec opcja Znaczni k czasowy przypomina poprzednią z tą różnicą że oprócz rejestrowania 32-bitowego adresu IP każdy router zapisuje 32-bitowy znacznik czasowy. Ta opcja również najbardziej przydaje się do usuwania błędów w algorytmach routingu.
Każdy host i każdy router w Internecie ma adres IP, w którym jest zakodowany numer sieci i numer hosta. Zestawienie jest unikatowe — w zasadzie żadne dwa urządzenia w Internecie nie mają tego samego adresu IP. Wszystkie adresy IP mają 32 bity długości i są używane w polach Adres źródłowy i Adres docelowy pakietu IP. Należy pamiętać, że adres IP nie odnosi się w rzeczywistości do hosta. Tak naprawdę wskazuje interfejs sieciowy, więc jeśli host jest podłączony do dwóch sieci, musi mieć dwa adresy IP. Jednakże w praktyce większość hostów znajduje się w jednej sieci, zatem ma jeden adres IP.
Przez kilkadziesiąt lat adresy IP były podzielone na pięć kategorii wymienionych na rysunku 5.48. Taki podział zdobył nazwę adresowania klasowego (ang. classful addressing). Nie jest ono już używane, lecz odwołania do niego nadal powszechnie spotyka się w literaturze. Następcę adresowania klasowego omówimy za chwilę.
RYSUNEK 5.48. Formaty adresów IP
Formaty klas A, B, C i D pozwalają na maksymalnie 128 sieci po 16 milionów hostów, 16 384 sieci po 64 k hostów i 2 miliony sieci (np. LAN) po 256 hostów w każdej (aczkolwiek niektóre adresy są specjalne). Poza tym obsługiwane jest rozsyłanie grupowe, w którym datagram jest kierowany do grupy hostów. Adresy zaczynające się od 1111 binarnie są zarezerwowane do przyszłych zastosowań. W chwili obecnej do Internetu podłączonych jest ponad 500 000 sieci i liczba ta rośnie z roku na rok. Numerami sieci zarządza korporacja niedochodowa ICANN (Internet Corporation for Assigned Names and Numbers), aby unikać konfliktów. Z kolei ICANN oddelegowała fragmenty przestrzeni adresów do różnych regionalnych władz, które z kolei rozdzielają adresy IP dostawcom usług internetowych i innym firmom.
Adresy sieciowe, będące 32-bitowymi liczbami, zwykle zapisuje się w notacji dziesiętnej z kropkami. W tym formacie każde z 4 bajtów adresu są zapisywane dziesiętnie jako wartość od 0 do 255. Na przykład 32-bitowy adres szesnastkowy C0290614 jest notowany w formie 192.41.6.20. Najniższy adres IP ma wartość 0.0.0.0, a najwyższy 255.255.255.255.
Wartości 0 i -1 (same jedynki) mają znaczenie specjalne, pokazane na rysunku 5.49. Wartość 0 oznacza daną sieć lub danego hosta. Wartość -1 jest adresem rozgłoszeniowym, który oznacza wszystkie hosty we wskazanej sieci.
Adres IP 0.0.0.0 jest używany przez hosty w chwili uruchamiania. Adresy IP z 0 w miejscu numeru sieci odnoszą się do bieżącej sieci. Pozwalają one komputerom odwoływać się do swojej sieci bez znajomości jej numeru (lecz muszą wiedzieć, do której klasy należy, aby zawrzeć odpowiednią liczbę zer). Adresy złożone z samych jedynek pozwalają na rozgłoszenia w sieci lokalnej, zwykle LAN. Adresy z poprawnym numerem sieci i samymi jedynkami w polu hosta pozwalają komputerom wysyłać rozgłoszenia do odległych sieci w dowolnym miejscu Internetu (aczkolwiek wielu administratorów sieci blokuje tę funkcjonalność). Na koniec adresy w postaci 127.xx.yy.zz są przeznaczone do testowania pętli zwrotnej. Pakiety wysłane na taki adres nie są wprowadzane do kabla, lecz przetwarzane lokalnie i traktowane jak pakiety przychodzące. Pozwala to wysyłać pakiety do sieci lokalnej bez znajomości jej numeru przez nadawcę.
Jak widzieliśmy, wszystkie hosty w sieci muszą mieć ten sam numer sieci. Ta właściwość adresowania IP może powodować problemy w miarę wzrostu wielkości sieci. Rozważmy na przykład uniwersytet, który zaczął od jednej sieci klasy B, używanej przez Wydział Informatyki na potrzeby swoich komputerów w sieci Ethernet. Rok później Wydział Elektryczny chciał podłączyć się do Internetu, więc kupił wzmacniak, aby przedłużyć Ethernet Wydziału Informatyki do swojego budynku. Z upływem czasu wiele innych wydziałów nabyło komputery i limit czterech wzmacniaków na Ethernet został szybko osiągnięty. Potrzebna była inna organizacja.
Uzyskanie drugiego adresu sieciowego może być trudne, ponieważ adresy sieciowe są dobrem deficytowym, a uniwersytet ma już dość adresów na ponad 60 000 hostów. Problem powoduje reguła mówiąca, że adresy jednej klasy A, B lub C odnoszą się do pojedynczej sieci, a nie zbioru sieci LAN. Ponieważ coraz więcej organizacji znajdowało się w takiej sytuacji, potrzebna była mała zmiana w systemie adresowania.
Rozwiązanie polega na tym, że sieć można podzielić na potrzeby wewnętrzne na kilka części, lecz nadal z zewnątrz sprawia wrażenie pojedynczej sieci. Typowa sieć dzisiejszego miasteczka akademickiego może wyglądać jak na rysunku 5.50, z głównym routerem podłączonym do ISP lub sieci regionalnej i szeregiem sieci Ethernet rozrzuconych po różnych budynkach i różnych wydziałach. Każdy Ethernet ma własny router podłączony do głównego (np. szkieletową siecią LAN, lecz natura połączeń między routerami tutaj nas nie interesuje).
W literaturze internetowej elementy sieci (w tym przykładzie pojedyncze sieci Ethernet) nazywa się podsieciami (ang. subnei). Jak wspomnieliśmy w rozdziale 2., to użycie słowa koliduje to z terminem „podsieć" oznaczającym zbiór wszystkich routerów i łączy komunikacyjnych w sieci. Na szczęście z kontekstu powinno być jasne, które znaczenie jest właśnie używane. W tym i w następnym punkcie będziemy używać wyłącznie nowej definicji.
Gdy pakiet dociera do głównego routera, skąd router może wiedzieć, do której podsieci (Ethernetu) ma go wysłać? Moglibyśmy w głównym routerze umieścić tablicę z 65 536 wpisami informującymi router o każdym hoście w miasteczku akademickim. Takie rozwiązanie mogłoby zadziałać, lecz wymagałoby bardzo dużej tablicy w głównym routerze i mnóstwa ręcznej pracy nad utrzymaniem tej tablicy w miarę dodawania, przenoszenia i wyłączania hostów z eksploatacji.
Wynaleziono zatem inny schemat. Zamiast jednego adresu klasy B z 14 bitami na numer sieci i 16 bitami na numery hostów z numeru hosta wzięto część bitów, aby utworzyć numer podsieci. Na przykład, jeśli uniwersytet ma 36 wydziałów, numer podsieci może mieć 6 bitów, a numer hosta 10 bitów, co pozwala na zaadresowanie 64 sieci Ethernet z maksymalnie 1022 hostami w każdej (0 i -1 są niedostępne, jak już wspomniano). Taki podział można później zmienić, jeśli okaże się niewłaściwy.
Aby zaimplementować podział na podsieci, główny router potrzebuje maski podsieci wskazującej miejsce podziału pomiędzy numerem sieci i podsieci oraz numerem hosta, jak na rysunku 5.51. Maski podsieci również są notowane w formie dziesiętnej z kropkami, z dodatkiem ukośnika oraz liczby bitów użytych na część sieć + podsieć. W przykładzie z rysunku 5.51 maskę podsieci można zapisać w formie 255.255.252.0. Alternatywna notacja /22 wskazuje, że maska podsieci ma długość 22 bitów.
RYSUNEK 5.51. Sieć klasy B podzielona na 64 podsieci
Z zewnątrz sieci podział na podsieci nie jest widoczny, więc przydzielenie nowej podsieci nie wymaga zwracania się do ICANN lub zmian w zewnętrznych bazach danych. W tym przykładzie pierwsza podsieć może używać adresów IP zaczynających się od 130.50.4.1, druga od 130.50.8.1, trzecia od 130.50.12.1 i tak dalej. Aby zrozumieć, dlaczego podsieci liczone są co cztery, spójrzmy na ich adresy w postaci binarnej:
Podsieć 1: 10000010 00110010 000001| 00 00000001
Podsieć 2: 10000010 00110010 000010|00 00000001
Podsieć 3: 10000010 00110010 000011|00 00000001
Pionowa poprzeczka (|) oznacza granicę pomiędzy numerem podsieci i numerem hosta. Po lewej znajduje się 6-bitowy numer podsieci, po prawej 10-bitowy numer hosta.
Aby poznać zasadę działania podsieci, musimy wyjaśnić, jak pakiety IP są przetwarzane w routerze. Każdy router zawiera tablicę przechowującą pewną liczbę adresów IP (sieć, 0) i pewną liczbę adresów IP (ta-sieć, host). Pierwszy typ informuje, jak dostać się do odległej sieci. Drugi informuje, jak dostać się do lokalnego hosta. Z wpisem do tablicy skojarzony jest interfejs sieciowy używany do dotarcia do celu i pewne inne informacje.
Gdy do routera dociera pakiet IP, jego adres docelowy jest wyszukiwany w tablicy routingu. Jeśli pakiet jest przeznaczony dla odległej sieci, to zostaje przekazany do następnego routera przez interfejs podany w tablicy. Jeśli jest dla lokalnego hosta (np. w sieci LAN routera), to zostaje wysłany prosto do miejsca przeznaczenia. Jeśli sieć nie jest obecna w tablicy, pakiet zostaje przesłany do routera domyślnego, zawierającego większe tablice. Użycie tego algorytmu oznacza, że każdy router musi posiadać tylko informacje o innych sieciach i o hostach lokalnych, a nie pary (sieć, host), co ogromnie redukuje wielkość tablicy routingu.
Po wprowadzeniu podsieci tablice routingu są zmieniane i zostają do nich dodane wpisy w postaci (ta-sieć, podsieć, 0) i (ta-sieć, ta-podsieć, host). Oznacza to, że router w podsieci k wie, jak dostać się do wszystkich pozostałych podsieci oraz do wszystkich hostów w podsieci k. Nie musi mieć szczegółowych informacji o hostach w innych podsieciach. W istocie jedyna niezbędna zmiana polega na tym, że każdy router wykonuje operację bulowską 1 z maską podsieci, aby pozbyć się numeru hosta, i sprawdza otrzymany wynik w swoich tablicach (po ustaleniu, w której jest klasie sieci). Na przykład pakiet zaadresowany do 130.50.15.6 i docierający do głównego routera po operacji I z maską podsieci 255.255.252.0/22 daje adres 130.50.12.0. Adres ten jest wyszukiwany w tablicy routingu, aby znaleźć linię wyjściową do połączenia się z routerem podsieci 3. Podział na podsieci zmniejsza więc objętość tablic routerów przez utworzenie trzypoziomowej hierarchii złożonej z podsieci, sieci i hosta.
IP jest intensywnie używany od dziesięcioleci. Sprawdził się doskonale, co dowiódł wykładniczy rozwój Internetu. Niestety, IP szybko pada ofiarą własnej popularności — zaczyna mu brakować adresów. Ta nadciągająca klęska wywołała w społeczności Internetu wiele kontrowersji i dyskusji, jak temu zaradzić. W tym podpunkcie opiszemy zarówno problem, jak i kilka proponowanych rozwiązań.
Około roku 1987 kilku wizjonerów przewidziało, że pewnego dnia Internet może rozrosnąć się do 100 000 sieci. Większość ekspertów zlekceważyła ten problem jako odległy o kilkadziesiąt lat, jeśli w ogóle możliwy. Stutysięczna sieć została podłączona w roku 1996. Problem, jak wspomnieliśmy powyżej, polega na gwałtownym kończeniu się dostępnych adresów w Internecie. Teoretycznie istnieją ponad 2 miliardy adresów, lecz praktyka organizacji adresów w klasy (patrz rysunek 5.48) marnuje ich miliony. Największym szkodnikiem są sieci klasy B. Dla większości organizacji sieć klasy A z 16 milionami adresów jest zbyt duża, a sieć klasy C z 256 adresami zbyt mała. Sieć klasy B, mieszcząca 65 534 adresów, jest w sam raz. W folklorze internetowym ta sytuacja jest znana pod nazwą problemu trzech misiów (jak w bajce o Złotowłosej i trzech misiach).
W rzeczywistości pula adresów klasy B jest za duża dla większości organizacji. Badania wykazały, że w ponad połowa wszystkich sieci klasy B mieści mniej niż 50 hostów. Wystarczyłaby sieć klasy C, lecz bez wątpienia każda organizacja, która zażądała klasy B, sądziła, że pewnego dnia przerośnie 8-bitowe pole hosta. Z perspektywy czasu lepiej byłoby, gdyby sieć klasy C używała na adres hosta 10 bitów zamiast 8, pozwalając na 1022 hosty na sieć. Gdyby tak było, większość organizacji zgodziłoby się pewnie na sieć klasy C i takich sieci byłoby ponad milion (w porównaniu z tylko 16 384 sieciami klasy B).
Trudno winić twórców Internetu za to, że nie udostępnili więcej adresów klasy B (dla mniejszych sieci). W czasie, gdy podejmowano decyzję o utworzeniu trzech klas, Internet był siecią badawczą, łączącą główne uniwersytety w USA oraz niewielką liczbę firm i ośrodków wojskowych zajmujących się badaniami sieci komputerowych. Nikt nie wyobrażał sobie, że Internet stanie się masowym systemem komunikacyjnym, rywalizującym z siecią telefoniczną. W tamtych czasach ktoś z pewnością powiedział: „USA ma około 2000 szkół wyższych i uczelni. Nawet gdyby każda z nich połączyła się z Internetem i nawet gdyby dołączyło się wiele uczelni z innych krajów, nigdy nie dojdziemy do granicy 16 000, ponieważ nie ma tylu uniwersytetów na całym świecie. Co więcej, gdy numer hosta zajmuje całkowitą liczbę bajtów, przetwarzanie pakietu przebiega szybciej".
Gdyby jednak w tym podziale przyznano 20 bitów na numer sieci klasy B, pojawiłby się nowy problem — gwałtowny wzrost wielkości tablic routingu. Z punktu widzenia routerów przestrzeń adresów IP tworzy dwupoziomową hierarchię złożoną z numerów sieci i numerów hostów. Routery nie muszą wiedzieć wszystkiego o hostach, lecz muszą wiedzieć wszystko o sieciach. Gdyby w użyciu było pół miliona sieci klasy C, każdy router w całym Internecie potrzebowałby tablicy zawierającej pół miliona wpisów, po jednym na sieć, informujących, której linii użyć, by dostać się do tej sieci, i zawierających jeszcze inne dane.
Fizycznie pamiętanie tablic mających pół miliona wpisów jest do zrobienia, aczkolwiek jest to kosztowne w przypadku krytycznych routerów, które przechowują tablice w statycznej pamięci RAM na kartach wejścia-wyjścia. Bardziej poważnym problemem jest to, że złożoność różnych algorytmów związanych z zarządzaniem tablicami rośnie szybciej niż liniowo. Co gorsze, większość istniejącego oprogramowania routerów (łącznie ze sprzętowym) została zaprojektowana w czasach, gdy Internet składał się z 1000 połączonych sieci, a 10 000 sieci wydawało się odległych o kilkadziesiąt lat. Decyzje projektowe dokonane wtedy są dziś dalekie od optymalności.
Oprócz tego różne algorytmy routingu (np. protokoły z użyciem wektorów odległości) wymagają od każdego routera okresowego wysyłania swoich tablic. Im większe tablice, tym większa szansa, że część informacji straci się po drodze, dając po drugiej stronie niekompletne dane i być może powodując niestabilność routingu.
Problem z tablicami routingu można było rozwiązać przez użycie głębszej hierarchii. Na przykład każdy adres IP mógłby zawierać pole kraju, stanu (prowincji), miasta i sieci. Wówczas router musiałby wiedzieć tylko, jak dostać się do każdego kraju, stanów lub prowincji w swoim kraju, miast w swoim stanie lub prowincji i do sieci w swoi mieście. Niestety, takie rozwiązanie wymagałoby znacznie więcej niż 32 bitów na adres IP i wykorzystywałoby przestrzeń adresów w sposób nieefektywny (np. Liechtenstein potrzebowałby tylu bitów ile USA).
Krótko mówiąc, pewne rozwiązania rozwiązują jeden problem, lecz tworzą następny. Rozwiązaniem, które zostało zaimplementowane i dało Internetowi trochę wytchnienia, jest CIDR — Classless InterDomain Routing (bezklasowy routing miedzydomenowy). Podstawowym założeniem CIDR, opisanego w RFC 1519, jest przydzielanie pozostałych adresów IP w blokach o różnych wielkościach bez zwracania uwagi na klasy. Jeśli jakiś ośrodek potrzebuje np. 2000 adresów, dostaje blok 2048 adresów na 2048-bajtowej granicy.
Porzucenie klas nieco skomplikowało przekazywanie. W starym systemie klasowym przekazywanie działało następująco: gdy pakiet docierał do routera, kopia adresu IP była przesuwana w prawo 0 28 bitów, aby dać 4-bitowy numer klasy. Następnie operacja z 16 rozgałęzieniami sortowała pakiety na klasy A, B, C i D (jeśli była obsługiwana), przy czym 8 przypadków było dla klas A, 4 dla B, dwie dla klasy C i po jednej na D i E. Kod dla każdej klasy maskował następnie 8-, 16- lub 24-bitowy numer sieci i wyrównywał do prawej w 32-bitowym słowie. Następnie numer sieci był wyszukiwany w tablicy A, B lub C, zwykle przez indeksowanie dla klas A i B oraz mieszanie dla sieci C. Po znalezieniu wpisu można było wyszukać linię wyjściową i przekazać pakiet dalej.
W CIDR ten prosty algorytm już nie działa. Zamiast tego każdy wpis w tablicy routingu jest rozszerzany o 32-bitową maskę. Mamy więc teraz jedną tablicę routingu dla wszystkich sieci składająca się z macierzy trójek (adres IP, maska podsieci, linia wyjściowa). Gdy przychodzi pakiet, najpierw zostaje wydobyty jego adres IP. Następnie (ideowo) tablica routingu jest przeszukiwana wpis po wpisie z maskowaniem adresu docelowego i porównywaniem go z wpisami w tablicy. Może się zdarzyć, że pasować będzie większa liczba wpisów z różnymi długościami maski podsieci, w którym to przypadku używana jest maska najdłuższa. Jeśli więc zostanie znalezione dopasowanie dla masek 120 i /24, zostanie użyty wpis dla /24.
Powstały złożone algorytmy przyspieszające proces dopasowywania adresów (Ruiz-Sanchez i in., 2001). Routery dostępne na rynku używają specjalnych układów VLSI z tymi algorytmami realizowanymi sprzętowo.
Aby ułatwić zrozumienie algorytmu przekazywania, rozważmy przykład, w którym dostępne są miliony adresów, zaczynając od 194.24.0.0. Załóżmy, że Cambridge University potrzebuje 2048 adresów i otrzymuje adresy od 194.24.0.0 do 194.24.7.255 z maską 255.255.248.0. Następnie Oxford University prosi o 4096 adresów. Ponieważ blok 4096 adresów musi zaczynać się od granicy 4096 bajtów, nie może otrzymać adresów zaczynających się od 194.24.8.0. Zamiast tego otrzymuje od 194.24.16.0 do 194.24.31.255 z maską podsieci 255.255.240.0. Teraz University of Edinburgh żąda 1024 adresów i otrzymuje adresy od 194.24.8.0 do 194.24.11.255 i maskę 255.255.252.0. Przydziały te przedstawia tabela 5.7.
TABELA 5.7.
Zbiór przydziałów adresów IP
Uniwersytet | Pierwszy adres | Ostatni adres | Liczba | Zapisane w postaci |
---|---|---|---|---|
Cambridge | 194.24.0.0 | 194.24.7.255 | 2048 | 194.24.0.0/21 |
Edinburgh | 194.24.8.0 | 194.24.11.255 | 1024 | 194.24.8.0/22 |
(wolne) | 194.24.12.0 | 194.24.15.255 | 1024 | 194.24.12/22 |
Oxford | 194.24.16.0 | 194.24.31.255 | 4096 | 194.24.16.0/20 |
Tablice routingu na całym świecie są teraz aktualizowane o trzy przydzielone wpisy. Każdy wpis zawiera adres bazowy i maskę podsieci. W zapisie binarnym wyglądają tak:
Adres
C; 11000010 00011000 00000000 00000000
E; 11000010 00011000 00001000 00000000
D; 11000010 00011000 00010000 00000000
Maska
11111111 11111111 11111000 00000000
11111111 11111111 11111100 00000000
11111111 11111111 11110000 00000000
Zobaczmy teraz, co stanie się, gdy przyjdzie pakiet zaadresowany do 194.24.17.4. Ten adres jest binarnie reprezentowany jako 3 2-bito wy łańcuch:
11000010 00011000 00010001 00000100
Najpierw operacja I z maską z Cambridge daje:
11000010 00011000 00010000 00000000
Ta wartość nie pasuje do bazowego adresu Cambridge, więc na oryginalnym adresie przeprowadza się operację I z maską Edinburgh, aby otrzymać:
11000010 00011000 00010000 00000000
Ta wartość nie pasuje do adresu bazowego University of Edinburgh, więc następnie jest sprawdzany Oxford, dając:
11000010 00011000 00010000 00000000
Ta wartość jest zgodna z bazowym adresem Oxford University. Jeśli w dalszej części tablicy nie znajdą się dłuższe dopasowania, zostaje użyty wpis Oksfordu i pakiet zostaje wysłany na linię wskazaną w tym wpisie.
Spójrzmy teraz na te trzy uniwersytety z perspektywy routera w Omaha w stanie Nebraska, który ma tylko cztery linie wyjściowe: do Minneapolis, Nowego Jorku, Dallas i Denver. Gdy oprogramowanie routera otrzymuje te trzy nowe wpisy, zauważa, że może połączyć wszystkie trzy w jeden wpis złożony 194.24.0.0/19 z następującym adresem binarnym i podmaską:
11000010 0000000 00000000 0000000011111111 11111111 11100000 00000000
Ten wpis wysyła wszystkie pakiety przeznaczone dla dowolnego z trzech uniwersytetów do Nowego Jorku. Agregacja tych trzech wpisów pozwoliła routerowi w Omaha zredukować swoją tablicę o dwa
wpisy.
Gdyby Nowy Jork miał jedną linię dla całego ruchu do Wielkiej Brytanii, mógłby również użyć wpisu złożonego. Jeśli jednak ma odrębne linie dla Londynu i Edynburga, musi mieć trzy odrębne wpisy. Składanie (agregacja) jest metodą intensywnie wykorzystywaną w Internecie do redukcji rozmiarów tablic routingu.
Należy jeszcze na koniec przykładu zauważyć, że złożony wpis trasy w Omaha wysyła do Nowego Jorku również pakiety dla nieprzydzielonych adresów. Dopóki te adresy naprawdę nie są przydzielone, nie ma to znaczenia, ponieważ takie pakiety nie powinny występować. Jeśli jednak zostaną w późniejszym terminie przyznane firmie w Kalifornii, potrzebny będzie dla nich dodatkowy wpis 194.24.12.0/22.
Adresy IP są towarem deficytowym. ISP może dysponować adresem /16 (uprzednio klasy B), co daje mu 65 534 numery hostów. Jeśli ma więcej klientów, to ma też problem. Dla klientów domowych z łączami telefonicznymi można go obejść, dynamicznie przydzielając adres IP komputerowi, gdy ten łączy się z serwerem i loguje, oraz odbierając adres po zakończeniu sesji. W ten sposób jeden adres /16 może obsłużyć do 65 534 aktywnych użytkowników, co może prawdopodobnie wystarczyć ISP mającemu kilkaset tysięcy klientów. Po zakończeniu sesji adres IP jest przydzielany innemu użytkownikowi. Wprawdzie ta strategia może sprawdzać się u dostawcy usług internetowych z umiarkowaną liczbą użytkowników domowych, lecz nie wystarcza dla ISP obsługującego głównie firmy.
Problem w tym, że firmy zwykle wymagają połączenia przez cały czas pracy. Zarówno małe firmy, takie jak trzyosobowe biura podróży, jak i duże korporacje, mają wiele komputerów połączonych sieciami lokalnymi. Częścią tych komputerów mogą być PC pracowników, innymi serwery WWW. Najczęściej w LAN znajduje się router połączony z ISP łączem dzierżawionym, które zapewnia stałą łączność z Internetem. Takie rozwiązanie oznacza, że każdy komputer musi mieć przez cały dzień własny adres IP, a zatem całkowita liczba komputerów posiadanych przez wszystkich klientów ISP nie może przekroczyć liczby adresów IP, którymi dysponuje dostawca usług internetowych. Dla adresu /16 ogranicza to łączną liczbę komputerów do 65 534. ISP mający kilkadziesiąt tysięcy klientów instytucjonalnych bardzo szybko przekroczy ten limit.
Sprawę pogarsza jeszcze fakt, że coraz więcej użytkowników domowych abonuje połączenia ADSL i łącza kablowe. Usługi te charakteryzują dwie cechy: użytkownik otrzymuje stały adres IP i me jest pobierana opłata za połączenie, a jedynie abonament miesięczny, więc wielu użytkowników ADSL i modemów kablowych po prostu zostawia komputery zalogowane na stałe. Rozwój tych usług doprowadził do niedoboru adresów IP. Przydzielanie adresów IP na bieżąco, jak dla użytkowników łączy telefonicznych, jest nieprzydatne, ponieważ liczba adresów IP używanych w dowolnej chwili może wielokrotnie przekraczać liczbę posiadanych przez ISP.
Żeby jeszcze trochę skomplikować sprawę, wielu użytkowników ADSL i modemów kablowych ma w domu dwa lub więcej komputerów, nieraz po jednym dla każdego domownika, i wszyscy chcą mieć cały czas połączenie z Internetem, używając jednego adresu, który przydzielił im ISP. Rozwiązanie polega tu na połączeniu wszystkich PC w sieć lokalną i przyłączenie do niej routera. Z punktu widzenia ISP rodzina wygląda teraz jak mała firma z garścią komputerów. Witamy w firmie Kowalski, sp. z o.o.
Niestety, wyczerpywanie się adresów IP nie jest problemem teoretycznym, który być może wystąpi w dalekiej przyszłości. To dzieje się tu i teraz. Rozwiązanie długofalowe polega na migracji Internetu do IPv6, w którym adresy mają długośćl28 bitów. Przejście to już powoli się odbywa, lecz ukończenie tego procesu potrwa lata. Dlatego też stwierdzono, że potrzebne jest na szybko krótkoterminowe rozwiązanie. Pojawiło się ono w formie NAT (Network Address Translation — translacja adresów sieciowych), mechanizmu opisanego w RFC 3022, który podsumujemy poniżej. Dodatkowe informacje prezentuje Dutcher (2001).
Podstawowa idea NAT polega na przydzielaniu każdej firmie jednego adresu IP (lub maksymalnie kilku) do komunikacji z Internetem. Wewnątrz firmy każdy komputer otrzymuje unikatowy adres IP używany do komunikacji wewnętrznej. Gdy jednak pakiet opuszcza firmę i idzie do ISP, odbywa się translacja adresu. Aby umożliwić takie rozwiązanie, zadeklarowano trzy zakresy adresów IP jako prywatne. Firmy mogą ich używać wewnątrz, jak tylko chcą. Jedyna reguła mówi, że żaden pakiet zawierający takie adresy nie może pokazać się w samym Internecie. Trzy zarezerwowane zakresy to:
10.0.0.0 - 10.255.255.255/8 (16.777.216 hostów)
172.16.0.0 - 172.31.255.255/12 (1.048.576 hostów)
192.168.0.0 - 192.168.255.255/16 (65.536 hostów)
Pierwszy zakres daje 16 777 216 adresów (z wyjątkiem 0 i -1, jak zwykle) i jest wybierany przez większość firm, nawet jeśli nie mają tak wielu adresów.
Działanie NAT przedstawia rysunek 5.52. Na terenie firmy każdy komputer ma unikatowy adres w postaci 10.x.y.z. Jednakże każdy pakiet opuszczający firmę przechodzi przez tzw. NAT box (konwerter NAT), który przekształca wewnętrzny źródłowy adres IP (10.0.0.1 na naszym rysunku) na prawdziwy adres IP firmy, w tym przykładzie 198.60.42.12. Konwerter NAT często jest łączony w jednym urządzeniu z zaporą sieciową która zwiększa bezpieczeństwo przez kontrolowanie tego, co wchodzi do firmy i co wychodzi. Zaporami sieciowymi zajmiemy się w rozdziale 8. Można również zintegrować konwerter NAT z routerem firmy.
RYSUNEK 5.52. Umiejscowienie i działanie konwertera NAT
Jak dotąd pomijaliśmy milczeniem jeden drobny szczegół — wracająca odpowiedź (np. z serwera WWW) jest oczywiście zaadresowana do 198.60.42.12, więc skąd konwerter NAT wie, czym zastąpić ten adres? Tu leży problem z NAT. Gdyby w nagłówku IP było jakieś zapasowe pole, można byłoby użyć go do zarejestrowania faktycznego nadawcy, lecz tylko jeden bit jest w nagłówku niewykorzystany. W zasadzie można byłoby zdefiniować nową opcję do zapisania prawdziwego adresu źródłowego, lecz wymagałoby to zmiany kodu IP we wszystkich urządzeniach w Internecie, aby mogły obsługiwać tę opcję. Takie rozwiązanie jako szybka poprawka jest mało obiecujące.
W rzeczywistości wygląda to tak: projektanci NAT zauważyli, że większość pakietów IP niesie ładunek TCP lub UDP. Gdy zajmiemy się TCP i UDP w rozdziale 6., zobaczymy, że oba mają nagłówki zawierające port źródłowy i port docelowy. Poniżej opiszemy wykorzystanie portów TCP. lecz dokładnie to samo obowiązuje dla portów UDP. Są to 16-bitowe liczby całkowite wskazujące, gdzie zaczyna i kończy się połączenie TCP. Porty te udostępniają pole niezbędne, aby mechanizm NAT mógł działać.
Gdy proces chce nawiązać połączenie TCP ze zdalnym procesem, podłącza się do niewykorzystanego portu TCP w swoi komputerze. Nosi on nazwę portu źródłowego i informuje kod TCP, gdzie ma wysyłać przychodzące pakiety należące do tego połączenia. Proces podaje też port docelowy, aby informować, dokąd przekazać pakiety po odległej stronie. Porty od 0 do 1023 są zarezerwowane dla powszechnie znanych usług. Na przykład port 80 jest wykorzystywany przez serwery WWW dla zdalnych klientów. Każdy wychodzący komunikat zawiera zarówno port źródłowy, jak i docelowy. Oba te porty służą do identyfikacji procesów korzystających z połączenia na obu jego końcach.
Możemy jaśniej wytłumaczyć działanie portów na analogii. Wyobraźmy sobie firmę z jednym głównym numerem telefonu. Gdy ktoś dzwoni pod ten numer, to łączy się z operatorem, który pyta o numer wewnętrzny i łączy rozmówcę z tym numerem. Główny numer jest odpowiednikiem adresu IP firmy, a numery wewnętrzne odpowiadają portom. Porty stanowią dodatkowe 16 bitów adresu i pozwalają zidentyfikować, który proces otrzyma przychodzący pakiet.
Używając pola Port źródłowy, możemy rozwiązać nasz problem z odwzorowywaniem. Gdy pakiet wychodzący na zewnątrz trafia do konwertera NAT, adres źródłowy 10.x.y.z zostaje zastąpiony prawdziwym adresem IP firmy. Oprócz tego pole TCP Port źródłowy zostaje zastąpione indeksem do tablicy translacji konwertera NAT zawierającej 65 536 wpisów. Ten wpis zawiera oryginalny adres IP i oryginalny port źródłowy. Na koniec sumy kontrolne nagłówków IP i TCP zostają obliczone na nowo i wstawione do pakietu. Zastąpienie portu źródłowego jest niezbędne, ponieważ połączenia komputerów 10.0.0.1 i 10.0.0.2 mogą używać tego samego portu źródłowego, np. 5000, więc pole Port źródłowy samo nie wystarczy do zidentyfikowania procesu wysyłającego pakiet.
Gdy pakiet dociera z ISP do konwertera NAT, pole Port źródłowy z nagłówka TCP zostaje pobrane i użyte jako indeks do tablicy odwzorowań konwertera. Ze znalezionego wpisu zostają pobrane oraz zapisane w pakiecie wewnętrzny adres IP i oryginalny port źródłowy TCP. Następnie pakiet zostaje przekazany do routera firmy w celu standardowego doręczenia pod adres 10.x.y.z.
NAT może też pomóc w zmniejszeniu niedoborów adresów IP dla użytkowników ADSL i modemów kablowych. ISP przydzielający każdemu użytkownikowi adres używa puli adresów 10.x.y.z. Gdy pakiety z komputerów użytkowników opuszczają ISP i wchodzą do właściwego Internetu, przechodzą przez konwerter NAT przekładający je na prawdziwy adres internetowy ISP. W drodze powrotnej pakiety przechodzą odwrotne odwzorowanie. Pod tym względem dla reszty Internetu ISP jego domowi użytkownicy ADSL i modemów kablowych wyglądają jak duża firma opisana wcześniej.
Wprawdzie ten schemat jakoś rozwiązuje problem, lecz wiele osób zajmujących się IP uznaje go za największe paskudztwo, jakie kiedykolwiek skalało oblicze Ziemi.
Po pierwsze, NAT narusza model architektury IP, w którym każdy adres IP powinien jednoznacznie identyfikować komputer w skali ogólnoświatowej. Na tym założeniu zbudowana jest cała struktura oprogramowania Internetu. W NAT tysiące komputerów mogą używać (i używają) adresu
Po drugie. NAT zmienia Internet z sieci bezpołączeniowej w coś w stylu sieci połączeniowej. Problem w tym, że konwerter NAT musi przechowywać informacje (mapowanie) dla każdego przechodzącego przezeń połączenia. Takie zachowanie jest cechą sieci połączeniowych, a nie bez-połączeniowych. Jeśli konwerter NAT padnie i utraci tablicę odwzorowań, wszystkie jego połączenia TCP zostaną zerwane. Gdy sieć nie stosuje NAT. padnięcie routera nie ma wpływu na TCP. Proces nadający po prostu po kilku sekundach stwierdzi, że upłynął czas oczekiwania i ponownie wyśle wszystkie niepotwierdzone pakiety. W NAT Internet staje się tak wrażliwy na awarie jak sieć z komutacją obwodów.
Po trzecie, NAT narusza najbardziej fundamentalną regułę warstwowości protokołów: warstwa k nie może pod żadnym pozorem przyjmować jakichkolwiek założeń, co warstwa k + 1 umieściła w polu ładunku roboczego. Ta podstawowa reguła pozwala zachować niezależność warstw. Gdyby TCP został w przyszłości zmodernizowany do TCP-2 z inną strukturą nagłówka (np. 32-bitowymi portami), NAT przestałby działać. Cała idea podziału protokołów na warstwy służy temu, by zmiany w jednej warstwie nie wymagały zmian w pozostałych. NAT niszczy tę niezależność.
Po czwarte, procesy w Internecie nie muszą używać TCP lub UDP. Jeśli użytkownik komputera A zdecyduje się użyć jakiegoś nowego protokołu transportowego, by komunikować się z użytkownikiem komputera B (np. na potrzeby aplikacji multimedialnej), użycie konwertera NAT uniemożliwi działanie aplikacji, ponieważ konwerter nie będzie mógł poprawnie zlokalizować portu źródłowego TCP.
Po piąte, niektóre aplikacje wstawiają adresy IP do ładunku pakietu. Odbiornik wydobywa te adresy i używa ich. Ponieważ NAT o tych adresach nie wie nic, to nie może ich zastąpić, więc wszelkie próby użycia ich po odległej stronie zakończą się niepowodzeniem. W ten sposób działa standardowy protokół przesyłu plików FTP (File Transfer Protocol), który może w obecności MAT nie działać, o ile nie zostaną podjęte specjalne kroki zapobiegawcze. Tę samą właściwość ma protokół telefonii internetowej H.323 (który omówimy w rozdziale 7.) i też może zawieść w obecności MAT. Załatanie NAT do współpracy z H.323 jest możliwe, lecz konieczność łatania kodu w konwerterze NAT za każdym razem, gdy pojawi się nowa aplikacja, nie jest zbyt dobrym pomysłem.
Po szóste, ponieważ pole TCP Port źródłowy ma długość 16 bitów, na jeden adres IP można odwzorować maksymalnie 65 536 komputerów. W rzeczywistości ta liczba jest nieco niższa, ponieważ pierwszych 4096 portów jest zarezerwowanych do zastosowań specjalnych. Jeśli jednak dostępnych jest więcej adresów IP, każdy może obsłużyć do 61 440 komputerów.
Te i inne problemy z NAT zostały omówione w RFC 2993. Ogólnie mówiąc, przeciwnicy NAT twierdzą, że załatanie problemu z niedoborem adresów IP za pomocą takiej prowizorycznej i nieeleganckiej sztuczki zmniejsza presję na implementację prawdziwego rozwiązania, czyli przejścia la IPv6, co nie jest korzystne.
Oprócz IP, który używany jest do transferu danych, Internet ma w warstwie sieciowej kilka protokołów sterujących, w tym ICMP, ARP, RARP, BOOTP i DHCP. W tym punkcie przyjrzymy się im kolejno.
Funkcjonowanie Internetu jest dokładnie monitorowane przez routery. Gdy wydarzy się coś nieoczekiwanego, zdarzenie jest raportowane przez ICMP (Internet Control Message Protocol — internetowy protokół komunikatów sterujących), który służy również do testowania Internetu, definiowanych typów komunikatów jest około dwóch tuzinów; najważniejsze z nich przedstawia tabela 5.8. Każdy komunikat ICMP jest kapsułkowany w pakiecie IP.
Komunikat DESTINATION UNREACHABLE jest używany, gdy podsieć lub router nie mogą znaleźć urządzenia docelowego lub gdy nie można dostarczyć pakietu z ustawionym bitem DF, ponieważ drogę blokuje sieć o małych pakietach.
Komunikat TIME EXCEEDED jest wysyłany po odrzuceniu pakietu z powodu osiągnięcia zera przez licznik. Takie zdarzenie może być symptomem zapętlenia pakietów, olbrzymiego przeciążenia lub zbyt małej wartości ustawionej w liczniku.
Komunikat PARAMETER PROBLEM wskazuje, że w polu nagłówka została wykryta niedopuszczalna wartość. Ten problem może oznaczać błąd w oprogramowaniu IP nadającego hosta lub routera, przez który przeszedł pakiet.
Komunikat SOURCE OUENCH był kiedyś używany do hamowania hostów, które wysyłały zbyt wiele pakietów. Gdy host otrzymywał taki komunikat, powinien był zwolnić transmisję. Obecnie jest rzadko używany w przypadkach przeciążeń, ponieważ te pakiety zwykle dolewają oliwy do ognia. Kontrola przeciążeń w Internecie odbywa się obecnie głównie w warstwie transportowej; poznamy ją szczegółowo w rozdziale 6.
Komunikat REDIRECT jest używany, gdy router zauważa pakiet kierowany najwyraźniej złą trasą Służy do informowania przez router hosta nadającego pakiety o możliwym błędzie.
Komunikaty ECHO i ECHO REPLY służą do sprawdzenia, czy dane urządzenie docelowe jest osiągalne i działa. Po odebraniu komunikatu ECHO adresat powinien odesłać z powrotem komunikat ECHO REPLY. Komunikaty TIMESTAMP i TIMESTAMP REPLY są podobne, z tą różnicą że w odpowiedzi zostają zapisane czas otrzymania komunikatu i czas odesłania odpowiedzi. Ten mechanizm pozwala mierzyć szybkość działania sieci.
Poza powyższymi komunikatami zostały zdefiniowane jeszcze inne. Lista online jest utrzymywana obecnie pod adresem www.iana.org/assignments/icmp-parameters.
Wprawdzie każdy komputer w Internecie ma przynajmniej jeden adres IP, lecz adresy te nie mogą służyć do samego wysyłania pakietów, ponieważ sprzęt warstwy łącza danych nie rozpoznaje adresów internetowych. Większość hostów w firmach i na uczelniach dzisiaj podłącza się do LAN poprzez karty interfejsów sieciowych, które rozpoznają tylko adresy LAN. Na przykład każda karta sieciowa Ethernet, która kiedykolwiek została wyprodukowana, ma wbudowany 48-bitowy adres Ethernet. Producenci takich kart zgłaszają do centralnych organizacji zarządzających żądania bloków adresów, aby zapewnić, że żadne dwie karty nie będą miały tego samego adresu (dzięki temu unika się możliwości konfliktu, gdyby kiedykolwiek takie dwie karty pojawiły się w jednej sieci lokalnej). Karty sieciowe wysyłają i odbierają ramki na podstawie 48-bitowych adresów Ethernet. Nie mają najmniejszego pojęcia o 32-bitowych adresach IP.
Powstaje pytanie: jak odbywa się mapowanie adresów IP na adresy warstwy łącza danych takie jak Ethernet? Wyjaśnimy to na przykładzie z rysunku 5.53 przedstawiającym małą uczelnię z kilkoma sieciami klasy C (obecnie nazywanymi /24). Mamy tu dwie sieci Ethernet, jedną na Wydziale Informatyki z adresem IP 192.31.63.0 i jednana Wydziale Elektrycznym z IP 192.31.63.0. ą one połączone pierścieniową siecią szkieletową miasteczka akademickiego (np. FDD1) o adresie 92.31.60.0. Każde urządzenie w Ethernecie ma unikatowy adres Ethernet, oznaczony od E1 do E6, każde urządzenie w sieci FDDI ma adres FDDI oznaczony od F1 do F3.
RYSUNEK 5.53. Trzy połączone sieci /24: dwie Ethernet i jeden pierścień FDDI
Zacznijmy od pokazania, jak użytkownik hosta 1 wysyła pakiet do użytkownika w hoście 2. Załóżmy, że nadawca zna nazwę swojego odbiorcy, na przykład mary@eagle.cs.uni.edu. Pierwszym krokiem będzie znalezienie adresu IP dla hosta 2, znanego pod nazwą eagle.cs.uni.edu. To wyszukiwanie przeprowadza system DNS. Na razie zakładamy, że NS zwrócił adres hosta 2 (192.31.65.5).
Oprogramowanie wyższej warstwy w hoście 1 tworzy teraz pakiet z 192.31.65.5 w polu Adres docelowy i przekazuje go do wysłania do oprogramowania IP. Oprogramowanie IP może sprawdzić adres i ustalić, że znajduje się w tej samej sieci, lecz potrzebuje jakiegoś sposobu na znalezienie docelowego adresu Ethernet. Jednym z rozwiązań może być plik konfiguracyjny gdzieś w systemie, odwzorowujący adresy IP na adresy Ethernet. Wprawdzie takie rozwiązanie jest jak najbardziej możliwe, lecz w przypadku organizacji z tysiącami komputerów aktualizowanie takich plików jest zadaniem podatnym na pomyłki i czasochłonnym.
Lepszym rozwiązaniem będzie wysłanie przez hosta 1 w Ethernet pakietu rozgłoszeniowego z pytaniem, kto jest posiadaczem adresu IP 192.31.65.5. Rozgłoszenie dotrze do każdego komputera w sieci Ethernet 192.31.65.0 i każdy sprawdzi swój adres IP. Tylko host 2 odpowie swoim adresem Ethernet (E2). W ten sposób host 1 dowie się, że adres IP 192.31.65.5 należy do hosta adresie Ethernet E2. Protokół używany do wysyłania takich pytań i odbierania odpowiedzi nosi nazwę ARP (Address Resolution Protocol — protokół rozwiązywania adresów). Używa go niemal każdy komputer w Internecie. ARP został zdefiniowany w RFC 826.
Przewagą ARP nad plikami konfiguracyjnym jest jego prostota. Administrator systemu nie musi przejmować się niczym poza przydzieleniem każdemu komputerowi adresu IP i zdecydowałem o masce podsieci. ARP zrobi resztę.
Teraz oprogramowanie IP w hoście 1 tworzy ramkę Ethernet zaadresowaną do E2, umieszcza pakiet IP (zaadresowany do 192.31.65.5) w jej polu ładunku użytecznego i wrzuca całość w Ethernet. Karta sieciowa Ethernet hosta 2 wykrywa tę ramkę, rozpoznaje że jest przeznaczona właśnie dla niego, wyciągają z sieci i generuje przerwanie. Sterownik Ethernet wydobywa pakiet IP z pola ładunku i przekazuje go do oprogramowania IP, które stwierdza, że pakiet jest zaadresowany poprawnie i przetwarza go.
Możliwe są różnorodne optymalizacje zwiększające wydajność ARP. Zacznijmy od tego. że komputer po wyszukiwaniu ARP zapisuje wynik w pamięci podręcznej na wypadek, gdyby musiał za chwilę skontaktować się z tym samym hostem. Za następnym razem znajdzie odwzorowanie we własnej pamięci, dzięki czemu drugie rozgłoszenie nie będzie potrzebne. W wielu przypadkach host 2 musi odesłać odpowiedź, co również jego zmusza do użycia ARP w celu ustalenia adresu Ethernet nadawcy. Tego rozgłoszenia ARP można uniknąć przez zawarcie przez hosta 1 swojego odwzorowania IP na Ethernet w pakiecie ARP. Gdy rozgłoszenie ARP dociera do hosta 2, para (192.31.65.7, El) zostaje wpisana do pamięci podręcznej hosta 2. W rzeczy samej wszystkie urządzenia w danym Ethernecie mogą wpisać tę parę do swojej pamięci podręcznej ARP.
Jeszcze inna optymalizacja polega na rozgłaszaniu swojego odwzorowania adresu przez każdy komputer w chwili uruchomienia. To rozgłoszenie zwykle ma formę zapytania ARP o własny adres IP. Odpowiedzi nie powinno być, lecz skutkiem ubocznym takiego rozgłoszenia będzie wprowadzenie informacji do pamięci podręcznej każdego komputera. Gdyby przyszła (nieoczekiwana) odpowiedź, oznaczałoby to, że dwóm urządzeniom został przypisany ten sam adres IP. Nowy komputer powinien zgłosić to do administratora systemu i nie uruchomić się.
Aby pozwolić na zmianę odwzorowania, na przykład po wymianie uszkodzonej karty Ethernet na nową (więc mającą nowy adres Ethernet), wpisy w pamięci podręcznej ARP powinny tracić ważność po kilku minutach.
Wróćmy jeszcze do rysunku 5.53. Tym razem host 1 chce wysłać pakiet do hosta 4 (192.31.63.8). Użycie ARP nie da wyniku, ponieważ host 4 nie otrzyma rozgłoszenia (routery nie przekazują dalej rozgłoszeń na poziomie Ethernetu). Możliwe są dwa rozwiązania. Po pierwsze, router INF można skonfigurować tak, by odpowiadał na żądania ARP dla sieci 192.31.63.0 (i ewentualnie innych sieci lokalnych). W takim przypadku host 1 dokona do pamięci podręcznej ARP wpisu (192.31.63.8, E3) i beztrosko będzie wysyłał wszystkie transmisje dla hosta 4 do lokalnego routera. Takie rozwiązanie nosi nazwę pośredniego ARP (ang. proxy ARP). Drugie rozwiązanie polega na tym, że host 1 natychmiast rozpoznaje, iż cel mieści się w odległej sieci i po prostu wysyła wszystkie pakiety pod domyślny adres Ethernet, który obsługuje cały ruch zamiejscowy, w tym przypadku E3. Takie rozwiązanie nie wymaga od routera INF wiedzy, którą zdalną sieć obsługuje.
Tak czy owak host 1 ładuje pakiet IP do pola ładunku użytecznego ramki Ethernet zaadresowanej do E3. Gdy router INF otrzyma taką ramkę, pobiera pakiet IP z pola ładunku i szuka adresu IP w swoich tablicach routingu. Odkrywa, że pakiet dla sieci 192.31.63.0 powinien pójść do routera 192.31.60.7. Jeśli nie zna jeszcze adresu FDDI 192.31.60.7, rozgłasza pakiet ARP w pierścieniu i dowiaduje się, że jego adres w pierścieniu to F3. Następnie wstawia pakiet do pola ładunku ramki FDDI zaadresowanej do F3 i wysyłają w pierścień.
W routerze EL sterownik FDDI wydobywa pakiet z pola ładunku użytecznego i przekazuje do oprogramowania IP, które ustala, że musi przesłać pakiet do 192.31.63.8. Jeśli tego adresu IP nie ma w swojej pamięci podręcznej ARP, to router rozgłasza żądanie ARP w Ethernecie EL i dowiaduje się, że adresem docelowym jest E6, więc konstruuje ramkę Ethernet zaadresowaną do E6, umieszcza pakiet w polu ładunku użytecznego i przesyła przez Ethernet. Gdy ramka ta dociera do hosta 4, pakiet zostaje wydobyty z ramki i przekazany do oprogramowania IP do przetworzenia.
Transmisja z hosta 1 do odległej sieci przez łącze WAN działa zasadniczo tak samo, lecz tym razem tablica routera INF każe skorzystać z routera WAN, którego adresem FDDI jest F2.
ARP rozwiązuje problem ustalenia, który adres Ethernet odpowiada danemu adresowi IP. Czasem trzeba rozwiązać odwrotny problem: jaki jest adres IP odpowiadający danemu adresowi Ethernet? Ten problem występuje podczas uruchamiania bezdyskowej stacji roboczej. Taki komputer otrzymuje zwykle binarny obraz swojego systemu operacyjnego ze zdalnego serwera plików. Lecz jak może poznać swój adres IP?
Pierwszym historycznie rozwiązaniem było użycie protokołu RARP (Reverse Address Resolution Protocol — protokół wstecznego rozwiązywania adresów), zdefiniowanego w RFC 903. Protokół ten pozwala uruchomionemu właśnie komputerowi rozgłosić swój adres Ethernet, mówiąc: „Mój 48-bitowy adres Ethernet to 14.04.05.18.01.25. Czy ktoś tu zna mój adres IP?". Serwer RARP odbiera to pytanie, wyszukuje adres Ethernet w swoich plikach konfiguracyjnych i odsyła odpowiadający mu adres IP.
Korzystanie z RARP jest lepsze od osadzania adresu IP w obrazie pamięci, ponieważ pozwala użyć tego samego obrazu dla wielu komputerów. Gdyby adres IP został zaszyty w obrazie pamięci, każda stacja robocza wymagałaby własnego obrazu.
Wadą RARP jest to, że używa adresu docelowego złożonego z samych jedynek (ograniczone rozgłaszanie), aby połączyć się z serwerem RARP. Takie rozgłoszenia nie są jednak przekazywane przez routery, więc w każdej sieci potrzebny jest osobny serwer RARP. Aby obejść ten problem, wynaleziono alternatywny protokół ładowania początkowego o nazwie BOOTP (BOOTstrap Protocol). W przeciwieństwie do RARP protokół BOOTP używa komunikatów UDP, które są przekazywane przez routery. Oprócz tego podaje bezdyskowej stacji dodatkowe informacje, w tym adres IP serwera plików mieszczącego obraz pamięci, adres IP domyślnego routera i maskę podsieci. BOOTP został opisany w RFC 951, 1048 i 1084.
Poważnym problemem z BOOTP jest to, że wymaga ręcznej konfiguracji tablic odwzorowujących adresy IP na adresy Ethernet. Nowy host dodany do sieci lokalnej nie może korzystać z BOOTP, dopóki administrator nie przydzieli mu adresu IP i nie wprowadzi ręcznie pary (adres Ethernet, adres IP) do tablic konfiguracyjnych BOOTP. Aby wyeliminować ten krok, podatny na pomyłki, protokół BOOTP został rozbudowany i otrzymał nową nazwę — DHCP (Dynamie Host Cofiguration Protocol — protokół dynamicznej konfiguracji hosta). DHCP, opisany w RFC 2131 i 2132, pozwala na przydzielanie adresów IP zarówno ręcznie, jak i automatycznie. W większości systemów zastąpił RARP i BOOTP.
RYSUNEK 5.54. Działanie DHCP
Podobnie jak RARP i BOOTP, DHCP opiera się na idei specjalnego serwera, który przydziela adresy IP żądającym ich hostom. Ten serwer nie musi być w tej samej sieci co host żądający konfiguracji. Ponieważ serwer DHCP może nie być osiągalny przez rozgłoszenia, w każdej sieci LAN musi być obecny agent przekazujący DHCP (ang. DHCP relay agent), jak na rysunku 5.54.
Aby dowiedzieć się o swoim adresie IP, świeżo uruchomiony komputer rozgłasza pakiet DHCP DISC0VER. Agent przekazujący DHCP w jego sieci LAN przechwytuje wszystkie rozgłoszenia dla DHCP. Gdy odbiera pakiet DHCP DISC0VER, wysyła go transmisją pojedynczą do serwera DHCP, który może mieścić się w odległej sieci. Jedyną informacją, której potrzebuje agent przekazujący, jest adres IP serwera DHCP.
Przy automatycznym przydzielaniu adresów IP z dostępnej puli pojawia się pytanie, na jak długo taki adres powinien być przyznawany. Gdyby host po opuszczeniu sieci nie oddał adresu IP do serwera DHCP, adres taki zostałyby na trwałe utracony. Z upływem czasu traciłoby się coraz więcej adresów. Aby temu zapobiec, przydział adresu IP może być ważny przez ustalony czas — ta technika nosi nazwę dzierżawienia. Przed wygaśnięciem dzierżawy host musi zażądać odnowienia od serwera DHCP. Jeśli nie zgłosi żądania lub żądanie zostanie odrzucone, host nie będzie już mógł używać adresu IP, który otrzymał wcześniej.
Zakończyliśmy temat internetowych protokołów sterujących. Pora przejść do nowego tematu: routingu w Internecie. Jak już wspomnieliśmy, Internet jest zbudowany z dużej liczby autonomicznych systemów (AS). Każdy taki system jest eksploatowany przez inną organizację i może wewnątrz używać własnego algorytmu routingu. Na przykład wewnętrzne sieci firm X, Y i Z zwykle widziane są jako trzy systemy autonomiczne, jeśli wszystkie trzy są w Internecie. Każda może wewnętrznie używać innego algorytmu routingu. Jednakże stosowanie standardów, nawet dla routingu wewnętrznego, upraszcza implementację na granicach pomiędzy systemami autonomicznymi i pozwala wykorzystywać ponownie kod. W tym punkcie zajmiemy się routingiem wewnątrz AS. W następnym przyjrzymy się routingowi pomiędzy systemami autonomicznymi. Algorytm routingu wewnątrz AS nosi nazwę protokołu bram wewnętrznych (ang. interior gateway protocol), natomiast algorytm routingu pomiędzy AS jest nazywany protokołem bram zewnętrznych (ang. exterior gateway protocol).
Oryginalnym protokołem bram wewnętrznych Internetu był protokół z użyciem wektorów odległości (RIP) oparty na algorytmie Bellmana-Forda odziedziczonym po sieci ARPANET. Sprawdzał się dobrze w małych systemach, lecz gorzej, gdy systemy autonomiczne zaczęły się rozrastać. Miał też problemy z odliczaniem do nieskończoności i ogólnie wolną zbieżnością, więc w maju 1979 roku został zastąpiony przez protokół stanu łączy. W roku 1988 Internet Engineering Task Force zaczęła pracować nad jego następcą. Następca ten, zwany OSPF (Open Shortest Path First — otwarty z wybieraniem najpierw najkrótszej ścieżki) stał się standardem w roku 1990. Większość producentów routerów zapewnia dziś jego obsługę i OSPF stał się najważniejszym protokołem bram wewnętrznych. Poniżej przestawimy w skrócie działanie OSPF. Pełny opis zawiera RFC 2328.
Biorąc pod uwagę wieloletnie doświadczenia z innymi protokołami routingu, grupa projektująca nowy protokół miała do zrealizowania długą listę wymagań. Po pierwsze, algorytm musiał być opublikowany w otwartej literaturze, stąd w skrócie OSPF litera „O". Zastrzeżone rozwiązanie należące do jednej firmy było nie do przyjęcia. Po drugie, nowy protokół musiał obsługiwać wiele różnorodnych miar odległości, w tym odległość fizyczną, opóźnienie i tak dalej. Po trzecie, musiał być algorytmem dynamicznym, automatycznie i szybko dostosowującym się do zmian w topologii.
Po czwarte, co w OSPF było nowością, musiał obsługiwać routing oparty na typach usług. Nowy protokół musiał być zdolny do kierowania ruchu w czasie rzeczywistym jedną trasą, a innego inną. Protokół IP zawiera pole Typ usługi, lecz nie używał go żaden istniejący protokół routingu. Pole to zostało wprowadzone w OSPF, lecz nadal nikt go nie używał, więc w końcu zostało usunięte.
Po piąte, co wiąże się z poprzednim problemem, nowy protokół musiał zajmować się równoważeniem obciążenia, dzieląc je na więcej linii. Większość istniejących protokołów przesyłało pakiety najlepszą trasą. Druga co do jakości nie była w ogóle używana. W wielu sytuacjach podział obciążenia na kilka linii daje lepszą wydajność.
Po szóste, potrzebna była obsługa systemów hierarchicznych. Do roku 1988 Internet rozrósł się tak bardzo, że od żadnego routera nie można było oczekiwać znajomości całej topologii. Nowy protokół routingu miał być tak zaprojektowany, by żaden router nie był do tego zmuszony.
Po siódme, potrzebna była odrobina zabezpieczeń, aby zapobiec przed zabawami studentów fałszujących routery przez podsyłanie nieprawdziwych informacji o trasach. Oprócz tego potrzebne były mechanizmy obsługi routerów łączących się z Internetem tunelami. Poprzednie protokoły nie radziły sobie z tym najlepiej.
OSPF obsługuje trzy typy połączeń i sieci:
Linie dwupunktowe pomiędzy dokładnie dwoma routerami.
Sieci wielodostępne z rozgłoszeniami (np. większość sieci lokalnych).
Sieci wielodostępne bez rozgłoszeń (np. większość sieci rozległych z komutacją pakietów).
Sieć wielodostępna to taka, która może zawierać większą liczbę routerów zdolnych do komunikacji z wszystkimi pozostałymi. Taką właściwość mają wszystkie sieci lokalne i rozległe. Rysunek 5.55 (a) pokazuje system autonomiczny zawierający sieci wszystkich trzech typów. Proszę zwrócić uwagę, że w OSPF hosty zasadniczo nie odgrywają żadnej roli.
OSPF działa przez zamodelowanie zbioru rzeczywistych sieci, routerów i linii w graf skierowany, w którym do każdego łuku jest przypisany koszt (odległość, opóźnienie itp.). Następnie oblicza najkrótszą ścieżkę, opierając się na wagach łuków. Łącze szeregowe pomiędzy dwoma routerami jest reprezentowane przez parę łuków, po jednym w każdym kierunku. Ich wagi mogą być różne. Sieć wielodostępna jest reprezentowana przez węzeł dla samej sieci i po jednym węźle na każdy router. Łuki od węzła sieci do routerów mają wagę 0 i są w grafie pominięte.
Rysunek 5.55 (b) przedstawia graf reprezentujący sieć z rysunku 5.55 (a). Jeśli nie jest zaznaczone inaczej, wagi są symetryczne. Krótko mówiąc, OSPF reprezentuje rzeczywistą sieć w postaci grafu, a następnie oblicza najkrótsze ścieżki z każdego routera do wszystkich pozostałych.
Wiele systemów autonomicznych w Internecie jest dużych i nie najłatwiejszych do zarządzania. OSPF pozwala na podział AS na ponumerowane obszary, gdzie obszar oznacza sieć lub zbiór spójnych sieci. Obszary nie nakładają się na siebie, lecz nie muszą być wyczerpujące, tzn. niektóre routery nie muszą należeć do żadnego obszaru. Obszar jest uogólnieniem podsieci. Z zewnątrz jego topologia i szczegóły nie są widoczne.
Każdy AS ma obszar szkieletu (ang. backbone), zwany obszarem 0. Wszystkie obszary są połączone z podstawowym, w niektórych wypadkach tunelami, więc z każdego obszaru można w systemie autonomicznym dostać się do dowolnego innego poprzez obszar podstawowy. Tunel w grafie jest reprezentowany jako łuk i ma przypisany koszt. Każdy router połączony z dwoma lub więcej obszarami należy do szkieletu. Podobnie jak w przypadku pozostałych obszarów, topologia szkieletu nie jest widoczna na zewnątrz.
W obrębie obszaru każdy router ma tę samą bazę danych stanów łączy i używa tego samego algorytmu najkrótszej ścieżki. Jego głównym zadaniem jest obliczenie najkrótszej ścieżki od siebie samego do każdego innego routera w obszarze, wliczając w to router połączony ze szkieletem (musi być przynajmniej jeden taki). Router łączący się z dwoma obszarami potrzebuje bazy danych dla każdego obszaru i w każdym musi osobno wyliczać najkrótsze ścieżki.
W normalnej eksploatacji mogą być potrzebne trzy typy tras: wewnątrz obszaru, między obszarami i między systemami autonomicznymi. Trasy wewnątrz obszarów są najłatwiejsze, ponieważ router źródłowy zna już najkrótszą ścieżkę do routera docelowego. Routing pomiędzy obszarami odbywa się zawsze w trzech krokach: ze źródła do szkieletu, w szkielecie do obszaru docelowego i do celu. Ten algorytm wymusza na OSPF konfigurację gwiazdy, w której szkielet jest węzłem centralnym, a inne obszary satelitami. Pakiety są kierowane do celu w stanie „naturalnym". Nie są kapsułkowane ani tunelowane, chyba że kierują się do obszaru połączonego ze szkieletem tylko tunelem. Rysunek 5.56 przedstawia fragment Internetu z systemami autonomicznymi i obszarami.
OSPF rozróżnia cztery klasy routerów:
Routery wewnętrzne mieszczące się całkowicie w obrębie jednego obszaru.
Routery brzegowe łączące dwa lub więcej obszarów.
Routery szkieletowe mieszczące się w obszarze szkieletu.
Routery brzegowe AS łączące się z routerami w innych systemach autonomicznych.
Te klasy mogą się nakładać. Na przykład wszystkie routery brzegowe automatycznie należą do szkieletu. Poza tym router należący do szkieletu, lecz nienależący do żadnego innego obszaru, jest też routerem wewnętrznym. Rysunek 5.56 ilustruje przykłady wszystkich czterech klas routerów.
Po uruchomieniu router wysyła komunikaty HELLO na wszystkich swoich liniach dwupunktowych i rozsyła je grupowo w sieciach LAN do grupy złożonej z wszystkich pozostałych routerów. W WAN może potrzebować dodatkowych informacji o konfiguracji, aby wiedzieć, z kim się kontaktować. Na podstawie odpowiedzi każdy router poznaje swoich sąsiadów. Routery w jednej sieci lokalnej są wszystkie dla siebie sąsiadami.
RYSUNEK 5.56. Związki pomiędzy systemami autonomicznymi, szkieletami i obszarami w OSPF
OSPF działa przez wymianę informacji pomiędzy przyległymi routerami (to nie to samo co routery sąsiadujące). Przede wszystkim komunikacja każdego routera w sieci lokalnej z wszystkimi pozostałymi w tej sieci jest nieefektywna. Aby tego uniknąć, jeden router jest wybierany do roli routera wyróżnionego. Mówi się, że przylega do wszystkich pozostałych routerów w LAN i wymienia z nimi informacje. Routery sąsiadujące, lecz nie przylegle, nie wymieniają pomiędzy sobą informacji. Zastępca wyróżnionego routera jest zawsze aktualizowany, aby ułatwić przejście w razie padu routera wyróżnionego i konieczności natychmiastowej wymiany.
Podczas normalnej eksploatacji każdy router okresowo rozsyła rozpływowo komunikaty LINK STATE UPDATE (aktualizacja stanu łącza) do każdego przyległego routera. Komunikat ten podaje swój stan i koszt użyty w topologicznej bazie danych. Komunikaty rozpływowe są potwierdzane, aby zapewnić niezawodność. Każdy komunikat ma numer sekwencyjny, więc router może widzieć, czy przychodzący LINK STATE UPDATE jest starszy czy nowszy od tego, który już posiada. Routery rozsyłają te wiadomości również po włączeniu i wyłączeniu linii lub zmianie kosztu.
Komunikaty DATABASE DESCRIPTION (opis bazy danych) podają numery sekwencyjne wszystkich wpisów stanów łączy aktualnie posiadanych przez nadawcę. Odbiorca porównując te wartości z własnymi, może ustalić, kto ma najświeższe dane. Te komunikaty są stosowane po włączeniu linii do działania.
Każdy partner może zażądać informacji o stanie łącza od drugiego, używając komunikatu LINK STATE REOUEST (żądanie stanu łącza). Ten algorytm pozwala przyległym routerom sprawdzić, który ma najnowsze dane i w ten sposób nowe informacje rozchodzą się po obszarze. Wszystkie komunikaty są wysyłane jako surowe pakiety IP. Tabela 5.9 zestawia pięć typów dostępnych komunikatów.
Teraz możemy wreszcie poskładać wszystko razem. Za pomocą rozpływu komunikatów router informuje wszystkie pozostałe routery w obszarze o swoich sąsiadach i kosztach. Informacje te pozwalają każdemu routerowi zbudować graf swojego obszaru (obszarów) i obliczyć najkrótsze ścieżki. Obszar szkieletowy robi to samo, lecz ponadto routery obszaru szkieletowego przyjmują informacje od brzegowych routerów obszarów, aby obliczyć najlepsze trasy z każdego routera szkieletowego do wszystkich pozostałych routerów. Informacje te są propagowane z powrotem do routerów brzegowych obszarów, które ogłaszają je w swoich obszarach. Używając tych informacji, router, który chce wysłać pakiet do innego obszaru, może wybrać najlepszy router wyjściowy do szkieletu.
Wewnątrz systemu autonomicznego zalecanym protokołem routingu (aczkolwiek z pewnością nie jedynym używanym) jest OSPF. Pomiędzy systemami autonomicznymi używa się innego protokołu, BGP (Border Gateway Protocol — protokół bram granicznych). Potrzebny jest inny protokół pomiędzy systemami autonomicznymi, ponieważ cele protokołów bram wewnętrznych i zewnętrznych nie są takie same. Od protokołu wewnętrznego oczekuje się jedynie, że będzie jak najefektywniej przenosił pakiety ze źródła do celu. Nie musi martwić się polityką.
Routery protokołów bram zewnętrznych muszą przejmować się polityką, i to bardzo (Metz, 2001). Na przykład, sieć autonomiczna korporacji chce mieć możliwość wysyłania pakietów w dowolne miejsce i odbierać pakiety z dowolnego miejsca w Internecie. Może jednak nie życzyć sobie przenoszenia pakietów pochodzących z zagranicznego AS i przeznaczonych dla innego zagranicznego AS, nawet jeśli własny AS firmy leży na najkrótszej ścieżce pomiędzy zagranicznymi („to ich problem, nie nasz"). Z drugiej strony może zgadzać się na przesyłanie ruchu dla swoich sąsiadów lub nawet konkretnych systemów autonomicznych, które zapłaciły za tę usługę. Na przykład firmy telefoniczne mogą z przyjemnością służyć pasmem swoim klientom, lecz nikomu więcej. Protokoły bram zewnętrznych ogólnie, a BGP w szczególności, zaprojektowano tak, by w ruchu pomiędzy systemami autonomicznymi można było egzekwować wiele różnych zasad (politycznych) routingu.
Typowe zasady biorą pod uwagę czynniki polityczne, ekonomiczne i bezpieczeństwo. Ograniczenia routingu mogą wyglądać np. tak:
Zakaz tranzytu przez określone systemy autonomiczne.
Irak nigdy nie powinien znaleźć się na trasie zaczynającej się w Pentagonie.
Ruch z Kolumbii Brytyjskiej do Ontario nie powinien przebiegać przez USA.
Tranzyt przez Albanię tylko z braku alternatywnych tras do celu.
Transmisje zaczynające się lub kończące w firmie IBM nie powinny przechodzić przez Microsoft.
Zasady są zwykle konfigurowane ręcznie w każdym routerze BGP (lub dołączane za pomocą jakiegoś skryptu). Nie stanowią składnika samego protokołu.
Z punktu widzenia routera BGP świat składa się z systemów autonomicznych i łączących je linii. Dwa systemy są uznawane za połączone, jeśli istnieje linia pomiędzy routerem brzegowym każdego z nich. Biorąc pod uwagę specjalne zainteresowanie BGP ruchem tranzytowym, sieci dzieli się na trzy kategorie. Pierwsza kategoria to sieci końcowe (ang. stub network). które mają tylko jedno połączenie z grafem BGP. Nie można używać ich do tranzytu, ponieważ nikogo nie ma po drugiej stronie. Następne są sieci wielopolączeniowe (ang. multiconnected network), które mogłyby posłużyć do tranzytu, tyle że nie zgadzają się na to. Na koniec mamy sieci tranzytowe, takie jak szkieletowe, które obsługują obce pakiety, czasem z pewnymi ograniczeniami i zwykle nie za darmo.
Pary routerów BGP komunikują się ze sobą, tworząc połączenia TCP. Taki tryb działania zapewnia niezawodną komunikację i ukrywa wszystkie szczegóły sieci, przez które przechodzi komunikacja.
BGP jest zasadniczo protokołem wektorów odległości, lecz znacznie różniącym się od innych, takich jak RIP. Zamiast utrzymywać jedynie koszt do każdego celu, każdy router rejestruje użytą trasę. Podobnie zamiast okresowo podawać każdemu sąsiadowi swój szacowany koszt do każdego możliwego celu, router BGP informuje sąsiadów o dokładnej trasie, której używa.
Jako przykład weźmy routery BGP z rysunku 5.57 (a), a konkretnie tablicę routingu routera F. Załóżmy, że używa ścieżki FGCD, aby dostać się do D. Gdy sąsiedzi przekazują mu swoje informacje o trasach, to podają pełne ścieżki, jak na rysunku 5.57 (b). Dla uproszczenia przedstawiony został jako cel tylko router D.
RYSUNEK 5.57. (a) Zbiór routerów BGP. (b) Informacje wysłane do F
Po otrzymaniu ścieżek od wszystkich sąsiadów F sprawdza, która jest najlepsza. Szybko odrzuca trasy od / i E, ponieważ ich ścieżki przechodzą przez sam F. Do wyboru są więc ścieżki z użyciem B i G. Każdy router BGP zawiera moduł sprawdzający i oceniający trasy do danego celu, który zwraca liczbową „odległość" do tego celu dla każdej trasy. Każda trasa naruszająca ograniczenia ze zdefiniowanych zasad automatycznie otrzymuje wynik nieskończony. Następnie router przyjmuje trasę o najmniejszej odległości. Funkcja oceniająca nie jest składnikiem protokołu BGP i może nią być dowolna funkcja, jakiej zażyczą sobie administratorzy systemu.
BGP z łatwością rozwiązuje problem naliczania do nieskończoności, który nęka inne algorytmy routingu z użyciem wektorów odległości. Załóżmy na przykład, że padnie router G lub linia FG. Wówczas F otrzymuje trasy od trzech pozostałych sąsiadów: BCD, IFGCD i EFGCD. Natychmiast może zauważyć, że dwie ostatnie trasy są bez sensu, ponieważ przechodzą przez sam router F, więc wybiera FBCD jako swoją nową trasę. Inne algorytmy wektorów odległości często dokonują błędnych wyborów, ponieważ nie mogą odróżnić, które sąsiednie routery mają niezależne trasy do celu, a które nie. BGP został zdefiniowany w RFC od 1771 do 1774
Komunikacja IP standardowo odbywa się pomiędzy jednym nadajnikiem a jednym odbiornikiem, jednakże w niektórych zastosowaniach przydaje się zdolność procesu do równoczesnej transmisji do dużej liczby odbiorników. Przykładami mogą być aktualizacja replikowanych, rozproszonych baz danych, rozsyłanie danych giełdowych do wielu maklerów i obsługa cyfrowych telefonicznych połączeń konferencyjnych (tzn. kilka osób jednocześnie).
IP obsługuje rozsyłanie grupowe za pomocą adresów klasy D. Każdy adres klasy D identyfikuje grupę hostów. Do identyfikacji grup dostępnych jest 28 bitów, więc w jednej chwili może istnieć ponad 250 milionów grup. Gdy proces wysyła pakiet na adres klasy D, zostaje podjęta próba doręczenia go do wszystkich członków zaadresowanej grupy, z wykorzystaniem dostępnych środków, lecz nie mamy żadnych gwarancji. Niektórzy członkowie mogą nie dostać pakietu.
Obsługiwane są dwa typy adresów grupowych: trwałe i tymczasowe. Grupy trwałe są zawsze obecne i nie trzeba ich konfigurować. Każda trwała grupa ma trwały adres. Do przykładów takich adresów należą:
224.0.0.1 — wszystkie systemy w sieci lokalnej,
224.0.0.2 — wszystkie routery w sieci lokalnej,
224.0.0.3 — wszystkie routery OSPF w sieci lokalnej,
224.0.0.4 — wszystkie wyróżnione routery OSPF w sieci lokalnej.
Grupy tymczasowe należy utworzyć przed użyciem. Proces może zażądać od swojego hosta dołączenia się do konkretnej grupy; może też zażądać opuszczenia grupy. Gdy ostatni proces w hoście opuszcza grupę, grupa ta przestaje być w tym hoście obecna. Każdy host rejestruje, do których grup aktualnie należą jego procesy.
Rozsyłanie grupowe jest implementowane za pomocą specjalnych routerów, które mogą, lecz nie muszą, być zintegrowane ze zwykłymi routerami. Mniej więcej raz na minutę każdy router rozsyłania grupowego wysyła sprzętową transmisję grupową (tzn. w warstwie łącza danych) do hostów w LAN (adres 224.0.0.1), żądając od nich zgłoszenia grup, do których aktualnie należą ich procesy. Każdy host odsyła odpowiedzi dla wszystkich adresów klasy D, którymi jest zainteresowany.
Te pakiety zapytania i odpowiedzi wykorzystują protokół IGMP (Internet Group Management Protocol — internetowy protokół zarządzania grupami), który przypomina trochę ICMP. Są w nim stosowane tylko dwa typy pakietów: zapytanie i odpowiedź, każdy o prostym, stałym formacie zawierającym pewne informacje sterujące w pierwszym słowie ładunku użytecznego i adres klasy D w drugim słowie. IGMP jest opisany w RFC 1112.
Routing grupowy odbywa się z użyciem drzew częściowych. Każdy router rozsyłania grupowego wymienia informacje ze swoimi sąsiadami, używając zmodyfikowanego protokołu wektorów odległości, tak aby każdy mógł utworzyć drzewa częściowe, po jednym na grupę, obejmujące wszystkich członków grupy. Różne metody optymalizacji są stosowane do okrawania drzew z routerów i sieci niezwiązanych z konkretnymi grupami. Protokół intensywnie wykorzystuje tunelowanie, aby nie zajmować węzłów w drzewie częściowym.
Wielu użytkowników Internetu dysponuje komputerami przenośnymi i chce zachować połączenie z Siecią z dalekich lokalizacji, a nawet podczas podróży. Niestety, z uwagi na system adresowania IP nie tak łatwo jest umożliwić pracę z dala od domu. W tym punkcie omówimy powyższy problem i jego rozwiązanie. Bardziej szczegółowy opis przedstawia Perkins (1998a).
Prawdziwym winowajcą jest sam schemat adresowania. Każdy adres IP zawiera numer sieci i numer hosta. Weźmy na przykład komputer o adresie IP 160.80.40.20/16. W tym adresie 160.80 oznacza numer sieci (41040 w notacji dziesiętnej), a 40.20 numer hosta (10260 w notacji dziesiętnej). Routery na całym świecie zawierają tablice routingu informujące, której linii należy użyć, by dostać się do sieci 160.80. Gdy przychodzi pakiet z docelowym adresem IP w postaci 160.80.xxx.yyy, zawsze zostaje wysłany tą linią.
Gdyby komputer o takim adresie nieoczekiwanie został wywieziony w jakieś odległe miejsce, pakiety nadal będą kierowane do jego macierzystej LAN (lub routera). Właściciel nie dostanie poczty elektronicznej i tak dalej. Przyznanie komputerowi nowego adresu IP, odpowiadającego nowej lokalizacji, jest mało atrakcyjne, ponieważ o zmianie trzeba byłoby powiadomić wiele osób, programów i baz danych.
Inne podejście polega na używaniu przez routery do wyznaczania tras kompletnych adresów IP, a nie tylko sieci. Jednakże taka strategia wymagałaby od każdego routera milionów wpisów w tablicach powodujących astronomiczne koszty dla Internetu.
Gdy użytkownicy zaczęli domagać się zdolności do podłączania swoich notebooków do Internetu niezależnie od lokalizacji. IETF powołał grupę roboczą do znalezienia rozwiązania. Grupa robocza szybko zdefiniowała szereg celów uznanych za pożądane w każdym rozwiązaniu. Najważniejsze z nich były następujące:
Każdy mobilny host powinien być zdolny do użycia swojego macierzystego adresu IP w dowolnym miejscu.
Zmiany oprogramowania w stacjonarnych hostach są niedopuszczalne.
Zmiany w oprogramowaniu i tablicach routerów są niedopuszczalne.
Większość pakietów dla hostów mobilnych nie powinno iść okrężnymi drogami.
Gdy mobilny host znajduje się w lokalizacji macierzystej, nie powinno występować dodatkowe obciążenie zasobów.
Wybrano rozwiązanie opisane w punkcie 5.2.9. Krótko mówiąc, każdy ośrodek, który chce pozwolić swoim użytkownikom na mobilność, musi utworzyć agenta macierzystego. Każdy ośrodek, który chce udostępniać gościnne połączenia, musi utworzyć agenta zewnętrznego. Gdy mobilny host pojawia się w obcej lokalizacji, kontaktuje się z jej agentem zewnętrznym i rejestruje się. Następnie kontaktuje się z agentem macierzystym użytkownika i podaje mu „adres kontaktowy" (ang. care-of address), zwykle własny adres IP agenta zewnętrznego.
Gdy pakiet dociera do macierzystej sieci lokalnej użytkownika, zwykle przychodzi do jakiegoś routera podłączonego do LAN. Następnie router usiłuje zlokalizować hosta na zwykły sposób, rozgłaszając pakiet ARP, np. z zapytaniem o adres Ethernet 160.80.40.20. Agent macierzysty odpowiada na to zapytanie, podając własny adres Ethernet, więc router wysyła pakiety przeznaczone dla 160.80.40.20 do tego agenta macierzystego. Ten z kolei tuneluje je pod adres kontaktowy, kap-sułkując pakiety w polu ładunku pakietu IP zaadresowanego do agenta zewnętrznego. Następnie agent zewnętrzny wydobywa pakiet i doręcza pod adres łącza danych mobilnego hosta. Oprócz tego przesyła adres kontaktowy do nadawcy, dzięki czemu kolejne pakiety mogą być tunelowane wprost do agenta zewnętrznego. Takie rozwiązanie spełnia wszystkie wymienione powyżej wymagania.
Warto wspomnieć o jednym szczególe. W chwili przenosin hosta mobilnego router przypuszczalnie ma jego adres Ethernet (który wkrótce będzie nieaktualny) w pamięci podręcznej. Zastąpienie tego adresu Ethernet adresem agenta macierzystego odbywa się z użyciem sztuczki zwanej „dobrowolnym ARP" (ang. gratuitous ARP). Jest to specjalny, niezamawiany komunikat do routera powodujący zastąpienie konkretnego wpisu w pamięci podręcznej, w tym przypadku adresu hosta, który za chwilę opuści sieć. Gdy użytkownik mobilny wróci do LAN, jego adres będzie można ponownie zmienić w pamięci podręcznej za pomocą tej sztuczki.
Z technicznego punktu widzenia nic nie zapobiega temu, by host mobilny był własnym agentem zewnętrznym, lecz takie podejście działa tylko wtedy, gdy host mobilny (w roli agenta zewnętrznego) jest logicznie połączony z Internetem w bieżącej lokalizacji. Ponadto host mobilny musi być w stanie pozyskać (tymczasowy) adres kontaktowy IP. Adres ten musi należeć do sieci lokalnej, do której host jest aktualnie przyłączony.
Metoda IETF dla hostów mobilnych rozwiązuje też szereg innych problemów, o których do tej pory nie wspomnieliśmy. Na przykład, jak lokalizowane są agendy zewnętrzne? Rozwiązanie polega na okresowym rozgłaszaniu przez każdego agenta swojego adresu i typu udostępnianych usług (np. macierzysty, zewnętrzny lub oba). Gdy mobilny host łączy się gdzieś z siecią, może po prostu nasłuchiwać tych tzw. ogłoszeń lub rozgłosić pakiet oznajmiający swoje przybycie i mieć nadzieję, że lokalny agent zewnętrzny odpowie.
Kolejny problem, który trzeba było rozwiązać, stanowiło pytanie, co zrobić z nieuprzejmymi hostami mobilnymi, które opuszczają sieć bez pożegnania. Rozwiązanie polega na ograniczeniu czasu ważności rejestracji. Jeśli rejestracja nie jest okresowo odświeżana, upływa jej limit czasowy i agent zewnętrzny może oczyścić swoje tablice.
Jeszcze jednym problemem jest bezpieczeństwo. Gdy agent macierzysty otrzymuje komunikat żądający przekazania wszystkich pakietów jakiego użytkownika pod wskazany adres IP, to lepiej żeby nie spełniał żądania, chyba że pochodzi właśnie od tego użytkownika, a nie od kogoś podszywającego się. Do tego celu stosowane są protokoły uwierzytelniania kryptograficznego, które poznamy w rozdziale 8.
Ostatni problem, którym zajęła się grupa robocza, dotyczy poziomów mobilności. Wyobraźmy sobie samolot z pokładową siecią Ethernet używaną przez komputery nawigacyjne i awionikę. W tym Ethernecie znajduje się standardowy router, które łączy się z kablowym Internetem naziemnym za pomocą łącza radiowego. Któregoś pięknego dnia sprytny prezes marketingu wpada na pomysł, aby zainstalować złącza Ethernet w poręczach foteli, aby pasażerowie z komputerami mogli się do nich podłączyć.
Mamy teraz dwa poziomy mobilności: własne komputery samolotu, które są stacjonarne względem pokładowego Ethernetu, oraz komputery pasażerów, które są względem tej sieci mobilne. Mobilność względem systemu, który sam w sobie jest mobilny, można osiągnąć przez rekurencyjne tunelowanie.
Wprawdzie CIDR i NAT mogą jeszcze kupić dla niego kilka dodatkowych lat, lecz każdy zdaje sobie sprawę, że dni IP w aktualnej postaci (IPv4) są policzone. Oprócz omówionych kwestii technicznych zbliża się jeszcze jeden problem. W początkach istnienia Internet był używany głównie przez uniwersytety, nowoczesne branże przemysłu i władze USA (głównie Departament Obrony). Gwałtowny wzrost zainteresowania Internetem od połowy lat 90. spowodował, że zaczęła go używać inna grupa ludzi, przede wszystkim o różnych wymaganiach. Po pierwsze, mnóstwo użytkowników bezprzewodowych urządzeń przenośnych korzysta z Internetu, aby zachować łączność z macierzystą bazą. Po drugie, zbliżanie się do siebie branż: komputerowej, komunikacji i rozrywki może wkrótce spowodować, że każdy telefon i telewizor na świecie będzie węzłem Internetu, przez co pojawią się miliardy urządzeń używających audio i wideo na żądanie. W tych warunkach stało się oczywiste, że IP musi się rozwinąć i nabrać większej elastyczności.
Widząc te problemy na horyzoncie, IETF w 1990 roku zaczął prace nad nową wersją IP, w której nigdy nie miała wyczerpać się pula adresów, rozwiązującą szereg innych problemów i zarazem zapewniającą większą elastyczność i wydajność. Główne założenia były następujące:
Obsługiwać miliardy hostów, nawet przy nieefektywnym przydzielaniu przestrzeni adresów.
Zmniejszyć rozmiary tablic routingu.
Uprościć protokół, aby routery mogły szybciej przetwarzać pakiety.
Zapewnić wyższe bezpieczeństwo (uwierzytelnianie i prywatność) niż bieżący IP.
Zwrócić większą uwagę na typy usług, zwłaszcza dla transmisji danych w czasie rzeczywistym.
Wspomagać rozsyłanie grupowe przez umożliwienie definiowania zakresów.
Umożliwić przenoszenie hosta bez zmiany adresu.
Pozwolić na ewolucję protokołu w przyszłości.
Umożliwić współistnienie przez szereg lat starego i nowego protokołu.
Aby opracować protokół spełniający wszystkie te wymogi, IETF wydał prośbę o propozycje i dyskusję w RFC 1550. Otrzymał dwadzieścia jeden odpowiedzi, z których nie wszystkie były pełnymi propozycjami. Do grudnia 1992 pozostało siedem poważnych propozycji, wahających się od niewielkich poprawek protokołu aż po całkowite wyrzucenie IP i zastąpienie całkowicie nowym protokołem.
Jedna z propozycji sugerowała używanie TCP poprzez CLNP, który z 160-bitową przestrzenią adresów zapewniałby wystarczającą liczbę adresów na wieki i pozwoliłby połączyć dwa liczące się protokoły warstwy sieciowej. Jednakże zbyt wiele osób uważało, że oznaczałoby to przyznanie, iż coś w świecie OSI faktycznie zostało zrobione jak należy (a takie stwierdzenie w kręgach Internetu jest politycznie niepoprawne). CNLP wzorował się ściśle na IP, więc pomiędzy tymi dwoma protokołami większych różnic nie ma. W istocie protokół, który został ostatecznie wybrany, różni się od IP o wiele bardziej niż CLNP. Kolejnym argumentem przeciwko CLNP było słabe wsparcie dla typów usług wymagane dla efektywnego przesyłania multimediów.
Trzy najlepsze propozycje zostały opublikowane w IEEE Network (Deering, 1993, Francis, 1993 oraz Katz i Ford, 1993). Po wielu dyskusjach, poprawkach i przepychankach została wybrana zmodyfikowana kombinacja propozycji Deeringa i Francisa, pod nazwą SIPP (Simple Internet Protocol Plus), którą oznaczono symbolem IPv6.
IPv6 całkiem nieźle spełnia wstępne założenia. Zachowuje dobre cechy IP, odrzuca lub redukuje złe i tam, gdzie trzeba, dodaje nowe. Ogólnie mówiąc, IPv6 nie jest zgodny z IPv4, lecz jest zgodny z innymi pomocniczymi protokołami Internetu, w tym TCP, UDP, ICMP, IGMP, OSPF, BGP i DNS, czasem wymagając niewielkich modyfikacji (głównie po to, by obsłużyć dłuższe adresy). Dodatkowe informacje o IPv6 możemy znaleźć w dokumentach RFC od 2460 do 2466.
Najważniejsza zmiana polega na tym, że IPv6 ma adresy dłuższe niż IPv4. Mają one długość 16 bajtów, co rozwiązuje podstawowy problem — zapewniają praktycznie niewyczerpane zapasy adresów internetowych. O adresach powiemy coś więcej za chwilę.
Drugim ważnym ulepszeniem IPv6 jest uproszczenie nagłówka. Zawiera tylko siedem pól (w porównaniu z 13 w IPv4). Ta zmiana pozwala routerom szybciej przetwarzać pakiety, zwiększając przepustowość i zmniejszając opóźnienia. Nagłówek również omówimy za chwilę.
Trzecim istotnym ulepszeniem IPv6 jest lepsza obsługa opcji. Ta zmiana była niezbędna, ponieważ w nowym nagłówku pola, które uprzednio były wymagane, są opcjonalne. Oprócz tego opcje są reprezentowane odmiennie, dzięki czemu routery mogą łatwiej pomijać opcje nie przeznaczone dla nich. Ta funkcjonalność przyspiesza przetwarzanie pakietów.
Czwartym obszarem, w którym IPv6 stanowi duży postęp, jest bezpieczeństwo. IETF wystarczająco naczytał się wiadomości prasowych o nad wiek rozwiniętych 12-latkach, które ze swoich osobistych komputerów włamywały się do banków i baz wojskowych w całym Internecie. Przekonanie, że coś trzeba zrobić z bezpieczeństwem Internetu, było bardzo silne. Kluczowymi cechami nowego IP są uwierzytelnianie i ochrona prywatności. W funkcje te został później wyposażony również IPv4. więc już nie są takim cudem.
Na koniec większą uwagę poświęcono jakości usług. W przeszłości podejmowano bez większego przekonania wiele prób, lecz dziś, z uwagi na rozwój multimediów w Internecie, zapotrzebowanie jest znacznie większe.
RYSUNEK 5.58. Stały nagłówek IPv6 (wymagany)
Nagłówek IPv6 został przedstawiony na rysunku 5.58. Pole Wersja zawsze zawiera wartość 6 (i 4 dla IPv4). W okresie przejściowym z IPv4, który zapewne potrwa dobrą dekadę, routery będą mogły sprawdzać zawartość tego pola, aby ustalić, z jakim typem pakietu mają do czynienia. Nawiasem mówiąc, ten test marnuje kilka instrukcji w ścieżce krytycznej, więc wiele implementacji będzie go przypuszczalnie unikać, używając jakiegoś pola w nagłówku łącza danych do odróżnienia pakietów IPv4 od IPv6. W ten sposób pakiety mogą być bezpośrednio przekazywane do właściwej funkcji obsługi w warstwie sieciowej. Jednakże zdolność warstwy łącza danych do rozpoznawania typu pakietu sieciowego kompletnie łamie zasadę projektowania mówiącą że żadna warstwa nie powinna być świadoma znaczenia bitów przekazanych do niej z wyższej warstwy. Dysputy pomiędzy zwolennikami porządku i szybkości będą bez wątpienia długie i zażarte.
Pole KI asa ruchu służy do rozróżniania pakietów o różnych wymogach co do doręczania w czasie rzeczywistym. Pole zaprojektowane do tego celu od początku znajdowało się w IP, lecz było jedynie sporadycznie implementowane w routerach. Obecnie trwają eksperymenty w celu ustalenia, jak można je najlepiej wykorzystać do dostarczania multimediów.
Pole Etykieta przepływu nadal jest eksperymentalne, lecz będzie używane do nawiązywania pomiędzy źródłem i celem pseudopołączeń o określonych właściwościach i wymogach. Na przykład strumień pakietów z jednego procesu w określonym hoście źródłowym do wskazanego procesu w określonym hoście docelowym może mieć ścisłe wymogi co do opóźnień i wymagać rezerwowania pasma. Przepływ można skonfigurować z góry i nadać mu identyfikator. Gdy pojawi się pakiet z nie-zerowym polem Etykieta przepływu, wszystkie routery będą mogły sprawdzić w wewnętrznych tablicach, jakiego specjalnego traktowania wymaga ten pakiet. Wobec tego przepływy są próbą połączenia elastyczności podsieci datagramowej z gwarancjami podsieci obwodów wirtualnych.
Każdy przepływ jest określany przez adres źródłowy, adres docelowy i numer, więc jednocześnie pomiędzy daną parą adresów IP może być aktywnych wiele przepływów. Poza tym, nawet jeśli przez router będą przechodzić dwa przepływy z różnych hostów, lecz o tej samej etykiecie, to router będzie mógł je odróżnić, używając adresów źródłowego i docelowego. Oczekuje się, że etykiety przepływu będą przydzielane losowo, a nie sekwencyjnie zaczynając od 1, oczekuje się, że routery będą je mieszać.
Pole Długość ładunku mówi, ile bajtów następuje po 40-bajtowym nagłówku z rysunku 5.58. Nazwa została zmieniona w stosunku do pola z IPv4 (Długość całkowita), ponieważ jego znaczenie nieco się zmieniło: 40 bajtów nagłówka nie wlicza się już do długości, jak uprzednio.
Przy polu Następny nagłówek wychodzi szydło z worka. Nagłówek można było uprościć, ponieważ teraz można stosować opcjonalne nagłówki dodatkowe. To pole informuje, który z (aktualnie) sześciu nagłówków dodatkowych następuje, jeśli w ogóle jest obecny, po bieżącym. Jeśli bieżący jest ostatnim nagłówkiem IP, pole Następny nagłówek informuje, do funkcji obsługi którego protokołu transportowego (np. TCP lub UDP) należy przekazać pakiet.
Pole Limit przeskoków zapobiega krążeniu pakietów w nieskończoność. W praktyce ma to samo znaczenie co pole Czas życia w TTL, to znaczy jest dekrementowane po każdym przeskoku. W teorii w IPv4 czas życia był podawany w sekundach, lecz żaden router nie używał go w ten sposób, więc nazwa została zmieniona, aby bardziej pasować do faktycznego zastosowania.
Następne są pola Adres źródłowy i Adres docelowy. W oryginalnej propozycji Deeringa (SIP) adres miał 8 bajtów, lecz podczas oceny propozycji wiele osób stwierdziło, że przy 8 bajtach adresy IPv6 wyczerpałyby się za kilka dekad, podczas gdy adresów 16-bajtowych nigdy nie braknie. Inni argumentowali, że 16 bajtów to za dużo, podczas gdy jeszcze inni faworyzowali adresy 20-bajtowe, aby zachować zgodność z protokołem datagramów OSI. Jeszcze inne stronnictwo chciało adresów o zmiennej długości. Po wielu debatach zdecydowano, że adres o stałej długości, wynoszącej 16 bajtów, będzie najlepszym kompromisem.
Opracowano nową notację zapisu 16-bajtowych adresów. Są one zapisywane jako osiem grup po cztery cyfry szesnastkowe każda. Grupy rozdzielone są dwukropkami, jak poniżej:
8000:0000:0000:0000:0123:4567:89AB:CDEF
Ponieważ wiele adresów zawiera długie ciągi zer, dopuszczono trzy metody optymalizacji. Po pierwsze, zera na początku grupy można pominąć, więc 0123 będzie zapisane w postaci 123. Po drugie, jedną lub więcej grup szesnastu zerowych bitów można zastąpić parą dwukropków. Wobec tego powyższy adres będzie wyglądać tak:
8000::123:4567:89AB: CDEF
Na koniec adresy IP można zapisać w starej notacji dziesiętnej z kropkami, lecz poprzedzonej dwoma dwukropkami, na przykład:
;:192.31.20.46
Być może taka dokładność opisu nie jest konieczna, lecz adresów 16-bajtowych jest naprawdę dużo. Dokładnie mówiąc, 2128, czyli w przybliżeniu 3 x 1038. Gdyby cała Ziemia, ląd i woda po równo, była pokryta komputerami, IPv6 pozwoliłby na 7 x 1023 adresów na metr kwadratowy. Studenci chemii zauważą, że ta liczba jest wyższa od stałej Avogadra. Wprawdzie zamysłem autorów nie było przydzielenie własnego adresu IP każdej cząsteczce na powierzchni Ziemi, lecz niewiele brakuje.
W praktyce przestrzeń adresowa nie będzie używana oszczędnie, podobnie jak przestrzeń numerów telefonicznych (numer kierunkowy Manhattanu, 212, jest niemal pełny, a Wyoming, 307, prawie pusty). W RFC 3194 Durand i Huitema obliczyli, że używając jako wzorca sposobu przydzielania numerów telefonów, nawet przy najbardziej pesymistycznych założeniach nadal zostanie 1000 adresów IP na każdy metr kwadratowy powierzchni Ziemi (lądu i wody). W każdym realnym scenariuszu powinny ich być tryliony na metr kwadratowy. Krótko mówiąc, w możliwej do przewidzenia przyszłości adresów raczej nie braknie.
Porównajmy teraz nagłówek IPv4 (rysunek 5.47) z nagłówkiem IPv6 (5.58), aby zobaczyć, co zostało pominięte w IPv6. Pole IHL ubyło, ponieważ nagłówek IPv6 ma stałą długość. Pole Protokół zostało usunięte, ponieważ pole Następny nagłówek mówi, co następuje po ostatnim nagłówku IP (tzn. segment UDP czy TCP).
Usunięto wszystkie pola związane z fragmentacją, ponieważ IPv6 stosuje inne podejście do fragmentacji. Po pierwsze, od wszystkich hostów zgodnych z IPv6 oczekuje się, że dynamicznie będą ustalać rozmiar datagramu. Dzięki tej regule fragmentacją będzie występować rzadziej. Poza tym minimum podniesiono z 576 do 1280, aby pozwolić na 1024 bajty danych i większą liczbę nagłówków. Oprócz tego, gdy host wysyła zbyt duży pakiet IPv6, router niezdolny do przekazania go dalej zamiast dzielić pakiet na fragmenty, odsyła komunikat o błędzie. Komunikat ten mówi, że host powinien podzielić wszystkie kolejne pakiety skierowane w tamtą stronę. Generowanie pakietów o właściwej wielkości już w hoście źródłowym jest o wiele wydajniejsze od podziału pakietu na fragmenty w locie przez router.
W końcu znikło pole Suma kontrolna, ponieważ obliczanie tej wartości znacznie pogarsza wydajność. Z uwagi na używane obecnie niezawodne sieci oraz fakt, że warstwy łącza danych i transportowa zwykle mają własne sumy kontrolne, jeszcze jedna suma kontrolna nie była warta swojej ceny.
Usunięcie wszystkich tych funkcji dało odchudzony i skuteczny protokół warstwy sieciowej. Oznacza to, że wybrany projekt spełnił założenia IPv6 — szybkość połączoną z elastycznością i obszerną przestrzeń adresową.
Niektóre z brakujących pól IPv4 bywają jeszcze potrzebne, więc w IPv6 wprowadzono ideę opcjonalnego nagłówka dodatkowego (ang. extension header). Nagłówki te mogą zawierać dodatkowe informacje, lecz zakodowane w efektywny sposób. Obecnie istnieje sześć zdefiniowanych typów nagłówków dodatkowych, które przedstawia tabela 5.10. Każdy z nich jest opcjonalny, lecz jeśli w pakiecie występuje więcej niż jeden, wszystkie muszą następować po nagłówku stałym i raczej w wymienionej kolejności.
Część nagłówków ma stały format, inne zawierają zmienną liczbę pól o zmiennej długości. Dla takich każda pozycja jest kodowana jako trójka (Typ, Długość, Wartość). Typ jest 1-bajtowym polem informującym, z jaką opcją mamy do czynienia. Wartości typu zostały tak wybrane, że dwa pierwsze bity informują routery niewiedzące, jak przetwarzać tę opcję, co z nią zrobić. Do wyboru są: pominięcie opcji, odrzucenie pakietu, odrzucenie pakietu z odesłaniem do nadawcy pakietu ICMP, oraz odrzucenia pakietu z wysłaniem ICMP, z tym wyjątkiem, że dla rozsyłania grupowego nie są zwracane pakiety ICMP (aby niewłaściwy pakiet nie wygenerował milionów raportów ICMP).
Pole Długość również jest jednobąjtowe i informuje, jak długa jest wartość (od 0 do 255 bajtów). Wartość zawiera wymagane informacje do 255 bajtów.
Nagłówek skok po skoku (ang. hop-by-hop) jest przeznaczony na informacje, które muszą sprawdzić wszystkie routery na całej trasie. Jak dotąd zdefiniowano jedną opcję — obsługę datagramów przekraczających 64 kB. Format tego nagłówka przedstawia rysunek 5.59. Gdy jest używany, pole Długość ładunku w stałym nagłówku zawiera wartość 0.
RYSUNEK 5.59. Nagłówek dodatkowy skok po skoku dla dużych datagramów (jumbogramów)
Podobnie jak wszystkie nagłówki dodatkowe, ten zaczyna się od bajta informującego, jaki typ nagłówka będzie następny, po którym następuje pole informujące o długości nagłówka w bajtach (nie licząc pierwszych obowiązkowych ośmiu bajtów). Tak zaczyna się każdy nagłówek dodatkowy.
Następne 2 bajty wskazują, że dana opcja definiuje wielkość datagramu (kod 194) i że wielkość jest liczbą 4-bajtową. Ostatnie cztery bajty podają wielkość datagramu. Rozmiary mniejsze niż 65 536 bajtów nie są dozwolone i spowodują, że pierwszy router odrzuci pakiet i odeśle komunikat błędu ICMP. Datagramy używające tego rozszerzenia nagłówka są nazywane jumbogramami. Jumbogramy są ważne dla aplikacji superkomputerowych, które muszą wydajnie przenosić przez Internet gigabajty danych.
Nagłówek opcji odbiorcy jest przeznaczony na pola, które muszą być interpretowane jedynie w hoście docelowym. W pierwszej wersji IPv6 tylko zdefiniowane opcje służą do wypełniania nagłówka do wielokrotności 8 bajtów, więc początkowo nie będzie używany. Ten nagłówek został zdefiniowany, aby nowe oprogramowanie routingu i hostów było w stanie go obsłużyć na wypadek, gdyby w przyszłości ktoś wymyślił jakieś opcje odbiorcy.
RYSUNEK 5.60. Nagłówek dodatkowy dla routingu
Nagłówek routingu wymienia jeden lub więcej routerów, które muszą zostać odwiedzone po drodze do celu. Jest bardzo podobny do swobodnego routingu wg nadawcy z IPv4, ponieważ wszystkie wymienione adresy muszą być odwiedzone w podanej kolejności, lecz w międzyczasie nogą zostać odwiedzone inne routery, nie zawarte na liście. Format nagłówka routingu przedstawia rysunek 5.60.
Pierwsze 4 bajty dodatkowego nagłówka routingu zawierają cztery jednobajtowe liczby całkowite. Pola Następny nagłówek i Długość nagłówka dodatkowego zostały już opisane. Pole Tyj routingu określa format reszty nagłówka. Typ 0 informuje, że po pierwszym słowie nastąpi zarezerwowane słowo 32-bitowe i pewna liczba adresów IPv6. Inne typy mogą powstać w przyszłości jeśli będą potrzebne. Na koniec pole Zostało segmentów służy do rejestracji, ile adresów na liście jeszcze nie zostało odwiedzonych. Jest dekrementowane po każdym odwiedzeniu takiego adresu Gdy dochodzi do 0, pakietowi pozostawia się wolną rękę bez wskazywania trasy. Zwykle w tym momencie jest już tak blisko celu, że najlepsza trasa jest oczywista.
Nagłówek fragmentacji zajmuje się fragmentacja podobnie jak IPv4. Nagłówek zawiera identyfikator datagramu, numer fragmentu i bit informujący, czy będą następować kolejne fragmenty. W IPv6, w przeciwieństwie do IPv4, tylko host źródłowy może dzielić pakiet na fragmenty. Routery po drodze nie mogą tego robić. Wprawdzie ta zmiana stanowi spore rozstanie z dawniejszą filozofią lecz upraszcza obowiązki routera i przyśpiesza routing. Jak już wspomniano, gdy router otrzyma zbyt duży pakiet, odrzuca go i wysyła do nadawcy pakiet ICMP. Informacja ta mówi hostowi źródłowemu, że powinien podzielić pakiet na mniejsze fragmenty z użyciem tego nagłówka i ponowić próbę.
Nagłówek uwierzytelniania udostępnia mechanizm, dzięki któremu odbiorca może być pewien tożsamości nadawcy. Szyfrowanie ładunku pozwala zaszyfrować zawartość pakietu, aby tylko zamierzony odbiorca mógł go odczytać. Oba nagłówki używają technik kryptograficznych do spełnienia swoich zadań.
Z uwagi na otwarty charakter procesu projektowania i zdecydowane trzymanie się swoich opinii przez wiele zaangażowanych weń osób nie powinno nas zaskoczyć, że wiele decyzji projektowych w IPv6 było, łagodnie mówiąc, kontrowersyjnych. Poniżej omówimy pokrótce kilka z nich. Zainteresowanych brutalnymi szczegółami walki odsyłam do RFC.
Wspomnieliśmy już dyskusję o długości adresu. Wynikiem był kompromis: adresy o stałej, 16-bajtowej długości.
Kolejna walka wywiązała się o długość pola Limit przeskoków. Jeden obóz był mocno przekonany, że ograniczenie liczby przeskoków do 255 (wynikające z użycia 8-bitowego pola) było grubą pomyłką. W końcu powszechnie spotyka się dziś ścieżki mające 32 przeskoki, a za 10 lat mogą stać się wszechobecne znacznie dłuższe trasy. Ta strona argumentowała, że użycie olbrzymiego adresu było dalekowzroczne, lecz użycie maleńkiego licznika przeskoków jest krótkowzroczne. Ich zdaniem największym grzechem, jaki może popełnić informatyk, jest udostępnienie gdzieś za małej liczby bitów.
Przeciwnicy argumentowali, że każde pole można wydłużyć, co doprowadzi do spuchnięcia nagłówka. Ponadto zadaniem pola Limit przeskoków powinno być zapobieganie długiemu krążeniu pakietu, a 65 535 przeskoków to o wiele za dużo. Poza tym w miarę rozwoju Internetu powstawać będzie coraz więcej łączy dalekosiężnych, pozwalających przeskoczyć z jednego kraju do dowolnego innego, wykonując najwyżej pół tuzina przeskoków. Jeśli dotarcie ze źródła lub celu do krajowej bramy międzynarodowej zajmuje więcej niż 125 przeskoków, to coś jest nie w porządku z krajową siecią szkieletową. Tę dyskusję wygrali ośmiobitowcy.
Kolejną śliską sprawą była maksymalna wielkość pakietu. Użytkownicy superkomputerów chcieli pakietów przekraczających 64 kB. Gdy superkomputer zabiera się do nadawania, to robi to na serio i nie życzy sobie przerywania co 64 kB. Przeciwko dużym pakietom argumentowano, że jeśli pakiet o wielkości 1 MB trafi na linię Tl, to zajmie ją na ponad 5 sekund, powodując bardzo zauważalne opóźnienie dla użytkowników interaktywnych współużytkujących tę linię. Tutaj strony poszły na kompromis: ograniczono zwykłe pakiety do 64 kB, lecz można użyć nagłówka dodatkowego skok po skoku, aby przesyłać jumbogramy.
Trzeci gorący temat stanowiło pozbycie się sumy kontrolnej IPv4. Niektórzy przyrównali to do usunięcia hamulców z samochodu. W ten sposób samochód zostaje odciążony i może pojechać szybciej, lecz jeśli zdarzy się coś nieoczekiwanego, może być nieciekawie.
Argumentem przeciwko sumom kontrolnym było to, że jeśli aplikacji naprawdę zależy na integralności danych, to i tak musi mieć sumę kontrolną w warstwie transportowej, więc dodatkowa suma kontrolna w IP (oprócz kolejnej w warstwie łącza danych) jest zbyteczna. Co więcej, z doświadczenia wynika, że obliczanie sumy kontrolnej IP było poważnym kosztem w IPv4. Tę dyskusję wygrał obóz przeciwników sumy kontrolnej i nie zawarto jej w IPv6.
Hosty mobilne też stanowiły kość niezgody. Gdy komputer przenośny przewędruje na drugą półkulę, czy może dalej działać w miejscu docelowym z użyciem tego samego adresu IPv6, czy będzie musiał korzystać z agentów macierzystych i zewnętrznych? Hosty mobilne wprowadzają dodatkowo asymetrię w systemie routingu. Może się zdarzyć, że mały komputer mobilny z łatwością usłyszy mocny sygnał dużego, stacjonarnego routera, lecz router stacjonarny może nie dosłyszeć anemicznego sygnału urządzenia przenośnego. Z tego powodu niektórzy autorzy chcieli jawnie wbudować do !Pv6 obsługę hostów mobilnych. Te próby zakończyły się niepowodzeniem z braku zgody na jedną konkretną propozycję.
Największa chyba bitwa toczyła się o bezpieczeństwo. Każdy zgadzał się, że jest niezbędne, wojna toczyła się o to, gdzie i jak. Zacznijmy od „gdzie". Za umieszczeniem zabezpieczeń w warstwie sieciowej przemawiało to, że stałyby się wtedy standardową usługą dostępną dla wszystkich usług bez planowania z góry. Przeciwko argumentowano, że naprawdę bezpieczne aplikacje nie zadowolą się niczym poniżej szyfrowania całej drogi transmisji, gdzie aplikacja źródłowa szyfruje, a docelowa deszyfruje. Jakiekolwiek obniżenie poziomu zabezpieczeń wystawia użytkownika na łaskę i niełaskę implementacji warstwy sieciowej, która może zawierać błędy i nad którą użytkownik nie ma kontroli. W odpowiedzi na ten argument twierdzono, że takie aplikacje mogą zrezygnować z zabezpieczeń IP i same zabezpieczyć transmisję. Repliką na to było stwierdzenie, że jeśli ktoś nie ufa zabezpieczeniom w warstwie sieciowej, to nie będzie życzył sobie powolnych, spuchniętych implementacji IP mających tę funkcjonalność, nawet jeśli jest wyłączona.
Kolejny aspekt decyzji, gdzie umieścić zabezpieczenia, wiąże się z faktem, że wiele państw (choć nie wszystkie) ma rygorystyczne przepisy eksportowe dotyczące kryptografii. Niektóre, należy tu wymienić Francję i Irak, również ograniczają ich użycie wewnętrznie, więc ludzie nie mogą mieć sekretów przed policją. Z tego powodu wielu implementacji IP używających systemu kryptograficznego wystarczająco silnego, by do czegoś się nadawał, nie można eksportować z USA (i wielu innych krajów) do klientów na całym świecie. Konieczność utrzymywania dwóch zestawów oprogramowania, jednego do użytku krajowego i jednego na eksport, jest bardzo niechętnie widziana przez większość producentów.
Jeden temat nie wzbudził żadnych kontrowersji — nikt nie oczekiwał, że Internet IPv4 zostanie pewnego niedzielnego poranka wyłączony, aby powrócić w poniedziałek jako Internet IPv6. Zamiast tego odizolowane „wyspy" będą konwertowane na IPv6, początkowo komunikując się tunelami. W miarę rozwoju wysepki IPv6 będą zlewać się w większe wyspy. W końcu wszystkie wyspy się połączą i Internet będzie w pełni skonwertowany. Biorąc pod uwagę ogromne inwestycje włożone w zainstalowane obecnie routery IPv4, proces przejścia może potrwać dekadę. Z tego powodu włożono ogromne wysiłki w zapewnienie, by przejście było tak bezbolesne, jak to możliwe. Dodatkowe informacje o IPv6 przedstawia Loshin (1999).
Warstwa sieciowa świadczy usługi warstwie transportowej. Może opierać się albo na obwodach wirtualnych, albo na datagramach. W obu przypadkach jej głównym zadaniem jest kierowanie pakietów ze źródła do celu. W podsieciach obwodów wirtualnych decyzje o wyborze trasy są podejmowane podczas zestawiania obwodu wirtualnego. W podsieciach datagramowych decyzje podejmowane są dla każdego pakietu osobno.
W sieciach komputerowych stosuje się wiele algorytmów routingu. Do algorytmów statycznych należą wybór najkrótszej ścieżki i trasowanie rozpływowe. Do algorytmów dynamicznych należą routing z użyciem wektorów odległości i z użyciem stanu łączy. Większość rzeczywistych sieci używa jednego z nich. Inne ważne kwestie związane z routingiem to routing hierarchiczny, routing dla hostów mobilnych, routing rozgłoszeniowy, grupowy i w sieciach równorzędnych.
Podsieci mogą z łatwością ulec przeciążeniom, co zwiększa opóźnienia i obniża przepływność pakietów. Projektanci sieci usiłują unikać przeciążeń już w fazie projektu. Dostępne techniki obejmują zasady retransmisji, buforowanie, sterowanie przepływem i wiele innych. Gdy wystąpi już przeciążenie, należy się z nim uporać. Można odsyłać do źródła pakiety tłumienia, zrzucać obciążenie i stosować inne metody.
Następnym krokiem wykraczającym poza zwykłe likwidowanie przeciążeń jest próba osiągnięcia obiecanej jakości usług. Dostępnymi tu metodami są buforowanie u klienta, kształtowanie ruchu, rezerwacja zasobów i kontrola wstępu. Do rozwiązań zaprojektowanych dla zapewnienia dobrej jakości usług należą usługi zintegrowane (w tym RSVP), usługi zróżnicowane i MPLS.
Sieci różnią się pod wieloma względami, więc mogą występować problemy przy łączeniu różnych sieci. Czasem problemy takie można obejść przez tunelowanie pakietu przez nieprzyjazną sieć, lecz jeśli sieć docelowa jest innego typu niż źródłowa, takiej metody nie da się zastosować. Gdy w różnych sieciach obowiązuje różna maksymalna wielkość pakietu, może być konieczna fragmentacja.
W Internecie istnieje wiele różnych protokołów związanych z warstwą sieciową. Należy do nich protokół transmisji danych IP, lecz również protokoły sterujące ICMP, ARP i RARP oraz protokoły routingu OSPF i BGP. Pula internetowych adresów IP wyczerpuje się gwałtownie, więc opracowano nową wersję protokołu IP — IPv6.
Podaj dwa przykłady aplikacji komputerowych, dla których odpowiednia jest usługa połączeniowa, oraz dwa przykłady aplikacji, dla których najlepiej nadają się usługi bezpołączeniowe.
Czy w jakichś warunkach usługa połączeniowa może dostarczyć pakiety w niewłaściwej kolejności? Uzasadnij odpowiedź.
Podsieci datagramowe kierują każdy pakiet jako osobną jednostkę, niezależnie od innych. Podsieci obwodów wirtualnych nie muszą tego robić, ponieważ każdy pakiet danych podróżuje trasą z góry ustaloną. Czy to oznacza, że podsieci obwodów wirtualnych nie potrzebują zdolności do kierowania pojedynczych pakietów z dowolnego źródła do dowolnego celu? Wyjaśnij swoją odpowiedź.
Podaj trzy przykłady parametrów protokołu, które mogą być negocjowane podczas nawiązywania połączenia.
Weźmy następujący problem, dotyczący implementacji usługi obwodów wirtualnych: gdy wewnątrz podsieci używane są obwody wirtualne, każdy pakiet danych musi zawierać trzybajtowy nagłówek, a każdy router musi zarezerwować 8 bajtów na identyfikację obwodu. Jeśli użyjemy wewnątrz podsieci datagramów, potrzebne będą nagłówki 15-bajtowe, lecz nie będzie trzeba miejsca w tablicach routera. Transmisja kosztuje 5 groszy za 106 bajtów na przeskok. Bardzo szybką pamięć dla routerów można kupić za 5 groszy za bajt i zakup zamortyzuje się po 2 latach, zakładając 40-godzinny tydzień roboczy. Średnia sesja trwa statystycznie 1000 sekund i zostaje podczas niej wysłanych 200 pakietów. Pakiet potrzebuje średnio czterech przeskoków. Która implementacja jest tańsza i o ile?