Část XIII: Aplikačně orientované vrstvy
Jedním z významných rozdílů mezi referenčním modelem ISO/OSI a TCP/IP je i počet "nejvyšších" vrstev. Zatímco referenční model ISO/OSI má samostatnou prezentační a relační vrstvu, v TCP/IP je nenajdeme. Pokud jsou jejich funkce zapotřební, jsou implementovány až v samotné aplikační vrstvě. Tu samozřejmě najdeme jak u RM ISO/OSI, tak i u TCP/IP. Ovšem představa, že do aplikační vrstvy spadají celé aplikace, používané koncovými uživateli, není zcela správná.
našem putování vrstvami referenčního modelu ISO/OSI směrem "zdola nahoru" jsme se dostali až k nejvyšším vrstvám, označovaným jako "aplikačně orientované". Jsou to vrstvy, nacházející se nad vrstvou transportní, kterou jsme se zabývali minule. Jak vidíme na dnešním prvním obrázku, počet těchto vrstev se v ISO/OSI a TCP/IP výrazně liší a to si určitě zaslouží vysvětlení. Takže proč tomu tak je? Odpověď je taková, že autoři obou architektur přemýšleli o tom, zda a jak často budou aplikace potřebovat určité funkce (prezentační a relační funkce, viz dále). Autoři RM ISO/OSI dospěli k závěru, že spíše častěji a tak považovali za správné poskytnout tyto funkce všem aplikacím, právě formou samostatné prezentační a relační vrstvy. Naopak autoři TCP/IP dospěli při svých výchozích úvahách k závěru, že využití těchto funkcí nebude až tak časté, a tak se nevyplatí vnucovat je každému (ve formě samostatných vrstev). Pokud je některá aplikace potřebovat bude, ať si je raději zajistí (implementuje) sama, podle svých vlastních představ, ale hlavně ve vlastní režii.
Právě režie je totiž faktorem, který v uvedených úvahách sehrál významnou roli. Každá vrstva už svou samotnou existencí představuje určitou režii, vynakládanou na to, aby data přes takovouto vrstvu prošla. Pokud by ve většině případů taková vrstva vlastně s daty nic nedělala, pak by byla režie na průchod vrstvou úplně zbytečná. Proto autoři TCP/IP raději příslušné vrstvy nezařadili do svého vrstevnatého modelu (když usoudili, že funkce těchto vrstev nebudou příliš často využívány). Naopak autorům RM ISO/OSI vyšlo, že když bude příslušné funkce využívat většina aplikací, režie na existenci samostatných vrstev bude vynaložená účelně.
Abychom různá rozhodnutí autorů RM ISO/OSI a TCP/IP mohli plně docenit, pojďme si nyní naznačit trochu podrobněji, v čem vlastně spočívají prezentační a relační služby.
Relační vrstva a relační služby
Relační vrstva je v ISO/OSI asi nejvíce kritizovanou vrstvou, protože toho má relativně nejméně na práci. Původní představa autorů byla zřejmě taková, že v této vrstvě budou soustředěny takové funkce, které usnadňují a podporují vzájemnou interakci komunikujících stran (tzv. relace, anglicky sessions). Například ve smyslu zajištění bezpečnosti podobné interakce. Nebo ve smyslu podpory transakčního zpracování, kde je důležité, aby se žádná transakce neprovedla "jen tak napůl", ale vždy jen úplně celá (nebo se naopak neprovedlo vůbec nic). Příkladem může být nějaká finanční transakce, spočívající v odepsání určité částky z jednoho účtu a připsání téže částky na jiný účet. Tady by skutečně nebylo korektní, aby proběhla jen jedna část transakce (odepsání částky z jednoho účtu), ale už se neprovedly ostatní části transakce (připsání na jiný účet).
Již na tomto prvním příkladu je dobře patrné hlavní dilema: mají být věci, jako je podpora transakcí, řešeny samostatně na úrovni relační vrstvy, tudíž pro všechny aplikace stejně? Nebo je vhodnější, aby si je aplikace řešily samy, podle svých vlastních představ? Tady je vhodné si uvědomit, že třeba bankovní aplikace budou mít zřejmě podstatně přísnější požadavky na "kvalitu" zajištění transakcí než nějaké jednodušší databázové aplikace, kde nehrozí takové následky při nekorektním provedení transakce. I v tomto ohledu zřejmě autoři TCP/IP usoudili, že je lepší, když podporu transakcí provede každá aplikace sama podle svého (hlavně podle svých nároků a požadavků), zatímco autoři RM ISO/OSI byli opačného názoru. Současná praxe dává celkem jednoznačně za pravdu autorům TCP/IP.
Původně uvažované úkoly relační vrstvy samozřejmě nekončily u již zmiňované bezpečnosti a transakčního zpracování. Zahrnovaly například podporu vzájemné synchronizace komunikujících stran (ovšem v jiném smyslu, než jak jsme mluvili o synchronizaci na úrovni fyzické vrstvy). Zde jde kupř. o to, že když při nějakém přenosu většího objemu dat mezi dvěma stranami dojde k výpadku spojení, musí se začít úplně znovu: navázat nové spojení a přenášet data od začátku. Relační vrstva však může nabízet výhodnější možnost: vrátit se k určitému "kontrolnímu bodu" a pokračovat od něj, nikoli od začátku. Takových kontrolních bodů může existovat více a v přerušené relaci pak lze pokračovat od kteréhokoli z nich. Vlastně ne nutně od kteréhokoli, protože to by bylo příliš drahé. Jednotlivé kontrolní body jsou totiž jakýmisi body zotavení, v jejichž rámci je uschován celý stav právě probíhající relace (včetně dosud přenesených dat). A to představuje poměrně velkou režii, kvůli níž se starší kontrolní body již mohou "uvolňovat" a není možné se k nim vracet. Situaci naznačuje obrázek s vedlejšími kontrolními body a hlavním kontrolním bodem (hlavní je ten kontrolní bod, přes který se již nelze vrátit hlouběji do historie relace, ke starším vedlejším bodům). Do relační vrstvy by nejspíše patřily i takové služby, jaké dnes v rámci TCP/IP zajišťuje protokol SIP. Ten má podporu relací dokonce ve svém názvu, protože jeho název je zkratkou od Session Initiation Protocol (doslova: podpora navazování relací). Pochází z oblasti internetové telefonie a službám na bázi VOIP slouží k navazování telefonických hovorů. Řeší zejména takové věci, jako je vyhledání volaného (podle telefonního čísla), aby k němu mohlo být navázáno transportní spojení a následně veden hlasový hovor. Příznačné ovšem je, že v rámci TCP/IP jde o aplikační protokol protože, jak již víme, TCP/IP nemá samostatnou relační vrstvu. A docela dobře se bez ní obejde.
Prezentační služby: hlavně konverze
Zatímco u relační vrstvy není úplně snadné vysvětlit, co by vlastně měla mít na starosti, v případě prezentační vrstvy je to naštěstí snazší. Stačí vyjít z následující úvahy: všechny nižší vrstvy (pod prezentační vrstvou) se snaží přenášet data jak "stojí a leží", aniž by se jakkoli změnila. Můžeme si to představit také tak, že přenáší skupiny bitů a snaží se, aby se při přenosu nezměnil ani jeden bit. Jenže to nemusí být vždy správné! Proč?
Třeba proto, že ona data mají určitý význam. Může to být například text, mohou to být čísla nebo nějaké obecnější datové struktury, od jednoduchých vícerozměrných polí až po struktury provázané pointry. Ovšem na různých platformách mohou být stejné texty, stejná čísla či stejné datové struktury reprezentovány úplně jinak. Třeba jen u textů může být rozdíl v tom, zda jsou jednotlivé znaky kódovány v kódu ASCII, v kódu EBCDIC nebo v nějakém úplně jiném kódu (Unicode atd., nehledě již na různé národní znakové sady (CP xy atd.). Asi není těžké nahlédnout, že v takovém případě musí být přenášené texty vhodně překódovány (konvertovány, pomocí vhodné konverze). A právě to má na starosti vrstva prezentační: stará se o to, aby přenášená data měla stejný význam pro obě komunikující strany.
Pro dokreslení celé problematiky konverzí se zmiňme ještě o jednom "ještě více základním" rozdílu, než je kódování jednotlivých znaků v textech. Jde o pořadí bytů (tzv. byte order), přesněji o způsob umisťování vícebytových položek do paměti. Pro jednoduchost si to představme na dvoubytovém slově (tedy na dvou bytech, tvořících jednu položku). Máme-li nějakou dvoubytovou hodnotu, například 1234H (hexadecimálně), můžeme ji uložit do dvou paměťových míst (každé o velikosti jednoho bytu) dvěma různými způsoby:
vyšší polovinu bitů (12H) do paměťového místa na vyšší adrese (např. na adrese 1), nižší polovinu bitů (34H) do paměťového místa na nižší adrese (např. 0), nebo
vyšší polovinu bitů (12H) vložíme do paměťového místa na nižší adrese (0), nižší polovinu bitů (34H) do paměťového místa na vyšší adrese (1).
Obě možnosti jsou stejně smysluplné, žádná z nich není výhodnější než ta druhá. Pro jejich označení se používají termíny, převzaté z angličtiny: Little Endian, resp. Big Endian. Proč, stojí za malou vsuvku, kterou si můžete přečíst níže. V běžné praxi jsou obě varianty rozloženy víceméně rovnoměrně: například procesory Intel používají konvenci Little Endian, zatímco procesory Motorola konvenci Big Endian. Variantu Big Endian používají také protokoly TCP/IP.
Tlustokoncoví proti tenkokoncovým, aneb proč říše Lilliput bojuje proti říši Blefuscu
O komplikovanějších věcech se lidé obvykle dohodnou relativně snadno. Ale běda, jak přijde na přetřes něco jednoduchého, až přímo banálního. Něco, čemu rozumí každý. Pak se snad vždy najdou lidé, kteří se potřebují vypovídat a hlavně vehementně prosazovat to či ono stanovisko (lhostejno které). Někdy jakoby platila nepřímá úměra: čím banálnější je celá kauza, tím větší vášně provází volbu jedné z možných variant. V době internetu z toho bývají nekonečné flamewars ("psané" slovní přestřelky), které si v ničem nezadají s jinými formami lidských hádek. Lidská tendence ke sporu i o největších banalitách je nejspíše tak stará, jak lidstvo samo.
Celý tento nešvar již v 18. století hezky zparodoval Jonathan Switft ve svých známých Gulliverovách cestách. Popisoval, jak se jeho hlavní hrdina dostal do říše Blefuscu, která byla právě ve válce s říší Liliput ohledně toho, zda se mají vajíčka rozbíjet na užším konci, nebo naopak na silnějším konci. V anglickém originále to je "at the little end" (na užším konci), resp. "at the big end" (na silnějším konci). Proto také Switft ve svém díle označil znesvářené strany jako "Little Endians" a "Big Endians" (v českém překladu třeba jako "tenkokoncoví" a "tlustokoncoví"). Původní inspirací Jonathana Swifta přitom byly náboženské spory mezi Anglií a Francií, přesněji mezi anglikánskou církví a katolickou církví ve Francii, a ve svých Gulliverových cestách chtěl upozornit na malichernost jejich podstaty.
Na způsob, jakým Swift svou kritiku malicherných sporů zasadil do svého literárního díla, si v roce 1980 vzpomněl pan Danny Cohen, když psal odborný text pojednávající o problému kolem pořadí bytů. I on chtěl nějak vyřešit vlekoucí se učené disputace ohledně toho, které pořadí bytů je správné (tedy která varianta ukládání vícebitových položek do paměti je vhodnější). Aby zdůraznil malichernost těchto sporů, které jakoby nebraly konce, vypůjčil si Swiftovu terminologii a poprvé pojmenoval obě varianty jako "Little Endian" a "Big Endian". Celý svůj text pak nazval velmi příznačně: "On Holy Wars and a Plea for Peace" (O svatých válkách a volání po míru). Napsal to tak hezky a od srdce, že se jím navržená terminologie ujala a používá se dodnes.
Tlustokoncoví však nabyli na dvoře císaře blefuskuánského tolik vážnosti a zde doma jim jejich strana tajně poskytuje tolik soukromé podpory a tak je podněcuje, že obě říše vedou posledních šestatřicet měsíců se střídavým štěstím krvavou válku. Za tu dobu jsme přišli o čtyřicet znamenitých lodí a mnohem více menších plavidel s třiceti tisíci nejlepších námořníků a vojáků. Počítá se, že nepřítel utrpěl o něco větší škodu než my.
Jonathan Switft, Gulliverovy cesty: O stranách podpatkářů a válkách kvůli vejcím
Linearizace a ASN.1 místo XML
Pořadí bytů, tedy volba mezi Little Endian a Big Endian, je samozřejmě jen jednou drobnou kostičkou celkové mozaiky toho, co zajišťuje prezentační vrstva. Abychom správně docenili její význam a princip fungování, řekněme si ještě o jedné důležité věci: když má prezentační vrstva přenést nějaká konkrétní data "na druhou stranu", musí je nejprve "zlinearizovat". Tedy převést do takového tvaru, aby mohla být přenesena po lineární (jednorozměrné) přenosové cestě. Například u dvourozměrných polí si to lze představit docela snadno: vezmou se postupně jednotlivé sloupce (nebo naopak řádky), které už lineární jsou, a ty se posílají (viz obrázek).
V případě vícerozměrných polí je řešení prakticky stejně snadné, byť jen trochu náročnější na představivost. Složitější to ale může být u obecnějších datových struktur. Zdaleka nejsložitější je to pak u datových struktur, provázaných ukazateli (tzv. pointry). Ukazatele totiž nelze přenést vůbec, protože mají pouze "místní význam" u odesilatele. Místo toho je nutné příslušnou datovou strukturu nahradit nějakým ekvivalentem, který již ukazatele (pointry) neobsahuje. To je obvykle možné, ale podtrhuje to význam dalšího úkolu, který musí prezentační vrstva řešit. Tímto úkolem je popsat data, přenášená skrze přenosový kanál, takovým způsobem, aby je příjemce dokázal zase "vrátit do původní podoby". Tedy rekonstruovat je tak, aby pro něj měly stejný význam jako pro odesilatele.
S určitým zjednodušením si můžeme představit, že prezentační vrstva se tohoto úkolu dokáže zhostit tak, že k přenášeným datům přibalí jakousi "průvodku". Tedy popis toho, co se vlastně přenáší, aby to příjemce dokázal správně "vybalit" a následně "poskládat". Samozřejmě tak musí činit způsobem, který bude předem dohodnutý a známý oběma stranám (jinak by příjemce nerozuměl ani samotné průvodce).
Ve světě ISO/OSI, kde existuje samostatná prezentační vrstva, se za tímto účelem dokonce navrhl samostatný (a tedy vlastně umělý) jazyk, pojmenovaný ASN.1 (Abstrakt Syntax Notation, verze 1). Lze si jej představit jako programovací jazyk, ovšem bez výkonných příkazů, pouze s deklaracemi. Stalo se tak v době, kdy svět ještě neznal jazyk XML, který by se k tomu velmi dobře hodil. Ale je otázkou, zda by jej ve světě spojů použili, i pokud by již existoval. Filozofie autorů referenčního modelu ISO/OSI totiž byla taková, že všechno museli vymyslet sami. V lepším případě, když už něco šikovného vymyslel někdo jiný, to alespoň potřebovali "posoudit" a vydat jako svůj vlastní standard. Tušili jste, že třeba takový ethernet, standardizovaný společností IEEE jako standard (řady) IEEE 802.3, existuje i jako standard ISO/OSI, konkrétně ISO 8803?
"Pseudovrstvy" v TCP/IP
Jak jsme si již uvedli výše, samostatná relační a prezentační vrstva je pouze v referenčním modelu ISO/OSI, ale v TCP/IP nikoli. Zde se předpokládá, že aplikace, která relační či prezentační služby potřebuje, si je zajistí sama, ve vlastní režii. O důvodech jsme se již zmiňovali (jde hlavně o úsporu režie na samostatné vrstvy). Přesto ale i v TCP/IP existuje jakési alternativní řešení, které připomíná rčení o "zlaté střední cestě" mezi dvěma extrémy (existencí samostatných vrstev a jejich úplnou absencí).
Jde o řešení, vzniklé v souvislosti s protokolem NFS (Network File System), který v rámci TCP/IP slouží ke sdílení souborů. Pochází od firmy Sun Microsystems a bylo to vlastně úplně první řešení, které vzniklo u komerční firmy (tedy jako její vlastní, "proprietární"), ale pak bylo otevřeno a mohlo se stát otevřeným internetovým standardem. Hlavně ale i tato aplikace potřebovala zajistit určité relační a prezentační funkce a tak si je, v duchu koncepce TCP/IP, musela zajistit sama. Ale když už tak učinila, bylo to způsobem, který je využitelný i jinými aplikacemi, aby ty již nemusely znovu "vynalézat kolo" a vyvíjet znovu vlastní prezentační a relační funkce.
Autoři NFS totiž navrhli vše tak, že samotný protokol NFS je "čistě aplikační" a má " k ruce" dva další samostatné protokoly, které pro něj zajišťují prezentační a relační funkce. Konkrétně jde o protokoly XDR (eXternal Data Representation) a RPC (Remote Procedure Call). Tyto protokoly jsou koncipovány tak, aby mohly být řešeny jako knihovní moduly, které si ostatní aplikace přilinkují, pokud je chtějí využívat ale pokud je využívat nechtějí, nenesou režii spojenou s jejich existencí (v podobě samostatné vrstvy).
Celý efekt naznačuje další obrázek: vůči těm protokolům, které XDR a RPC využívají, se tyto chovají obdobně jako samostatné vrstvy. Ovšem ostatní aplikace jimi neprochází, a proto ani nenesou režii, která by s tím byla spojena.
Aplikace: v aplikační vrstvě?
Původní představa autorů referenčního modelu ISO/OSI možná byla taková, že aplikační vrstva bude sloužit k tomu, aby v ní byly provozovány jednotlivé aplikace. Na první pohled to vypadá velmi logicky, ale přináší to jeden zásadní problém: pokud by tomu tak bylo, pak by i všechny aplikace musely být standardizovány a tudíž podřízeny stejným pravidlům, které by definovaly nejen jejich činnost, ale i vše, co s tím souvisí. Ale to by nebylo dobře. Proč?
I aplikace určitě musí respektovat určité konvence a musí se jim důsledně přizpůsobovat. Třeba aplikace, které se účastní práce s elektronickou poštou, musí dodržovat formátování jednotlivých zpráv, musí používat stejně koncipované adresy, stejné mechanismy přenosu zpráv atd. Ale proč by současně měly nabízet jednotné (rozuměj: úplně stejné) uživatelské rozhraní? Proč by měly svým uživatelům vnucovat vždy přesně stejný (standardizovaný) repertoár funkcí? V čem by se pak lišily? Nebo z opačného pohledu: má smysl standardizovat podobu uživatelského rozhraní a předepisovat autorům poštovních klientů, jak mají jejich produkty vypadat? Jaká mají používat okénka, jaké barvy, písma, repertoáry funkcí atd.? Určitě ne.
Původní představa o tom, že v aplikační vrstvě budou "umístěny" celé aplikace, vzala brzy za své. Místo toho došlo k jakémusi "roztržení" aplikací na dvě části:
na část, které musí být standardizována, aby si rozuměla s dalšími aplikacemi, resp. instancemi stejné aplikace (například s poštovními servery atd.),
na část, kterou nemá smysl standardizovat (typicky jde o uživatelské rozhraní aplikace).
Jak také naznačuje poslední obrázek, v aplikační vrstvě nakonec zůstala jen první z obou výše uvedených částí, zatímco ta druhá již byla "vytlačena" nad aplikační vrstvu a tím i z dosahu standardizace a jakéhokoli "sešňěrovávání". Díky tomu si dnes může každý vybrat například takového poštovního klienta, jaký vyhovuje jeho potřebám s maximálním komfortem nebo naopak jednoduchého, s grafickým uživatelským rozhraním nebo v řádkovém režimu atd.