Кратко
- TCP сохранял надёжный упорядоченный поток байтов, но не границы CALL и REPLY; ONC RPC поместил каждое сообщение в запись из одного или нескольких фрагментов.
- Перед фрагментом шёл четырёхбайтный маркер big-endian: младшие 31 бит задавали его длину, старший сообщал, что запись кончится после этих данных.
- Полная запись доказывала framing, а не исполнение: XDR, XID, аутентификация, разрешение, результат и долговременный эффект требовали отдельных решений.
Один read не был одним вызовом
Приложение просит четыре байта, а система возвращает два. Это не укороченный заголовок, а пока лишь половина заголовка. В следующем чтении могут прийти остальные два байта, всё тело, несколько полных записей и начало новой.
RFC 793 определил TCP как службу упорядоченных октетов и не позволил PUSH стать границей записи. Нынешний RFC 9293 по-прежнему говорит о надёжном упорядоченном byte stream. Сегменты перевозят поток, но не сообщают грамматику удалённой процедуры.
RPC должен был отделить один CALL от следующего и одну REPLY от соседней. Поскольку транспорт не обещал этого знания, граница появилась в протоколе сообщений.
Старший бит замыкал то, что отсчитали младшие
RFC 1050 в апреле 1988 года назвал механизм record marking. Одно RPC-сообщение помещалось в одну RM-запись, состоящую из одного или нескольких фрагментов. Июньский RFC 1057 сохранил тот же формат.
Фрагмент начинается с четырёхбайтного беззнакового слова в порядке от старшего байта к младшему. Нижние 31 бит объявляют от нуля до 2^31 - 1 следующих байтов данных. Старший бит равен единице для последнего фрагмента записи и нулю, если в той же записи будет ещё один.
Единица не закрывает запись прямо в заголовке. Сначала принимается весь заявленный фрагмент. Если его длина выполнена, но бит был нулём, запись тоже не завершена: следующие четыре байта открывают очередной фрагмент той же записи.
Граница возникала из точного состояния
Парсер накапливает четыре байта маркера, отделяет бит от длины и затем потребляет ровно объявленное тело. Оно может прийти через любое число TCP-чтений. Данные остаются привязаны к текущей записи.
При нуле парсер снова ждёт маркер. При единице накопленные фрагменты становятся одним законченным RPC-сообщением, а оставшиеся байты начинают следующую запись. Алгоритм одинаков для заголовка, рассечённого пакетами, и для множества записей в одном буфере.
Нулевая длина входит в допустимый диапазон: данных нет, но решение продолжить или закончить остаётся. А разрыв соединения внутри заявленного тела оставляет усечённый фрагмент. Он не доказывает, что удалённая процедура не выполнилась.
Фрагмент записи не совпадал с фрагментом сети
RM fragment, IP fragment и TCP segment — объекты разных уровней. RM-фрагмент также не обязан совпадать с одним write или одним значением XDR. Он может занимать много TCP-сегментов, а один сегмент может нести несколько фрагментов и записей.
Старший бит не является FIN, PSH, концом файла, commit или признаком успеха. CALL и REPLY — разные сообщения с отдельными записями. Правильно закрытая запись может содержать неизвестную программу, недопустимые аргументы или отвергнутые учётные данные.
PUSH просит продвинуть доступные байты без лишнего ожидания. RM указывает, сколько байтов принадлежит текущему фрагменту и завершает ли он сообщение. Время отправки и синтаксическая граница не взаимозаменяемы.
Внешняя рамка не стала XDR
Внутри RPC использует External Data Representation. RFC 4506 задаёт канонические числа, длины, заполнение и типы для разных архитектур.
Но RPC-спецификации отдельно предупреждают: четырёхбайтный маркер не находится в стандартной форме XDR. Порядок байтов похож, назначение иное. Потоковый parser обязан найти контейнер до того, как XDR разберёт полное значение внутри него.
Поэтому правильная граница и правильное содержание могут дать разные результаты. Неприемлемую длину можно остановить до вызова процедуры. Идеально закрытая запись может затем не пройти XDR или RPC. Факт окончания не подтверждает содержимое.
Тридцать один бит не выделял память
Поле ограничивает один фрагмент, не всю запись. Поскольку фрагментов может быть несколько, базовый формат не объявляет единого суммарного максимума. Числовой диапазон также не приказывает немедленно резервировать память; такая реализация отдаёт ресурсы получателя под власть отправителя.
Нужны локальные бюджеты общей длины, числа фрагментов, памяти и времени. Это эксплуатационный вывод для безопасной реализации, а не новый нормативный предел RFC. В журнале должны оставаться и заявленное число, и применённая политика.
Документы говорят, что границы помогают обнаруживать и иногда исправлять протокольные ошибки, но не определяют сканирование payload в поиске похожего слова. Любой шаблон может встретиться в данных. После потери синхронизации закрыть соединение нередко честнее, чем приписать байты другому вызову.
Формат сохранился, пока иной транспорт не заменил framing
RFC 1831 перенёс правило в 1995 год. RFC 5531 заменил его в 2009-м без изменений на проводе. Простота выжила, потому что восполняла только отсутствующую границу TCP.
RFC 8166 показывает зависимость от транспорта. RPC-over-RDMA имеет собственные transport stream и payload stream и заменяет всё прочее RPC-framing, включая TCP record marking даже при работе RDMA поверх TCP. Динамический переход допустим между отдельными RPC-сообщениями и согласованно с транспортом.
Следовательно, RM была не вечным свойством процедуры, а адаптером сообщения к конкретному byte stream.
Границы источников
Закрытый набор состоит из RFC 793, RFC 1050, RFC 1057, RFC 1831, RFC 4506, RFC 5531, RFC 8166 и RFC 9293. Он подтверждает формат, историю и разделение слоёв, но не измеряет современное применение, не сертифицирует библиотеку и не доказывает личность, полномочие или исход реального вызова.
Старший бит оказался долговечным именно потому, что не был печатью исполнения. Он завершал запись, оставляя последствия тому уровню, который мог их проверить.
Обзор для участников
Подробный контекст профиля
Войдите с подходящим уровнем подписки, чтобы открыть полный обзор и примечания к источникам.
Только для Стратегического сообщества
Стратегическое сообщество
Открыто всем читателям. Вступите и войдите, чтобы открыть обзоры профилей.
Вступить в Стратегическое сообществоТолько для Альянса лидеров
Альянс лидеров
Для проверенных владельцев IP-активов и руководителей. Войдите, чтобы открыть обзоры Альянса.
Вступить в Альянс лидеров
