Кратко

  • По RFC 4028 срок продлевает только ответ 2xx на внутридиалоговый re-INVITE или UPDATE. Отправленный запрос, видимый трафик и 422 обновлением не являются.
  • Session-Expires, Min-SE и refresher распределяют тайминг, обязанность обновлять и право очистить локальное состояние. Они не подтверждают RTP, человека, качество, согласие или корректность начислений.
  • Проверяемая модель хранит отдельно транзакцию, диалог, медиа, приложение и коммерческое решение, связывая их по происхождению и времени без единственного флага «звонок жив».

Успешная транзакция рядом с мёртвым звуком

Сигнализация корпоративного звонка идёт через stateful-прокси, RTP — по отдельному маршруту. Назначенный refresher отправляет UPDATE без SDP, получает 200 OK, и прокси рассчитывает новый deadline. Но односторонняя авария уже остановила голосовые пакеты; отчёты RTCP исчезли, человек отошёл от устройства, а приложение ещё не послало BYE.

Если тарификация принимает событие session refreshed за продолжение услуги, она начисляет лишнее время. Протокол при этом может работать точно по спецификации. Ошибка возникает, когда факт о сигнализации получает власть над медиа и договором.

RFC 4028 решает узкую задачу: UA может не отправить BYE, либо BYE теряется, и call-stateful-прокси сохраняет состояние бесконечно. Периодические re-INVITE или UPDATE задают границу устаревания SIP-состояния. Спецификация отдельно упоминает специфические для медиа признаки жизни, например RTCP.

Session timer — не универсальный пульс. Это срок действия конкретного сигнального состояния.

Три времени вместо одного

Session interval — максимальная пауза между успешными обновлениями. Текущее значение берётся из Session-Expires последнего значимого 2xx.

Minimum timer — самый короткий интервал, который элемент готов принять. Внутридиалоговые запросы стоят ресурсов, поэтому Min-SE не позволяет навязать слишком частую нагрузку.

Session expiration — локально вычисленный предел. UAS считает от отправки 2xx, UAC — от получения, прокси — от пересылаемого им ответа. Передача и обработка разводят эти моменты. Единого заверенного всеми времени нет.

Запись «1800 секунд» не говорит, какой ответ установил интервал, когда запустились локальные часы, кто обязан обновлять и не выключил ли последующий 2xx timer. Для расследования нужны исходное событие и локальный монотонный deadline.

Ограничения сходятся по всему пути

UAC может объявить option tag timer и предложить интервал. Прокси, сохраняющие состояние, вправе потребовать timer, уменьшить Session-Expires или поднять Min-SE, но не опустить интервал ниже накопленного минимума.

UAS возвращает финальный интервал в 2xx и выбирает refresher=uac либо refresher=uas. На обратном пути прокси видят итог, но уже не переписывают его.

Слишком короткое предложение получает 422 Session Interval Too Small с Min-SE. UAC может начать новую транзакцию с большим CSeq и допустимым значением. Это согласование ограничений, не успешный refresh. Deadline двигает только 2xx.

Поэтому 422 перед самым истечением создаёт гонку: будущее значение известно, но новый запрос должен завершиться до старого срока. Лог, где остался лишь последующий 200, скрывает опасное окно.

Минимум также защищает от усиления нагрузки. Всплеск 422 может означать новую трассу, политику, перегрузочную защиту, неверный default или атаку. Код ответа не устанавливает виновника.

uac и uas — роли, а не стороны договора

refresher назначает следующий refresh. Он не называет постоянного звонящего, клиента или плательщика. UAC и UAS — роли одной транзакции: получатель первого INVITE становится UAC, когда позже отправляет UPDATE.

Поэтому refresher=uac без контекста недостаточно. Нужно привязать роль к endpoint именно этой транзакции и сохранить Call-ID, tags, method, CSeq и направление.

Forking создаёт из одного INVITE несколько диалогов. У каждого возможны собственные интервал, refresher и срок — либо timer отсутствует. Обновление одной ветви не продлевает соседнюю. А 2xx без Session-Expires способен выключить timer в середине диалога: когда-то включённый механизм не равен текущему состоянию.

Единственное событие, которое продлевает срок

Граница RFC 4028 однозначна: только 2xx на refresh request. Отправка UPDATE, provisional response, 401/407, 422, запись в транспорт или наблюдение запроса прокси не подходят. Поздняя успешная аутентифицированная попытка не делает первую успешной задним числом.

При timeout, 408 или 481 обновляющий UA отправляет BYE. Другие ошибки могут допускать ограниченный повтор, но не бесконечную маскировку отказа.

У non-refresher другая обязанность: если обновления нет, он посылает BYE незадолго до конца. Рекомендуемый запас — минимум из 32 секунд и трети интервала, потому что firewall или NAT ALG на точной границе может уже закрыть путь.

У прокси полномочий меньше. После своего deadline он удаляет состояние и освобождает ресурсы, но не создаёт BYE от имени endpoint. Он управляет собственной записью, не объявляет разговор оконченным.

Поэтому медиа могут продолжаться после очистки прокси, BYE может потеряться, локальные deadlines — разойтись. Один синтетический hangup time превращает наблюдаемое расхождение в ложную точность.

Refresh может одновременно что-то изменить

Re-INVITE и UPDATE остаются обычными SIP-методами. RFC 3311 разрешает UPDATE менять session information и remote target. RFC 3261 связывает re-INVITE с dialog, target refresh и offer/answer.

Для чистого таймера RFC 4028 рекомендует UPDATE без offer, если peer его поддерживает. Re-INVITE обычно несёт offer даже при прежнем SDP. Запрос ради hold, resume или нового media path тоже может заодно обновить timer.

Один 2xx способен сопровождать новый Contact, SDP, направление stream, codec, адрес, аутентификацию или разрешение гонки. RFC 6141 разбирает re-INVITE, 491 и восстановление offer/answer именно потому, что это не простой ping.

Аудит должен показать назначение запроса, наличие и hash SDP, origin version, направления, Contact и финальный response.

Сигнализация и медиа отвечают на разные вопросы

RFC 3264 согласует sendrecv, sendonly, recvonly, inactive или отклонённый stream. Это заявленные состояния, не квитанции доставки.

RFC 3550 не гарантирует для RTP ни доставку, ни качество. RTCP даёт reception reports, timing и сведения об участниках. Это ценная оценка потока, но не доказательство, что человек услышал, понял, согласился или получил услугу.

Нужно разделять как минимум пять слоёв: SIP-транзакцию; dialog и timer; RTP/RTCP; приложение и действие человека; entitlement, billing и compliance. 2xx силён в первых двух и почти ничего не говорит о последних трёх.

Медиа умирают при успешных refresh, продолжаются при потере сигнализации, бывают намеренно inactive, а программа работает после ухода человека. Различие Heng Lu между символической властью и практической реальностью становится инженерным правилом: верная запись не получает суверенитет над исполнением.

Защита по хопам тоже ограничена

Прокси законно меняют timer fields, поэтому end-to-end S/MIME не подходит для полей, которые должны редактировать посредники. RFC 4028 рекомендует TLS на каждом релевантном хопе и SIPS.

Это мешает постороннему изменить частоту или очистку, пока вся цепочка защищена. Но целостность поля не превращает его в аттестацию медиа или счёта.

Реестр errata RFC 4028 содержит verified-исправления терминов UAC/UAS. Сообщение мая 2026 года о поведении прокси при явном refresher=uas пока имеет статус Reported. Его надо проверять на совместимость, а не выдавать за изменённую норму.

След, пригодный для спора

Защищаемая запись связывает dialog identity с реальными ролями endpoint в каждой транзакции. Она хранит method, CSeq, branch, route, timer fields до и после посредников, времена запросов и ответов, вычисленные deadlines и конкретный 2xx, который их сдвинул.

Нужны и побочные эффекты: наличие и hash SDP, offer/answer version, направления, Contact, challenges и retries. У BYE должны быть источник и причина — пользователь, refresh failure, peer timeout или policy.

Медиа и приложение остаются независимыми источниками. SIP раскрывает личность и топологию, поэтому оригинал можно держать в ограниченном хранилище, а в общей телеметрии — связанные проекции или keyed hashes.

Тестовый набор включает 422 у deadline, 401 с успешным повтором, 408, 481, отсутствие refresh у peer, очистку прокси без BYE, мёртвые медиа при свежем SIP, медиа после потери сигнализации, разные forked dialogs, выключение timer, offerless UPDATE, re-INVITE с изменением SDP, target refresh, потерю состояния при failover и незащищённый хоп.

Итог — не один зелёный бит, а линия событий, объясняющая, какой слой жил и кто на каком основании действовал.

Источники