Библиотека сайта rus-linux.net
Sendmail – Архитектура и принципы разработки
Глава 17 из 1 тома книги "Архитектура приложений с открытым исходным кодом".
Оригинал: "Sendmail"
Автор: Eric Allman
Перевод: Vlad http://vlad8.com/
17.8. Что если бы я делал sendmail сегодня?
Многие вещи на сегодняшний день я бы сделал по-другому. Некоторые было трудно предсказать в то время (например, как спам изменит восприятие почтовой системы, как будут выглядеть современные наборы инструментов и т.д.), а некоторые были очень предсказуемы. В процессе написания sendmail я многое изучил о e-mail, TCP/IP и программировании вообще. Все растут в процессе того, как пишут код.
Но есть множество вещей, которые я бы сделал также, некоторые из них даже несмотря на противоречие с общепринятым мнением.
17.8.1. Что бы я сделал иначе
Наверное моей главной ошибкой с sendmail было то, что я не смог распознать достаточно быстро, насколько важной станет программа. У меня было несколько возможностей подтолкнуть мир в верном направлении, но я ими не воспользовался; в некоторых случаях даже наоборот, я нанес вред, например, не сделав sendmail более строгим к неверным данным, когда это следовало сделать. Я также довольно рано понял, что синтаксис конфигурационного файла нужно улучшить, когда работало только несколько сотен экземпляров sendmail, но решил ничего не менять, потому что не хотел причинять неудобства пользователям. Позже стало ясно, что лучше было бы исправить все раньше, пусть ценой небольшого неудобства, но зато сделать лучше в долгосрочной перспективе.
Синтаксис почтовых ящиков версии 7
Одним из примеров было то, как в почтовых ящиках версии 7 разделялись сообщения. Они использовании строку, начинавшуюся с “From?” (где “?” это ASCII символ пробела, 0х20) для разделения сообщений. Если приходило сообщение, содержавшее слово “From?” в начале строки, программа локальной почты конвертировала ее в “>From?”. После усовершенствования на некоторых системах стала требоваться предварительно пустая строка, но на это нельзя было рассчитывать. И по сей день “>From” появляется в чрезвычайно непредсказуемых местах, которые не совсем связаны с email (но очевидно были обработаны email в какой-то момент времени). В ретроспективе я понимаю, что, наверное мог бы исправить почтовую службу BSD — сделать использование нового синтаксиса. В то время меня бы все проклинали, но в перспективе я спас бы мир от огромных проблем.
Синтаксис и содержимое конфигурационного файла
Возможно, моей самой большой ошибкой в синтаксисе конфигурационного файла было использование таба (HT, 0×09) в правилах преобразования для разделения паттерна от заменяющего текста. В то время я делал подобно тому, как сделано в make, и только годы спустя я узнал, что Стюарт Фельдман, автор make, считал это одной из своих самых больших ошибок. Помимо того, что когда вы смотрите на экран, совсем неочевидно, если именно символ табуляции используется в файле, эти символы не сохраняются после вырезания и вставки на большинстве Windows-систем.
Хотя я считаю, что использование правил преобразования было хорошей идеей (см. ниже), я бы изменил общую структуру конфигурационного файла. Например, я не ожидал необходимость иерархии в конфигурации (например, опций, которые будут задаваться по-разному для различных портов SMTP). В то время, когда создавался конфигурационный файл, не было “стандартных” форматов. Сегодня бы склонялся к тому, чтобы сделать конфигурацию подобно Apache – она чистая, аккуратная и достаточно выразительная – или даже может быть включил язык, подобный Lua.
Когда разрабатывался sendmail, пространство адресов было небольшим и протоколы были еще меняющимися. Большие затраты сил на конфигурационный файл казались хорошей идеей. Сегодня, это выглядит как ошибка: у нас огромное пространство адресов (для агентов передачи почты), а стандарты довольно статичные. Более того, часть “конфигурационного файла” — на самом деле код, который нужно обновлять в новых релизах. Конфигурационный файл .mc исправляет это, но необходимость пересобирать конфигурацию каждый раз, когда обновляется программа, это неудобство. Простым решением для этого было бы иметь два конфигурационных файла, читаемые sendmail’ом: один скрытый и устанавливаемый с каждым новым релизом, а другой открытый, используемый для локальной конфигурации.
Использование инструментов
Сегодня доступно множество новых инструментов, например, для конфигурирования и собирания программ. Инструменты могут помочь в этом, но они также могут быть излишними, затрудняя понимание системы. Например, никогда не нужно использовать грамматику yacc(1), если все что вам нужно — это strtok(3). Но и переизобретать колесо также не является хорошей затеей. В частности, несмотря на некоторые замечания, я все равно точно бы использовал сегодня autoconf.
Обратная совместимость
Если бы у меня была возможность заглянуть в будущее и узнать, насколько вездесущим станет sendmail, я бы не беспокоился о том, что придется прекратить поддержку существующих инсталляций в первые дни разработки. Если существующая практика имеет серьезные проблемы, ее нужно исправлять, а не подстраиваться под нее. Несмотря на это, я бы все равно не сделал бы строгую проверку всех форматов сообщений; некоторые проблемы могут быть легко и безопасно проигнорированы или пропатчены. Например, я бы все равно добавил поле заголовка Message-Id: в сообщения, у которых его не было, но я бы больше склонялся к тому, чтобы отклонять сообщения без поля заголовка From:, а не пытался бы создавать его из информации в конверте.
Внутренние абстракции
Есть несколько внутренних абстракций, к которым я бы не прибегал сегодня, а есть другие, которые бы добавил. Например, я бы не использовал строки с завершающим нулем, вместо этого предпочел бы пары “длина/значение”, несмотря на то, что это означало бы, что большую часть стандартной библиотеки C было бы трудно использовать. Но даже только последствия этого решения для безопасности стоили того. Однако, я бы не пытался создавать систему обработки ошибок на C, вместо этого создал бы последовательную систему статусных кодов, которые бы использовались в коде программы вместо создания процедур, возвращающих null, false или отрицательные числа для представления ошибок.
Я бы точно абстрагировал бы концепцию имен почтовых ящиков от ID пользователя в Unix. В то время, когда я писал sendmail, модель была такова, что сообщения отправлялись только пользователям Unix. Сегодня такое почти не происходит; даже в системах, которые используют эту модель, существуют системные аккаунты, которые никогда не должны получать e-mail.
17.8.2. Что я бы оставил точно так же
Конечно, были и удачные решения…
Syslog
Одним из успешных сайд-проектов sendmail был syslog. В то время, когда писался sendmail, программы, которым нужно было писать информацию в лог, имели для этого специальный файл. Такие файлы были разбросаны по системе. Syslog было трудно написать в то время (UDP еще не существовало, поэтому я использовал так называемые mpx файлы), но это того стоило. Однако, я бы добавил одно существенное изменение: я бы обратил больше внимания на то, чтобы сделать синтаксис логируемых сообщений пригодным для разбора – я все-таки не смог предсказать существование мониторинга логов.
Правила преобразования
Правила преобразования были во многом опорочены, но я бы снова использовал их (хотя, возможно, не во всех случаях, где они используются сейчас). Использование символа табуляции было явной ошибкой, но учитывая ограничения ASCII и синтаксиса почтовых адресов, какой-то символ экранирования все-таки необходим. В общем, концепция использования замены по совпадению с паттерном работала хорошо и была очень гибкой.
Избегать ненужных инструментов
Несмотря на мой комментарий выше о том, что я бы использовал больше внешних инструментов, я бы не стал использовать многие доступные сейчас динамические библиотеки. На мой взгляд многие из них слишком раздуты. Библиотеки нужно выбирать осторожно, балансируя между пользой от повторного использования кода и проблемой использования чересчур мощного инструмента для решения простой проблемы. Как минимум, я бы избегал использования XML в качестве языка конфигурации. Я думаю, что его синтаксис слишком расточителен для таких задач. У XML есть свое место, но сейчас он используется чересчур часто.
Код на C
Некоторые люди предложили, что более естественным языком для реализации были бы Java или C++. Несмотря на хорошо известные проблемы C, я все равно выбрал бы его для реализации. Отчасти это навеяно личными предпочтениями: я знаю C намного лучше, чем Java или C++. Но я также разочарован той небрежностью, с котрой большинство объектно-ориентированных языков относится к распределению памяти. Распределение памяти во многом затрагивает проблемы производительности, которые трудно охарактеризовать. Senmail используется объектно-ориентированные концепции внутри, где это необходимо (например, реализация классов преобразования данных), но на мой взгляд полный переход на объектно-ориентированное программирование было бы очень расточительным и чересчур ограничивающим.
17.9. Заключение
Агент передачи почтовых сообщений sendmail появился в момент невероятного подъема, своего рода “на диком Западе”, существовавшем, когда e-mail не был должным образом продуман, а текущие почтовые стандарты не были еще сформулированы. В последующие 31 год “почтовая проблема” изменялась от просто надежной работы до работы с большими сообщениями и серьезными нагрузками, затем до защиты узлов от спама и вирусов и, наконец, на данный момент – использования в качестве платформы для огромного количества приложений, основанных на использовании e-mail. Sendmail эволюционировал в рабочую лошадку, используемую даже самыми избегающими рисков корпорациями, после того, как электронная почта прошла путь от простой текстовой коммуникации между людьми до части инфраструктуры, использующей мультимедиа и критичной для выполнения задач.
Причины такого успеха не всегда очевидны. Создание небольшой группой частично занятых в проекте разработчиков программы, которая выживает и даже процветает в постоянно меняющемся мире, не может быть выполнено при использовании обычных методологий разработки программного обеспечения. Я надеюсь, что пролил некоторый свет на факторы успеха sendmail.
Ссылки
Вернуться к началу статьи.