Оглавление темы 8 Польская версия документа

8.4.1 Протокол TFTP

Содержание


Авторы протокола

Творцом протокола является Noel Chiappa, позднее был переработан им, K.R.Sollins (автор [1] и [2]), Bob Baldwin и Dave Clark с замечаниями Steve Szymanski. Последняя версия протокола возникла в 1992 г. в результате дискуссий с большим колличеством людей (см. [2]). В ней были устранены некоторые неточности, бывшие в [1]. При создании протокола идея подтверждений и схема повторной передачи пакетов была взята из протокола TCP, механизм обработки ошибок был взят из PARC's EFTP abort message.


Введение

Абвириетура TFTP расшифровывается следующим образом: "Trivial File Transfer Protocol". Первоначальное его назначение - протокол для передачи файлов, основанный на протоколе UDP. TFTP является прототипом для позднее созданного значительно более мощного протокола FTP[4], основанного на протоколе TCP.TFTP способен передавать тексты, почту или файлы. Такие вещи, как просмотр содержимого дирректории для него не доступна, как, впрочем, и идентификация пользователя.. Это, однако, вполне объяснимо. Дело в том, что при разработке протокола основной нажим был на простоту кодирования. Как большая часть интернетовых протоколов, TFTP передает данные размером в 8 бит.

В 1984 г. было предложено использовать протокол для первичной загрузки бездисковых терминалов. Этот проект вместе с описанием способа загрузки находится в [3]. Это предложение вполне оправданно. Дело в том, что протокол UDP запрограммирован в ROM почти каждой машины (Уж больно он прост!). Поскольку код TFTP занимает не так уж и много места, код обслуживающей его программы легко можно поместить в ROM. С одной из самых больших неприятностей TFTP - с его медленностью передачи данных очень легко бороться - достаточно загрузить модуль, обслуживающий иные, более быстрые протоколы (он занимает не так уж и много места), и с его использованием завершить загрузку.


Как это работает

Протокол TFTP использует 3 типа передач:

Любая передача начинается с запроса на чтение или на запись, который одновременно служит для запроса на соединение. Если сервер положительно реагирует на запрос, то соединение открывается и файл (или почта) пересылается в стандартных блоках по 512 байт. Каждый пакет данных содержит один блок данных и его получение должно быть подтверждено перед высылкой следующего пакета. Пакет данных размером меньше, чем 512 байт (0..511) означает конец передачи.Если пакет потеряется в сети, то пакет, подтверждающий прием не будет выслан. В этом случае высылающий компьютер, не получив подтверждения в течение установленного времени, должен повторно выслать пакет с данными. Передающий компьютер должен держать в памяти только один пакет данных до тех пор, пока не получит подтверждения его получения. Следует отметить, что обе машины - и передающая, и принимающая, - занимаются как приемом, так и передачей пакетов. Одна пересылает данные и получает подтверждающие пакеты, а другая посылает подтверждения и получает данные.

Большая часть ощибок вызывает разрыв соединения. Сообщение об ошибке высылается при помощи ERROR-пакета. Прием этого пакета не подтверждается и не передается повторно (что вполне понятно, т.к. пользователь или сервер могут закончить работу сразу после высылки сообщения об ошибке), таким образом получатель этого пакета может его и не получить.В этом случае конец соединения можно определить по timeout. Ошибки возникают в трех случаях:

TFTP имеет только одну ошибку, которая не вызывает прерывания соединения: если исходный порт (source port) принятого пакета неверен.В этом случае сообщение об ошибке передается на хост источника.


Связь с иными протоколами

Поскольку TFTP был разработан как протокол, использующий UDP, а UDP использует для коммуникации протокол IP, пакеты будут иметь IP-заголовок, UDP-заголовок и TFTP-заголовок. Кроме того, пакет может иметь и другие заголовки (LNI, ARPA и т.д.), которые позволят ему пройти через локальную сеть. Таким образом мы имеем следующий порядок заголовков:

  Локальный (если есть)         IP          UDP       TFTP   

TFTP не использует данных из IP заголовка, однако использует исходный адрес и адрес назначения (source&destination ports) из заголовка UDP, а также поле длины для определения длины пакета TFTP. Идентификаторы передачи (transfer identifiers или TID), используемые TFTP, помещаются в слой UDP, где используются как номера портов. Поэтому их значение должно лежать в пределе 0..65,535. Инициализация TID подробно рассмотрена в следующем пункте.


Initial Connection Protocol

Передача начинается с запроса на (WRQ) запись или на чтение (RRQ) и приема подтверждающего пакета (ACK) в случае запроса на запись или первого пакета с данными в случае запроса на чтение.

В общем случае подтверждающий пакет содержит номер последнего полученного пакета данных. Эти номера расположены по возрастанию и начинаются от 1. В случае подтверждения запроса на запись высылается подтверждающий пакет с номером блока 0. Если пересылается ERROR-пакет, то это означает, что соединение невозможно.

Для создания соединения, и передающий и принимающий компьютеры должны выбрать для себя TID. Поскольку номера выбираются случайным образом, вероятность выбора одного и того же номера обоими компьютерами мала. Каждый пакет ассоциируется с двумя TID'ами: source TID и destination TID, которые используются UDP как source и destination порты. Запрашивающий хост устанавливает source порт способом, описанным выше и посылает инициализирующий запрос на известный TID 69 десятичный). Реагируя на запрос, отвечающий хост выбырает тем же способом свой TID и использует полученный TID как destination. Полученные таким образом TID'ы используются в течении всей сессии.

Например, при запросе соединения на запись файла, выполняются следующие операции:

Может произойти ситуация, что source TID не соответствует первоначально выбранному (это может произойти в результате сбоя в сети и т.п.). В этом случае полученный пакет считается случайно попавшим откуда-то пакетом. Сообщение об ошибке должно быть выслано по source порту пришедшего ошибочного пакета. Следующий пример описывает, что должно произойти, если вышеописанная операция имела место:


Пакеты TFTP

TFTP имеет 5 видов пакетов:

Код Операция
1 Read Request (RRQ)
2 Write Request (WRQ)
3 Данные (DATA)
4 Подтверждение (ACK) - Acknowlegment
5 Ошибка (ERROR)

RRQ, WRQ

2 байта               String           1 байт               Sring             1 байт

   Код          Имя файла      

     0     

          Режим                0     

Хост, получающий NetASCII данные, обязан перевести их в свой собственные формат. Хорошим примером может служить DOS и UNIX с их различными видами окончания строк. Именно поэтому при переписывании бинарных файлов с установкой ASC в FTP мы получаем ерунду!

Данные в формате "Octet" должны передаваться в неизменном виде. Иными словами, если посланый ранее файл передать обратно, то полученная копия не должна отличаться от оригинала. Следует учитывать, что если передающая машина использует длину слова, отличную от 8 байт, то перед передачей данные должны быть перекодированы в формат с 8-битным словом. Такой формат данных был использован как наиболее общий для различных типов компьютеров. Например, DEC-20 имеет 36-битное слово, таким образом одно слово можно представить в виде четырех 8-битных слов и одной 4-битной "половинки".

При передаче почты на месте файла находится адрес пользователя. Может быть в форме "username" или "username@hostname".

Возможны, конечно, и другие режимы передачи, но относиться к этому нужно с большой осторожностью, т.к. они не входят в стандарт.

DATA

2 байта            2 байта                              n байт                        

     3          Номер блока                         Данные                    

Следует отметить, что всего блоков может быть 65535, иными словами, общая длина передаваемого (или принимаемого) файла не может превысить 33,553,920 байт.

ACK - подтверждения.

2 байта            2 байта         

     4           Номер блока     

Прием каждого пакета данных должен быть подтвержден. Это единственный механизм защиты данных, использованый в TFTP. Компьютер, передающий данные не будет передавать следующий блок до тех пор, пока не наступит подтверждение приема предыдущего или же пока те пройдет критическое время, установленное на ожидание подтверждения (timeout). В этом случае произойдет повторная высылка данных.

Как я уже отмечал это выше, запрос на запись WRQ подтверждается ACK - пакетом с номером блока данных 0.

Пример соединений

:

                     Чтение                                               Запись                             

ERROR - сообщения об ошибках

 2 байта       2 байта                         String                 1 байт    

     5         Error Code              Error Message                0     

ERROR-пакет может быть подтверждающим для любого типа пакетов. Сообщение об ошибке (Error Message) должно быть в формате NetASCII. Получение ERROR-пакета не подверждается и этот пакет повторно не высылается (процессы могут уже завершить свою работу). Ниже поданы кода ошибок:

Код Значение
0 Не определено, см. Error Message (если есть!)
1 Файл не найден
2 Нарушение прав доступа
3 Диск полон
4 Неверная TFTP операция
5 Неизвестный ID передатчика
6 Файл уже существует
7 Нет такого пользователя

Нормальное завершение соединения.

Конец передачи обозначает пакет DATA содержащий 0..511 байтов данных (т.е. длина UDP-пакета <516). Прием этого пакета подтверждается ACK-пакетом, как и все остальные. Хост, получивший последний пакет с данными посылает последний подтверждающий пакет. Однако, хост, пославший последний ACK должен ждать, чтобы передать завершающий ACK еще раз, если предыдущий потеряется в сети. Эту ситуацию легко определить, т.к. другой хост вышлет данные еще раз по истечении времени. Он должен высылать данные до тех пор, пока не получит ACK или не истечет время ожидания для передающего хоста. Если пришел ACK, то соединение было успешным. Если вышло время, то соединение могло быть успешным, а могло и нет. В любом случае, соединение закрывается.


Преждевременное завершение

Если не было получено разрешения на доступ или появилась ошибка во время передачи, то высылается ERROR-пакет. Он никогда не высылается повторно и никогда не подтверждается. Таким образом, этот пакет может быть не получен. В этом случае нужно использовать механизм Timeout.


Библиография

  1. RFC0783. The TFTP Protocol (Revision 2). K.R. Sollins, June, 1981.
  2. RFC1350. The TFTP Protocol (Revision 2). K.R. Sollins, July, 1992.
  3. RFC0906. Bootstrap Loading using TFTP. Ross Finlayson, June 1984.
  4. RFC0959. File Transfer Protocol (FTP). J. Postel, J. Reynolds, October 1985
  5. Programowanie zastosowan sieciowych w systemie UNIX. R. Stevens

Вопросы и ответы

  1. Почему нет никакого исходного кода?

    Дело в том, что реализация этого протокола не входит в ядро Linux'а. Кроме того, полный исходный код для клиента и сервера находится в [5], стр. 520. Поскольку помещенные там программы имеют исчерпывающие комментарии, да еще на польском языке, не имело смысла их приводить здесь. Мало того, по моему мнению, реализация данного протокола не выглядит слишком интересной или сложной. Именно поэтому при написании этого документа я в основном руководствовался RFC1350 в большей мере, чем книжкой R.Stevense.

  2. Возможно ли реализация TFTP на основе протокола, отличного от UDP?

    ДА! В [5] помещены примеры реализации на основе TCP.


Автор: Дмитрий Мажар