Vyšlo v týdeníku Computerworld č. 7/93 v roce 1993
Vytištěno z adresy: http://www.earchiv.cz/a93/a307c110.php3

Protokol TCP - II.

V minulém dílu jsme se začali zabývat protokolem TCP. Řekli jsme si, že své bezprostředně vyšší vrstvě poskytuje přenosové služby spolehlivého a spojovaného charakteru, i když k jejich zajištění může sám využívat jen nespolehlivé (a nespojované) přenosové služby na úrovni síťové vrstvy, poskytované protokolem IP. Naznačili jsme si také, že potřebné spolehlivosti dosahuje protokol TCP pomocí potvrzování a opakovaného vysílání chybně přenesených dat. Dnes se zastavíme podrobněji právě u způsobu opakování přenosů.

Připomeňme si však ještě jednou to, co jsme si o konkrétním mechanismu potvrzování řekli již minule: protokol TCP používá tzv. kladné potvrzování (positive acknowledgement), což znamená, že potvrzuje pouze správně přijatá data, zatímco na chybně přijatá data nereaguje nijak. Odesilatel proto pozná, že určitá data nebyla přenesena správně, až po vypršení určitého časového limitu. Současně s tím je ale dobré si uvědomit, že také kladná potvrzení jsou sama přenášena pomocí stejně nespolehlivých přenosových služeb síťové vrstvy, jako samotná data. Může se proto stát, že určitá data jsou přenesena bezchybně, ale "ztratí" se jejich kladné potvrzení. Odesilatel však nemá možnost oba tyto případy rozlišit. Vždy musí čekat až do vypršení časového limitu, zda nedostane kladné potvrzení, a pokud ne, musí data vyslat znovu.

Otázkou ovšem je, jak volit příslušný časový limit (timeout)? Bude-li příliš krátký, může docházet k situacím, kdy data budou přenesena bezchybně, ale jejich kladné potvrzení dojde odesilateli příliš pozdě - až po vypršení časového limitu, což odesilatele přinutí znovu vyslat úspěšně přenesená data. V opačném případě - bude-li časový limit příliš dlouhý - bude odesilatel zase zbytečně dlouho čekat, než si bude moci domyslet, že se data nepřenesla správně. V obou případech je výsledkem neefektivní využití přenosových kapacit.

Problém vhodné volby časového limitu je navíc komplikován skutečností, že protokol TCP může být používán v různých sítích, ve kterých se doby přenosu mohou lišit i v několika řádech. Například v rychlé lokální síti by příslušný časový limit měl být výrazně kratší než v rozlehlé síti, která používá relativně velmi pomalé pevné telefonní okruhy. Situace je navíc ještě komplikovanější u vzájemně propojených sítí (internets, s malým "i"), kde jednotlivé části přenosové trasy (route) mají obecně různé přenosové kapacity, a kde se navíc trasa mezi dvěma koncovými účastníky může v průběhu přenosu dynamicky měnit (např. v důsledku zahlcení či výpadku).

Adaptivní chování

Způsob, jakým se protokol TCP vyrovnává s problémem správné volby časového limitu pro opakované vysílání (retransmission), lze v prvním přiblížení charakterizovat jako adaptivní. TCP totiž průběžně monitoruje skutečné chování přenosové sítě, a podle něj se snaží předvídat její chování i pro nejbližší časový úsek. Tomu pak přizpůsobuje i své chování.

TCP neustále měří dobu obrátky (RTT, round trip time) jako dobu od odeslání dat do přijetí kladného potvrzení o jejich úspěšném doručení. Časový limit pak uzpůsobuje průměrné době obrátky, kterou vypočítává jako vážený průměr (weighted average) jednotlivých naměřených dob obrátky.

Nejednoznačnost potvrzování

V minulém dílu jsme si také říkali, že protokol TCP nepotvrzuje celé segmenty (jak se nazývají jím přenášené bloky dat), ale jednotlivé byty (přesněji: oktety) v rámci přenášeného proudu (stream). To má jeden závažný důsledek pro výpočet doby odezvy. Představme si situaci, kdy odesilatel nedostane do časového limitu kladné potvrzení o přijetí určité části dat, a tak je vyšle znovu ve stejně velkém segmentu. Dostane-li pak kladné potvrzení, není z něj schopen rozlišit, ke kterému segmentu se toto potvrzení vztahuje - zda jde o potvrzení poprvé vyslaných dat (které se někde zdrželo), nebo zda jde již o potvrzení podruhé vyslaných dat (zatímco poprvé vyslaná data se přenesla s chybou, nebo se jejich kladné potvrzení ztratilo). Potvrzování, používané protokolem TCP, je proto v obecném případě nejednoznačné (ambiquous).

Z pohledu zabezpečení spolehlivého přenosu tato nejednoznačnost nijak nevadí, ale problém vzniká při výpočtu doby obrátky: má tato být vztažena k okamžiku prvního vyslání, nebo naopak k okamžiku posledního opakovaného vyslání určitých dat? Dá se ukázat, že obě varianty jsou špatné - v případě té první může vážený průměr doby obrátky růst nade všechny meze, zatímco ve druhém případě sice konverguje k určité konečné hodnotě, ale tato je menší, než by správně měla být (praktické implementace této varianty ukazují, že je tato hodnota přibližně poloviční oproti správné, a protokol TCP pak vysílá všechna data právě dvakrát).

Karnův algoritmus

S jednoduchým a elegantním řešením poprvé přišel radioamatér Phil Karn, když se snažil implementovat TCP/IP protokoly i pro prostředí radioamatérských paketových sítí (což se mu ostatně povedlo - výsledkem je známý programový balík KA9Q, nazvaný podle volací značky svého autora).

Myšlenka, se kterou Karn přišel, je velmi jednoduchá - v případě nejednoznačného potvrzení (tj. v případě opakovaného vyslání již jednou vyslaných dat) vůbec neměřit dobu obrátky, a tudíž i neuzpůsobovat podle ní časový limit. Jinými slovy: pro stanovení časového limitu využívat pouze ty případy, kdy data byla vyslána jen jednou, a je tudíž jasné, jak dobu obrátky měřit.

I toto řešení však ve své čisté podobě není příliš použitelné. Představme si totiž situaci, kdy například vlivem změny trasy či výpadku části přenosových kapacit náhle vzroste zpoždění při přenosu. Potvrzení nestihne přijít včas, a tak jsou data vyslána znovu - v důsledku toho se pak ale neměří doba obrátky, a nijak se nemění ani časový limit. Bude-li nárůst zpoždění trvalý, výše uvedený algoritmus na něj vůbec nezareaguje!

Konkrétní algoritmus, který Phil Karn navrhl, však řeší i tuto situaci (technikou, označovanou jako timer backoff): v okamžiku, kdy začne docházet k opakovanému vysílání dat, přestává tento algoritmus měřit dobu obrátky, a nemění tudíž ani vážený průměr těchto dob. Začne ale zvětšovat časový limit (např. na dvojnásobek po každém opakovaném vyslání dat). Teprve v okamžiku, kdy díky většímu časovému limitu dostane kladné potvrzení včas (tj. jako jednoznačné potvrzení), změří skutečnou dobu obrátky, znovu začne vypočítávat vážený průměr dob obrátky, a tomuto průměru pak uzpůsobí časový limit.