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

TELNET - III.

V minulém dílu jsme se zabývali virtuálním terminálem NVT protokolu TELNET. Dospěli jsme k představě, že jde jen o jisté "povinné minimum", jehož možnosti a schopnosti si mohou obě strany na základě vzájemné dohody rozšířit. Dnes se již dostaneme ke konkrétním mechanismům, které se přitom používají.

Na úvod je vhodné si znovu zdůraznit, že veškerá komunikace mezi klientskou a serverovou složkou protokolu TELNET má zásadně charakter přenosu znaků. Mají-li pak být v takovémto prostředí implementovány jakékoli řídící mechanismy a postupy, musí mít příslušné řídící příkazy i veškeré reakce na ně opět povahu znaků. Musí však být zajištěna také potřebná transparence dat - musí být možné jednoznačně rozlišit, které znaky představují "užitečná data" a které naopak představují řídící příkazy.

Tvůrci protokolu TELNET měli v zásadě dvě možnosti, jak tohoto cíle dosáhnout. Jednou bylo přisoudit význam řídících příkazů některým ASCII znakům. Tím by se ale připravili o možnost používat tytéž znaky v jejich původním významu, který mají v kódu ASCII, a navíc by si tím dosti omezili možný repertoár vlastních řídících příkazů (protože takto využitelných znaků ASCII je jen velmi omezený počet). Proto se autoři protokolu TELNET raději rozhodli pro druhou možnost, kterou představuje samostatné kódování řídících příkazů, nezávislé na kódu ASCII.

Zajištění transparence

Jak jsme si již uvedli minule, protokol TELNET přenáší jednotlivé znaky v osmibitových bytech. Znaky kódu ASCII jsou však jen sedmibitové, a pro potřeby přenosu se doplňují nejvyšším bitem, nastaveným na nulu. Pro kódování svých řídících příkazů se pak tvůrcům protokolu TELNET nabízelo všech 128 možných 8-bitových hodnot, s nejvyšším bitem nastaveným na jedničku - a tuto možnost také skutečně využili. Zde je ovšem důležité si uvědomit, že virtuální terminál NVT sice předpokládá pouze přenos sedmibitových ASCII znaků, ale že jednou z možností rozšíření je přenos osmibitových znaků. Jakmile se ale toto rozšíření použije, okamžitě se tím ztrácí automatické rozlišení mezi "užitečnými" znaky a řídícími příkazy podle hodnoty nejvyššího (přesněji: nejvýznamnějšího) bitu.

Samotný způsob kódování řídících příkazů tedy ještě nemohl zajistit potřebnou transparenci dat, a proto tvůrcům protokolu TELNET nezbylo než použít řešení, obvyklé např. u znakově orientovaných linkových protokolů či u řídících jazyků pro ovládání tiskáren a obdobných znakově orientovaných zařízení: před samotný řídící znak zařadit speciální znak, který změní interpretaci jednoho, resp. několika následujících znaků. V případě tiskáren jde o znak ESCAPE (s ASCII kódem 27, resp. 1B hexadecimálně), který uvozuje tzv. ESCAPE sekvence, zatímco u linkových protokolů jde o znak DLE (Data Link ESCAPE, s ASCII kódem 16, resp. 10 hexadecimálně), který prefixuje řídící znaky začátku a konce rámce apod. V případě protokolu TELNET byl zvolen znak s číselných kódem 255 (resp. FF hexadecimálně), označovaný jako IAC (Interpret As Command, dolova: interpretuj jako řídící příkaz), který povinně uvozuje všechny řídící příkazy. Pokud by se číselný kód tohoto znaku (tj. kód 255) vyskytl v "užitečných" datech, musí být zdvojen, čím se zamezí jeho interpretaci jako uvozujícího znaku řídícího příkazu.

Příkazy protokolu TELNET

Většina řídících příkazů protokolu TELNET je reprezentována jedním řídícím znakem, ke kterému se přidává povinný prefix - znak IAC - takže nekratší příkaz je tvořen dvěma osmibitovými byty. Existují ovšem i příkazy, pro jejichž vyjádření jediný řídící znak nestačí, a je nutné použít ještě jeden dodatečný znak. I v tomto případě se ale používá jediný uvozující znak IAC, takže výsledný příkaz je tvořen třemi byty. Pro ještě "delší" příkazy se pak již používá poněkud odlišný mechanismus, se kterým se seznámíme posléze.

Podle svého významu spadají řídící příkazy protokolu TELNET do tří skupin, mezi:

  • příkazy pro editaci (jsou jen dva: pro vymazání aktuální řádky a pro vymazání předchozího znaku),
  • příkazy pro řízení komunikace mezi oběma stranami (například pro přerušení aplikačního procesu na straně serveru, pro zastavení jeho výstupu, pro vzájemnou synchronizaci apod.),
  • příkazy, umožňující oběma stranám dohodnout se na použití konkrétních rozšíření.
Na poslední skupinu se nyní zaměříme podrobněji.

Licitace o rozšíření

Jak jsme si již naznačili minule, použití nejrůznějších rozšíření oproti virtuálnímu terminálu NVT je nepovinné. Každá ze stran má právo navrhnout použití takového rozšíření, jaké uzná za vhodné, ale druhá strana má plné právo jej odmítnout. Výrazný prvek demokratičnosti je pak i v tom, že právo navrhovat použití rozšíření má nejen složka v roli klienta, ale i složka v roli serveru - obě strany mají v tomto ohledu rovnoprávné postavení.

Zajímavý je i konkrétní způsob vzájemné "licitace". Ta strana, která chce iniciovat použití určitého rozšíření, má dvě možnosti: navrhnout, že sama přijme nějaké opatření (tj. sama začne používat příslušné rozšíření), a ptát se druhé strany, zda s tím souhlasí, nebo naopak navrhnout druhé straně, aby ona přijala určité opatření. Ukažme si na příkladu, v čem může spočívat rozdíl, a proč je vůbec nutné jej uvažovat: virtuální terminál NVT předpokládá, že každá strana bude používat tzv. lokální echo (local echo) - tedy že veškeré znaky, zadané z klávesnice, si bude sama ihned zobrazovat na svém displeji (resp. tisknout na tiskárně, kterou předpokládá NVT), a současně s tím je odesílat druhé straně. Díky tomu uživatel okamžitě vidí, co vlastně z klávesnice zadal, a co se druhé straně odeslalo. Alternativa je taková, že zadaný znak je pouze odeslán druhé straně, a teprve ta jej zase pošle zpět k zobrazení na displeji uživatelova terminálu. Používání této techniky, označované jako tzv. vzdálené echo (remote echo), je jedním z možných rozšíření virtuálního terminálu NVT. Je ovšem zásadní rozdíl mezi tím, kdy jedna strana navrhne druhé, že ona bude provádět vzdálené echo (tj. že bude posílat zpět každý znak, který od druhé strany dostane), a kdy vzdálené echo požaduje na druhé straně.

Některá rozšíření virtuálního terminálu NVT, jako právě naznačené používání tzv. vzdáleného echa, mají asymetrický charakter, a mohou být používány oběma stranami současně, žádnou z nich, nebo jen jednou ze zúčastněných stran. Naproti tomu jiná rozšíření mají symetrický charakter, a musí je používat buď obě strany současně, nebo žádná.

Protokol TELNET nabízí celkem čtyři příkazy, pomocí kterých mohou obě strany "licitovat" o použití rozšíření. Jsou to po příkazy:

  • WILL (doslova: budu), vysílající strana tímto příkazem signalizuje, že chce sama začít používat určité rozšíření, a dotazuje se druhé strany na její souhlas
  • DO (doslova: dělej), vysílající strana tímto příkazem vyzývá druhou stranu, aby ona začala používat určité opatření
  • WON'T (od: Will Not, doslova: nebudu), tímto příkazem vysílající strana odmítá výzvu druhé strany (vyjádřenou příkazem DO), případně signalizuje, že sama již nebude dále pokračovat v používání určitého rozšíření (pokud jej dosud používala)
  • DON'T (od: Do Not, doslova: nedělej), tímto příkazem vysílající strana odmítá nabídku druhé strany (vyjádřenou příkazem WILL), případně signalizuje, že od druhé strany již neočekává, že bude nadále používat určité rozšíření.

Příkazy WON'T a DON'T jsou tedy zápornými odpověďmi na výzvu, vyjádřenou po řadě příkazy DO a WILL. Jaké jsou ale kladné odpovědi? Kladnou odpovědí na příkaz DO (výzvu "dělej") je příkaz WILL (tj. "budu"), a naopak kladnou odpovědí na příkaz WILL (nabídku "budu") je příkaz DO (tj. "dělej").

Identifikace rozšíření

Příkazy WILL, DO, WON'T a DON'T samy o sobě ještě neurčují jednu velmi podstatnou věc - o jaké konkrétní rozšíření se jedná. Toto je určeno až dalším rozlišujícím parametrem (ve skutečnosti číselným kódem v rozsahu jednoho osmibitového bytu), který následuje bezprostředně za vlastními příkazy. Takže například nabídka jedné strany, že bude druhé straně zajišťovat vzdálené echo, se symbolicky zapisuje jako

IAC WILL ECHO
a ve skutečnosti se vysílá jako trojice bytů s hodnotami po řadě 255, 251 a 1 (kde 255 je kód uvozujícího znaku IAC, 251 je kód příkazu WILL, a 1 je kód rozšíření o vzdálené echo). Druhá strana v případě souhlasu odpoví sekvencí
IAC DO ECHO
(číselně: 255 253 1), a v případě nesouhlasu sekvencí
IAC DON'T ECHO
(číselně: 255 254 1).

Obdobně požadavek jedné strany, aby pro ni druhá strana zajišťovala vzdálené echo, by měl tvar

IAC DO ECHO
(číselně: 255 253 1). Druhá strana akceptuje tuto výzvu sekvencí
IAC WILL ECHO
(číselně: 255 251 1), resp. odmítá ji pomocí
IAC WON'T ECHO
(číselně: 255 252 1). Aby se zabránilo možnému zacyklení, kdyby jedna strana považovala odpověď druhé strany za novou žádost, je zavedeno následující pravidlo: na žádost o použití takového rozšíření, které již je používáno, se neodpovídá nijak.

Počet a význam jednotlivých rozšíření není předem stanoven. Nová rozšíření mohou vznikat a skutečně vznikají na základě skutečných potřeb a vývoje výpočetní techniky. Pro jejich koordinaci však musí existovat jediná centrální autorita, která jim přiděluje jejich číselné kódy. Tou je pan John Postel z University of Southern California, autor mnoha standardů Internetu, vydávaných ve formě tzv. RFC dokumentů.

Podrobnější licitace

Z některých zajímavých rozšíření (které uvádí tabulka 69.1) stojí za zmínku např. možnost dohodnout se na použití konkrétního typu terminálu (s větším repertoárem schopností a možností, než jaké nabízí "základní NVT"). V současné době, kdy je velká část terminálových relací zajišťována prostřednictvím terminálové emulace (viz 65. díl), a příslušné emulátory jsou často schopny emulovat více různých terminálů, je dokonce žádoucí, aby se obě strany mohly dohodnout na použití nejvhodnějšího terminálu.

Pro tyto účely však již není výše naznačený mechanismus dostatečný. Umožňuje pouze to, aby se obě strany dohodly na tom, že se vůbec chtějí (a umějí) domlouvat na typu terminálu. Poté musí následovat druhá fáze "licitace" (v angličtině označovaná jako subnegotiation), v rámci které se již mohou podrobněji domlouvat na konkrétních parametrech. V případě volby typu terminálu by v rámci této druhé fáze složka v roli klienta předkládala složce v roli serveru jednotlivé typy terminálů, které je schopna emulovat, a server by si z nich vybíral tu, kterou považuje ze svého pohledu za nejvýhodnější.

Obdobná úvaha platí i pro jiná rozšíření: například pro stanovení velikosti displeje, kde se konkrétní počet řádek na stránce a počet znaků na řádce sděluje opět v druhé fázi (subnegotiation) "licitace".

Konkrétní forma této druhé fáze není předepsána, neboť je určena až potřebami příslušného rozšíření. Závazný je pouze způsob zajištění transparence: posloupnost znaků, předávaných v rámci druhé fáze "licitace", musí být uvozena řídícím znakem SB (Start of Subnegotiation), a zakončena znakem SE (End of Subnegotiation). Oba tyto znaky přitom musí být samy prefixovány znakem IAC.

Symb. označení číselný kód význam
TRANSMIT-BINARY 0 přenos 8-bitových znaků (resp. binárních dat)
ECHO 1 tzv. vzdálené echo (viz text)
STATUS 5 toto rozšíření umožňuje, aby jedna strana vysílala druhé straně informace o svému stavu (tzv. status), resp. aby si jedna strana vyžádala od druhé informace o jejím stavu
TERMINAL-TYPE24díky tomuto rozšíření se zúčastněné strany mohou dohodnout na typu používaného terminálu
NAWS31 (Negotiate About Window Size), toto rozšíření umožňuje zúčastněným stranám dohodnout se na velikosti displeje terminálu
TERMINAL-SPEED 32 obdobně, pro přenosovou rychlost terminálu
TOGGLE-FLOW-CONTROL 33 toto rozšíření umožňuje zúčastněným stranám dynamicky měnit způsob řízení toku
EXTENDED-OPTIONS-LIST 255 toto rozšíření je ve skutečnosti mechanismem, pomocí kterého lze zvýšit počet možných rozšíření nad 255
Tabulka 69.1: Příklady rozšíření virtuálního terminálu NVT protokolu TELNET