Свой лунапарк TFTP с блэкджеком и С++17

image


Преамбула

Я работаю в команде разработки встраиваемого ПО на базе GNU Linux для телекоммуникационного оборудования. В ходе разработки у нашей команды появляется огромное количество прошивок для нашего оборудования: релизные версии, предрелизные версии, тестовые отладочные сборки, сборки для разных веток из трекера задач — и все это для разных аппаратных платформ.


Прошивка, в данном случае, это …

набор бинарных файлов, размером до 70Мб, представляющих собой:


  • доработанный Das u-boot;
  • доработанное ядро GNU Linux;
  • файловая система, в которой содержится множество скомпилированных исполняемых файлов, конфигураций и пр., например, корневая файловая система GNU Linux;
  • кортеж комбинаций всего перечисленного;

Для идентификации файлов прошивки в системе документооборота и трекере используются MD5 хеши в файлах *.md5. В итоге имеем несколько деревьев в файловой системе для хранения прошивок.

Обновление ПО, а именно передача прошивки в изделие, происходит через протокол TFTP.


Постановка задачи

Необходимо избавиться от «головной боли» при поиске и идентификации нужной прошивки, для чего необходимо чтобы сервер TFTP осуществлял поиск и выгрузку файлов используя их md5-хеш, осуществляя рекурсивный поиск по нескольким каталогам.


Результат

В результате, получился проект TFTP Firmware Server или просто server-fw.

Поддержка рекомендаций:


  • RFC1350 «THE TFTP PROTOCOL (REVISION 2)»
  • RFC2347 «TFTP Option Extension»
  • RFC2348 «TFTP Blocksize Option»
  • RFC7440 «TFTP Windowsize Option» (экспериментально)

Текущая версия сервера v0.2.0


Список опций сервера
$ bin/server-fw -h
Simple tftp firmware server 'server-fw' v0.2 licensed GPL-3.0
(c) 2019-2021 Vitaliy.V.Shirinkin, e-mail: vitaliy.shirinkin@gmail.com
Some features:
  - Recursive search requested files by md5 sum in search directory
  - Use Firebird SQL server as file storage (optional requirement)
Usage: bin/server-fw [ []] [ []] ... 
Possible options:
  {-h|-H|-?|--help} Show help message
  {-l|-L|--ip|--listen} {|[]}[:port] Listening address and port
    (default 0.0.0.0:69)
    Sample IPv4: 192.168.0.1:69
    Sample IPv6: [::1]:69
  {-s|-S|--syslog} <0...7> SYSLOG level flooding (default 6)
  --lib-dir  System library directory
  --lib-name  Firebird library filename (default libfbclient.so)
  --root-dir  Server root directory
  --search  Directory for recursive search by md5 sum (may be much)
  --fb-db  Firebird access database name
  --fb-user  Firebird access user name
  --fb-pass  Firebird access password
  --fb-role  Firebird access role
  --fb-dialect <1...3> Firebird server dialect (default 3)
  --daemon Run as daemon
  --retransmit  Maximum retransmit count if fail
  --file-chuser  Set user owner for created files (default root)
  --file-chgrp  Set group owner for created files (default root)
    Warning: if user/group not exist then use root
  --file-chmod  Set permissions for created files (default 0664)
    Warning: can set only r/w bits - maximum 0666; can't set x-bits and superbits

Сервер позволяет настроить один основной каталог (опция --root-dir) и любое количество каталогов для поиска (опция --search). Каталоги для поиска работают только для GET запросов.
Для принимаемых файлов сервер позволяет настроить права (опция --file-chmod) и владение (опция --file-chuser и опция --file-chgrp).

Для запуска в качестве демона настройки располагаются в файле /etc/default/server-fw.


Соответствие настроек файла конфигурации и аргументов командной строки сервера

Обработка запросов GET осуществляется в следующем порядке:


  • если сервер распознает имя как md5-хеш, то ищет по хешу:
    — в основном каталоге сервера
    — в дополнительных каталогах поиска в порядке их задания в опциях
  • сервер ищет по имени файла:
    — в основном каталоге сервера
    — в дополнительных каталогах поиска в порядке их задания в опциях

При обработке запросов PUT, сервер складывает файл в основной каталог.

Пакет для установки для OC Ubuntu 18.04 (другие не проверялись) лежит здесь

Для самостоятельной сборки (GNU Linux):

$ mkdir server-fw
$ git clone https://github.com/shvit/server-fw.git server-fw
...
$ cd server-fw
$ make deb
...
$

Рефлексия

Сервер не поддерживает режим mail и netascii, вернее он должен их обрабатывать аналогично режиму octet (интересно узнать, а кто-то их испрользует? см. опрос).

Проверить опцию «windowsize» пока не получилось, но вроде должно работать.


Послесловие


Задачи на будущее:
  • использовать для хранения файлов реляционную СУБД
  • расширить поиск файлов по дополнительным метаданным

© Habrahabr.ru