Как изменить API BoringSSL
BoringSSL предоставляет больше возможностей для внесения изменений, чем многие другие библиотечные проекты, поскольку мы имеем представление о том, кто наши пользователи. Тем не менее, внесение критических изменений требует осторожности. Мы полагаемся на тесную обратную связь с нашими потребителями, чтобы узнавать об ошибках и исправлять их. Чтобы это работало, обновление BoringSSL должно быть плавным.
В конечном итоге стратегия для каждого критического изменения определяется в каждом конкретном случае. Этот документ содержит рекомендации и методы, которые помогут обеспечить плавный переход.
Риск поломки
Традиционно критические изменения определяются с точки зрения поверхности API или ABI. Открытые символы и сигнатуры типов не могут изменяться и т. д. Но это плохое приближение к истинному воздействию. Удаление API может не привести к критическому изменению, если им никто не пользуется. И наоборот, действует закон Хайрама. Исправление ошибки может стать критическим изменением для некоторых потребителей, которые зависели от этой ошибки.
Таким образом, мы думаем не о том, является ли изменение формально критическим, а о риске того, что оно кого-то сломает.
Некоторые изменения, такие как внутренние очистки или исправления ошибок, имеют низкий риск и не требуют специальных мер. Любые проблемы можно решить, когда затронутый потребитель обновит BoringSSL и заметит.
Другие изменения, такие как удаление API, запрет некоторых крайних случаев или корректировка поведения, с большей вероятностью приведут к поломке. Чтобы помочь потребителю устранить любые возникающие сбои, включите текст в сообщение фиксации, предварённое Update-Note: . Это может включать информацию о том, что может нарушить это изменение, и инструкции по устранению проблемы.
Поиск кода
Подавляющее большинство потребителей BoringSSL удобно проиндексировано в различных экземплярах поиска кода. Это позволяет предсказать влияние рискованного изменения и заранее определить код для исправления. Документ «Как выполнить поиск кода» в (только для Google) go/boringssl-folder включает примечания по этому поводу.
Оцените стоимость изменения
Если какое-либо изменение имеет высокую стоимость (из-за необходимости исправлять потребителей) и относительно небольшую пользу для BoringSSL, оно может не стоить затраченных усилий. Например, вероятно, не стоит удалять небольшую функцию совместимости в углу библиотеки, которую легко отбрасывает статический компоновщик.
И наоборот, изменение, которое приводит к значительному улучшению для всех потребителей BoringSSL за счёт исправления одного или двух потребителей, обычно того стоит.
Исправление потребителей
Если поиск кода выявляет сайты вызовов, которые определённо будут ломаться, предпочтительнее обработать их перед внесением изменения. Хотя неожиданное нарушение всегда возможно, мы обычно считаем, что ответственность за последствия этого изменения несёт разработчик или группа, вносящая изменение. Команды, как правило, недовольны тем, что их застают врасплох новые работы по миграции, но рады, что работа по миграции выполнена за них.
В большинстве случаев это просто:
Удаление всё равно должно включать тег Update-Note, на случай, если некоторые из них были пропущены.
В некоторых случаях такой поэтапный подход невозможен: возможно, один и тот же код не может одновременно работать до и после изменения, или, возможно, существует слишком много разных версий. Например, Conscrypt поступает в три разных репозитория. Репозиторий GitHub напрямую потребляет ветку BoringSSL master. Он отправляется в Android, где он потребляет внешний/boringssl Android. Ещё одна копия отправляется во внутренний репозиторий, где она потребляет эту копию BoringSSL. Поскольку каждый из этих Conscrypts обновляется независимо от соответствующих BoringSSLs, Conscrypt upstream не может полагаться на новый API BoringSSL, пока он не появится во всех копиях BoringSSL, на которые полагаются его нисходящие потоки.
В этом случае более подходящим может быть многостороннее изменение:
Загрузите критическое изменение в Gerrit, но пока не отправляйте его. Увеличьте символ BORINGSSL_API_VERSION. 2. Внесите логику препроцессора #if BORINGSSL_API_VERSION < N
в потребляющий репозиторий. Оставьте комментарий, чтобы позже удалить его, со ссылкой на изменение BoringSSL.
Когда проверка BORINGSSL_API_VERSION
распространится на соответствующие копии потребляющего репозитория, отправьте изменение BoringSSL.
Когда изменение BoringSSL распространится на соответствующие копии BoringSSL, удалите промежуточную логику из потребителя.
Наконец, в некоторых случаях изменение потребителя может быть зафиксировано атомарно с обновлением BoringSSL. Это можно сделать только для кода, который использует только один экземпляр BoringSSL (поэтому пример Conscrypt выше не подходит). Сначала проконсультируйтесь с сопровождающим этого проекта или, что ещё лучше, сами станьте сопровождающим этого проекта.
Если в каком-то потребителе требуются более сложные изменения, обсудите их с соответствующими сопровождающими, чтобы спланировать переход.
Когда происходят критические изменения, они должны завершаться сбоем как можно раньше и как можно более явно.
В идеале проблемные потребители не могут скомпилироваться. Лучше полностью удалить функции, чем оставить всегда сбойную заглушку. Иногда это невозможно из-за других потребителей, особенно библиотек привязок. В качестве альтернативы, если заглушка может быть разумно обоснована как всё ещё удовлетворяющая ограничениям API, рассмотрите возможность её добавления для улучшения совместимости. Например, BoringSSL имеет множество заглушек no-op, соответствующих множеству функций инициализации OpenSSL.
Если какой-либо параметр теперь должен быть NULL
, измените тип на непрозрачный указатель структуры. Потребители, передающие указатели не NULL
, не смогут скомпилироваться.
Если нарушение компиляции невозможно, прервите выполнение в надежде, что у потребителей есть некоторое покрытие тестами. При этом старайтесь потерпеть неудачу в общем случае. В частности, не полагайтесь на то, что потребители адекватно тестируют или даже проверяют случаи сбоев. Одна из стратегий — привести объект в «отравленное» состояние: если происходит незаконная операция, установите флаг, чтобы все последующие операции завершились ошибкой.
В других функциях может быть уместно просто вызвать abort()
.
Хотя мы стараемся избегать поломок, иногда вещи ломаются неожиданно. В зависимости от воздействия мы можем исправить потребителя, внести небольшое исправление в BoringSSL или отменить изменение, чтобы либо попробовать снова позже, либо пересмотреть подход.
Если мы в конечном итоге не исправим потребителя, добавьте тест в BoringSSL для проверки неожиданного контракта API, чтобы будущие регрессии быстро обнаруживались.
При планировании крупного проекта, зависящего от критического изменения, сначала внесите критическое изменение — до внесения более крупных изменений. Или при изменении требований к инструментарию или языку добавьте небольшой экземпляр зависимости где-нибудь, а затем подождите пару недель, пока изменение появится у потребителей. Это гарантирует, что при необходимости возврат к изменению всё ещё возможен.
Хотя мы полагаемся на тесную обратную связь с нашими потребителями, есть несколько потребителей, которые обновляются реже. Для чрезвычайно рискованных изменений, таких как введение C++ в цель, может быть целесообразно подождать гораздо дольше.
Во многих случаях мы заинтересованы в изменении поведения, которое пришло из OpenSSL. Поверхность API OpenSSL огромна, но фактически используется лишь небольшая часть. Поэтому мы можем и иногда меняем такое поведение. Это сложнее, чем изменить поведение, связанное только с BoringSSL, из-за стороннего кода.
Мы используем BoringSSL во многих сторонних проектах, которые обычно используют OpenSSL. Как правило, мы считаем это своей обязанностью заставить это работать и не поощряем внешние проекты полагаться на BoringSSL. Хотя мы можем поддерживать патчи для этого по мере необходимости, это требует дополнительных усилий, поэтому стоимость нарушения стороннего кода выше.
Мы довольно сильно склоняемся к внесению изменений в BoringSSL вместо исправления стороннего кода, если только стороннее изменение не устраняет проблему безопасности.
Кроме того, изменение API OpenSSL повлияет не только на сторонний код, который мы используем сегодня, но и на любой сторонний код, который мы будем использовать в будущем. Таким образом, Code Search менее полезен в качестве абсолютного инструмента. Предсказатель и различные другие соображения, представленные в этом документе, более важны.
Если патч для поддержки изменения BoringSSL может быть полезен стороннему проекту, отправьте его вверх по течению. Например, он может лучше использовать API, очистить код или помочь поддерживать новые версии OpenSSL. В целом мы стараемся обеспечить совместимость с «большинством» «хорошо себя ведущих» пользователей OpenSSL.
Наконец, если какой-то конкретный API или паттерн OpenSSL проблематичен для BoringSSL, вероятно, он проблематичен и для OpenSSL тоже. Рассмотрите возможность подачи им заявки на ошибку, чтобы предложить изменение либо в новом коде, либо для следующего разрыва API. Циклы выпуска и циклы обратной связи OpenSSL намного длиннее, чем у BoringSSL, поэтому обычно это не приносит немедленной пользы, но помогает экосистеме двигаться в правильном направлении.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )