В символьном режиме каждый посланный отправителем символ немедленно доставляется получателю. Это полноценный дуплексный режим, где сторонам нет необходимости договариваться об очередности передачи. Однако с помещением каждого символа в отдельный пакет значительно падает скорость обмена, а накладные расходы резко возрастают (практически по сети передаются одни заголовки пакетов). На быстрых каналах это может быть и не заметно, но ощутимо сказывается на загруженных линиях. Чтобы перейти в символьный режим одна из сторон должна либо попросить другую отключить у себя опцию GA, либо сделать это самостоятельно и послать другой стороне уведомление. Т.е. это может выглядеть либо так: «IAC DO 0x3», либо так «IAC WILL 0x3», где 0x3 код опции «Запрещение команды GA», взятый из таблицы, приведенной выше.
Строчечный режим еще называемый kluge [186] line mode не предусматривался разработчиками явно и фактически возник в результате ошибки. В RFC-858 декларируется, что для ввода символа за один раз с удаленным эхом, опция эхо-отображения должна быть включена, а команда GA запрещена. Если же хотя бы одно из этих условий не выполняется, telnet находится в режиме строка за один раз (т.е. строчечном). Такая ситуация может возникнуть при запросе пароля, если сервер посылает клиенту «IAC WILL ECHO», а тот переходит в режим kluge line mode и передает введенный пароль целиком в одном пакете.
Значительно более совершенен недавно разработанный режим linemode, который устраняет недостатки всех остальных режимов, но сохраняет их достоинства. Подробно он описан в RFC-1184. Существенным достижением (относящимся к безопасности) является возможность передавать пароль на сервер в зашифрованном виде.
–
Символьный режим, несмотря на все свои достоинства, все же очень неудобен в глобальных сетях, поскольку каждый символ помещается в отдельный пакет [187]. Если суммарный размер IP и TCP заголовков принять равным 40 байтам, тогда несложным подсчетом нетрудно убедиться, что на долю полезных данных приходится всего 2% (1/41 * 100 = 2.4).
Падение производительности особенно заметно на медленных каналах и перегруженных линиях. Попытки же буферизации данных не всегда увенчиваются успехом (если приложение обрабатывает ввод пользователя посимвольно - это ласты).
В RFC-869 предложено простое и элегантное решение, именуемое алгоритмомНагла. Суть его заключается в следующем: отправитель посылает получателю первый TCP пакет с единственным символом, но до получения подтверждения о его доставке (а протокол TCP всегда уведомляет отправителя, что его пакет был успешно получен) все поступающие на отправку символы помещаются в один пакет. Такая методика кэширования совершенно прозрачна для telnet-протокола, поскольку работает на уровень ниже его. Зато в зависимости от степени загруженности сети она автоматически настраивается на максимальную производительность.
Алгоритм Нагла используется в протоколах telnet и rlogin.
Следующий пример, демонстрирует взаимодействие telnet-сервера и telnet-клиента: вход на сервер может происходить так:
· сервер посылает клиенту «IAC DO 0x3» для перевода клиента в символьный режим
· клиент отвечает «IAC WILL 0x3» и переходит в символьный режим
· сервер посылает «IAC DO 0x1» для включения эхо-отображения клиента
· клиент отвечает «IAC WILL 0x1» и включает это-отображение
· сервер посылает строку “login:”
· клиент возвращает имя пользователя
· сервер посылает строку “password:”
· сервер посылает «IAC DONT 0x1» для отключения эхо-отображения клиента
· клиент отвечает «IAC WONT 0x1» и отключает эхо-отображение
· клиент посылает строку пароля, набранную пользователем «вслепую»
На практике, однако, ситуация варьируется от сервера к серверу и часто оказывается намного сложнее.
Перехватить сессию связи между сервером и клиентом можно с помощью специально разработанного для этой цели Proxy-сервера TCPSPY (на прилагаемом к книге диске он находится в файле /SRC/tcpspy.bat, а его исходный текст приведен в Приложении). Запустив его, необходимо указать порт удаленного сервера (23), порт локального сервера (скажем, 123) и адрес удаленного сервера (в приведенном ниже примере использовался telnet.org). Затем запустить telnet-клиент (в этом примере использовался клиент, входящий в Windows 2000) и установить соединение с узлом 127.0.0.1 по выбранному порту (123).
Ниже приведен протокол работы, сохраненный в файле tcpspy.log (на диске, приложенном к книге он расположен в /SRC/telnet.log)
· FF FD 18 FF FD 20 FF FD ¦ 23 FF FD 27 FF FB 18 FF ¤^ ¤ ¤# ¤' v^
· FB 1F FF FC 20 FF FC 23 ¦ FF FC 27 FF FD 1F FF FA vЎ № №# №' ¤Ў ·
· 18 01 FF F0 FF FB 1F FF ¦ FA 1F 00 50 00 19 FF F0 ^O Ё vЎ ·Ў P v Ё
· FF FA 18 00 41 4E 53 49 ¦ FF F0 FF FB 03 FF FD 01 ·^ ANSI Ё v¦ ¤O
· FF FB 05 FF FD 21 FF FD ¦ 03 FF FB 01 FF FE 05 FF v¦ ¤! ¤¦ vO ¦¦
· FC 21 FF FE 01 FF FB 01 ¦ 0D 0D 0A 52 65 64 20 48 №! ¦O vOdd0Red H
· 61 74 20 4C 69 6E 75 78 ¦ 20 72 65 6C 65 61 73 65 at Linux release
· 20 36 2E 31 20 28 43 61 ¦ 72 74 6D 61 6E 29 0D 0D 6.1 (Cartman)dd
· 0A 4B 65 72 6E 65 6C 20 ¦ 32 2E 32 2E 31 36 2D 33 0Kernel 2.2.16-3
· 20 6F 6E 20 61 6E 20 69 ¦ 35 38 36 0D 0D 0A 6C 6F on an i586dd0lo
· 67 69 6E 3A 20 FF FC 01 ¦ FF FD 01 6B 70 6E 63 0D gin: №O ¤Okpncd
· 0D 0A 6B 70 6E 63 0D 0D ¦ 0A 50 61 73 73 77 6F 72 d0kpncdd0Passwor
· 64 3A 20 70 61 73 73 77 ¦ 6F 72 64 0D 0D 0A 0D 0D d: passworddd0dd
· 0A 4C 6F 67 69 6E 20 69 ¦ 6E 63 6F 72 72 65 63 74 0Login incorrect
· 0D 0D 0A 0D 0D 0A 6C 6F ¦ 67 69 6E 3A 20 dd0dd0login:
Расшифровка перехваченной сессии выглядит следующим образом (разумеется, возможны вариации в зависимости от используемого читателем клиента и сервера).
· SERVER:FF FD 18 IAC DO 0x18; можно определить тип терминала?
· SERVER:FF FD 20 IAC DO 0x20; можно определить скорость терминала?
· SERVER:FF FD 23 IAC DO 0x23; поддерживается ли некая опция?
· SERVER:FF FD 27 IAC DO 0x27; поддерживается ли некая опция?
· CLIENT:FF FB 18 IAC WILL 0x18; да, можно определить тип терминала
· CLIENT:FF FB 1F IAC WILL 0x1F; клиент изменяет размер своего окна
· CLIENT:FF FC 20 IAC WONT 0x20; нельзя установить скорость терм
· CLIENT:FF FC 23 IAC WONT 0x23; неизвестная опция 0х23
· CLIENT:FF FC 27 IAC WINT 0x27; неизвестная опция 0х27
· SERVER:FF FD 1F IAC DO 0x1F; изменить размер окна
· SERVER:FF FA 18 01 IAC SB 0x18 1; указание клиенту возвратить тип термин.
· SERVER:FF F0 IAC SE; конец подопции
· CLIENT:FF FB 1F IAC WILL 0x1F; изменение размеров окна ОК
· CLIENT:FF FA1F IAC SB 0x18; сообщение размеров окна
· CLIENT:00 50 00 19; размер окна 80x25 символов
· CLINET:FF F0 IAC SE; конец подопции
· CLINET:FF FA 18 00 IAC SB 0x18 0;начало подопции сообщения типа терминала
· CLINET:41 4E 53 49 “ANSI”; тип терминала
· CLINET:FF F0 IAC SE; конец подопции
· SERVER:FF FB 03 IAC WILL 0x3; перевод в символьный режим
· SERVER:FF FD 01 IAC DO 0x1; включение эха
· SERVER:FF FB 05 IAC WILL 0x5; получение статуса
· SERVER:FF FD 21 IAC DO 0x21; удаленный контроль потоком данных
· CLIENT:FF FE 01 IAC DONT 0x1; клиент просит сервер включить эхо
· CLIENT:FF FB 01 IAC WILL 0x1; клиент включает эхо у себя
· CLINET:FF FE 05 IAC DONT 0x5; нельзя возвратить статус
· CLINET:FF FC 21 IAC WONT 0x21; удаленный контроль потоком данных ОК
· SERVER:FF FE 01 IAC DONT 0x1; сервер против эха клиента
· SERVER:FF FB 01 IAC WILL 0x1; серер включает это у себя
· SERVER:0D 0D 0A 52…«Red Hat Linux…»
Обращает на себя внимание тот факт, что данный сервер запрещает клиенту использовать локальное эхо. Вместо этого он самостоятельно возвращает все полученные символы, разумеется, за исключением символов пароля.