Кратко
- RFC 1141 дал удобный способ изменить уже записанную в IP-заголовке контрольную сумму после изменения одного поля, в частности времени жизни TTL.
- RFC 1624 показал, что на границе нуля способ выдаёт
0xFFFFвместо результата полного пересчёта0x0000, и предложил исправленное выражение.
В привычной бухгалтерии ноль один. В арифметике с дополнением до единицы у него две формы: все биты обнулены или все выставлены. Пока речь идёт об абстрактной сумме, двойник мало кому мешает. Когда итоговые биты надо записать в заголовок пакета, соседний компьютер способен различить братьев. На этом различии сломался аккуратный приём обновления контрольной суммы.
RFC 1071, опубликованный в сентябре 1988 года, описал алгоритм интернет-контрольной суммы. Байты складываются в 16-битные слова, их сумма считается по правилам дополнения до единицы, а её инверсия занимает поле контрольной суммы. Для проверки можно сложить заголовок вместе с этим полем и ожидать все единицы. Авторы подробно разбирали ускорение: работу с порядком байтов, параллельное сложение, отложенный перенос, совмещение подсчёта с копированием памяти. Если изменилось одно слово заголовка, предлагалось использовать разницу старого и нового значения.
У маршрутизатора такой случай возникает при уменьшении TTL. Прочие поля остаются прежними, поэтому повторное сложение всего заголовка кажется лишним. RFC 1141 января 1990 года записал формулу для контрольной суммы, которая уже находится в пакете. Для уменьшения TTL на единицу, когда он расположен в старшем байте 16-битного слова, документ показывал прибавление 0x100 к полю суммы. Полезный маленький шаг в часто выполняемой операции.
Но правила сложения здесь непривычны. Положительный ноль записывается как 0x0000, отрицательный — как 0xFFFF. RFC 1624 мая 1994 года нашёл в выводе RFC 1141 предположение о распределительном свойстве, которое перестаёт действовать при нулевом результате. Выражение, похожее на законную перестановку слагаемых, приводило к другой записи нуля в контрольном поле.
Проверочный пример точен до каждого числа. Значение одного 16-битного поля меняется с 0x5555 на 0x3285; остальные слова заголовка вместе дают 0xCD7A. Прежняя контрольная сумма равна 0xDD2F. Полный пересчёт нового заголовка даёт 0x0000. Формула RFC 1141 выводит 0xFFFF. Исправленная запись из RFC 1624 — HC' = ~(~HC + ~m + m') — возвращает 0x0000. При наличии в IP-заголовке ненулевого поля полное вычисление не могло бы оставить 0xFFFF в этом поле контрольной суммы.
У получателя оставалась собственная процедура проверки. Если он складывал весь заголовок, включая контрольное поле, и сравнивал сумму со всеми единицами, оба значения из примера проходили. Если заново вычислял значение контрольного поля и сравнивал его с полученными битами, ошибочный 0xFFFF мог привести к отказу. Поэтому вопрос «работал ли пакет» решался не одним числом в промежуточном устройстве, а ещё и способом проверки на конечной машине.
RFC 1624 рассказал о происхождении поправки. Граничный случай обнаружили при испытании продукта, где применялся алгоритм RFC 1141; улучшенное решение затем проверили моделированием. Публичный текст не называет изделие и не считает распространённость ошибки. Зато оставляет воспроизводимые исходные значения и объяснение неверного шага в формуле. Для желающих сберечь дополнительные машинные команды приводится вариант с вычитанием и заёмом.
Обновлять сумму по изменённому полю было разумно: маршрутизатору не нужно снова читать неизменное. После исправления правило стало строже к последней детали — какие именно биты записаны в пакет. Два математических нуля встретились с одним вполне материальным полем заголовка.
Обзор для участников
Подробный контекст профиля
Войдите с подходящим уровнем подписки, чтобы открыть полный обзор и примечания к источникам.
Только для Стратегического сообщества
Стратегическое сообщество
Открыто всем читателям. Вступите и войдите, чтобы открыть обзоры профилей.
Вступить в Стратегическое сообществоТолько для Альянса лидеров
Альянс лидеров
Для проверенных владельцев IP-активов и руководителей. Войдите, чтобы открыть обзоры Альянса.
Вступить в Альянс лидеров





