При работе с SIP-телефонией достаточно часто можно встретить проблему отсутствия слышимости. Ошибка может возникнуть как на сети, так и на стороне SIP-устройства или приложения.

Хотелось бы поделиться сбоем, вероятность воспроизведения которого крайне мала - настолько, что техподдержке проще будет сослаться на ошибку из-за космических лучей: в ТП одного крупного оператора SIP-телефонии за 3 года зафиксировано 6 обращений, в которых такая проблема зафиксирована (из ~300.000 всего - 0.002%).

Данные для диагностики

Обращается абонент с примером звонка, в котором он не слышал другого собеседника.

Известно, что проблем на оконечном оборудовании с трубкой/гарнитурой/микрофоном нет.
Звук и пишется, и воспроизводится.

Имеется дамп SIP-звонка:

По протоколу SIP звонок успешно установлен (INVITE - 200 OK - ACK), пошёл нормальный обмен RTP-пакетами с двух сторон:

Cвязки IP:порт не меняются
Cвязки IP:порт не меняются

Наличие с одной стороны двух RTP дорожек нарушением не является - так, например, одна дорожка может быть мелодией ожидания от АТС, а потом уже голос абонента.

Потери и задержки на сети в норме (менее 5% и не более 150 мс):

С джиттером тоже всё хорошо. Максимальные значения нигде не зашкаливают:

Согласование кодеков прошло успешно - выбран PCMA (g711a).
Ptime у абонентов также совпадает - 20 мс.

Со стороны абонента A
Со стороны абонента A
Со стороны абонента B
Со стороны абонента B

При просмотре RTP-дорожек видно, что они непустые (идут колебания), но опять смущает разрыв со стороны одного абонента на 2 дорожки:

Абонент A - синяя дорожка. Абонент B - чёрная и коричневая
Абонент A - синяя дорожка. Абонент B - чёрная и коричневая

Как указано ранее - это частое явление и само по себе ошибкой не является.
Здесь вышло скорее наоборот - абонент B (с черной и коричневой дорожкой) не слышал абонента A (с единой синей). Хотя по идее, в его сторону отправка звука шла без разрыва.

На данном этапе мы проверили практически все параметры, которые требовали проверки при проблемах с качеством связи или отсутствием слышимости - кроме SSRC.

Смена SSRC

Что такое SSRC?

Synchronization source (SSRC): The source of a stream of RTP packets, identified by a 32-bit numeric SSRC identifier carried in the RTP header so as not to be dependent upon the network address. (RFC 3550 - стр. 10)

Проще говоря, SSRC - это идентификатор источника потока RTP:

Разные SSRC от одного абонента
Разные SSRC от одного абонента

По RFC 3550 и RFC 8108 SSRC менять можно. Несколько SSRC может использоваться при использовании абонентом нескольких типов мультимедиа (аудио + видео), нескольких устройств захвата голоса и т.д.

Один из авторов RFC 8108 предоставил комментарий:

Да, SSRC может измениться. Кроме того, вы можете увидеть несколько SSRC в сеансе (одноадресный сеанс не ограничивается одним SSRC от каждого участника или даже двумя участниками, поскольку один из них может быть транслятором или микшером RTP)

// перевод автора

В нашем случае первая дорожка имеет SSRC от IVR со стороны АТС, а вторая - от устройства абонента B.

Дополнительный параметр - CNAME

В ходе разбора вопроса удалось обнаружить, что помимо SSRC (о котором в принципе есть информация) RTCP содержит ещё один идентификатор для RTP - каноническое имя или CNAME (стр. 20 RFC 3550).

Так как идентификатор SSRC может измениться, получателям требуется CNAME для отслеживания каждого участника.
Каждый составной пакет RTCP должен (MUST) включать CNAME, так как он остается постоянным (стр. 46 RFC 3550).

Проверим, как абонент B с двумя дорожками и проблемой слышимости указывал данный параметр:

RTCP-пакет с первым SSRC
RTCP-пакет с первым SSRC
RTCP-пакет со вторым SSRC
RTCP-пакет со вторым SSRC

Как видим, CNAME не указан - нет текста с ним, а длина элемента 0 бит.
То есть, абонент B нарушает обязательные требования RFC 3550 и не указывает CNAME. В результате получаем сбой работы телефонии.

Проверка от обратного

Попробуем перепроверить свой вывод - действительно ли проблема не в разных SSRC / разрыве дорожек, а в отсутствии CNAME?

Вот пример звонка, в котором также разные SSRC, но CNAME указан - в нем со слышимостью полный порядок:

Разные SSRC
Разные SSRC
Разрыв на 2 дорожки
Разрыв на 2 дорожки
RTCP-пакет с первым SSRC
RTCP-пакет с первым SSRC
RTCP-пакет со вторым SSRC
RTCP-пакет со вторым SSRC

Более того, это пример звонка от того же самого абонента, но спустя некоторое время.
В чем отличие? - версия сервера АТС на его стороне обновилась (нестандартная АТС по типу известных Asterisk и т.д.). Вероятнее всего предыдущий релиз был с багом, т.к. до этого данный абонент длительное время успешно общался.

То есть, подтверждаем вывод, что проблема на АТС абонента B, не указавшей CNAME.

Выводы

Точной информации о том, как именно повел себя сервер абонента B при 2х SSRC без CNAME не имеется, но можно предположить, что поток от абонента A на его АТС или за ней некорректно маршрутизировался либо это было отражением иного системного сбоя.

Однако сам по себе факт нарушения обязательного пункта RFC в такой ситуации дает основания указать на необходимость глубокой проверки именно на стороне АТС абонента B.

Информация о таком параметре RTCP как CNAME встречается не то, чтобы часто, а тем более о возможных сбоях с ним.

Комментарии (10)


  1. datacompboy
    31.05.2024 10:38
    +3

    Как видим, CNAME не указан - нет текста с ним, а длина элемента 0 бит.

    Строго говоря, CNAME указан -- пустая строка. Так как в звонке два абонента, у второго непустая строка, то все требования соблюдены -- у каждого есть CNAME и они уникальны для каждого абонента.


    1. xReaper
      31.05.2024 10:38

      Не согласен с вами, если есть поле а значения нет то не указан, с такой логикой можно сказать что поле Connexion information IP4 "Пусто" должно работать.


      1. datacompboy
        31.05.2024 10:38

        Должно работать в каком смысле?

        "RTCP carries a persistent transport-level identifier for an RTP
        source called the canonical name or CNAME, Section 6.5.1. Since
        the SSRC identifier may change if a conflict is discovered or a
        program is restarted, receivers require the CNAME to keep track of
        each participant. Receivers may also require the CNAME to
        associate multiple data streams from a given participant in a set
        of related RTP sessions....

        То есть CNAME необходим для уникального идентифицирования абонента в случае смены SSRC или наличия множества стримов.

        Да, CNAME обязан быть передан -- и он передан, в пункте 6.5.1 я не вижу ничего, что делало бы пустую строку невалидной.


        1. xReaper
          31.05.2024 10:38

          Вы же сами написали про уникальный идентификатор, или для вас пустое поле это уникально ?


          1. datacompboy
            31.05.2024 10:38

            Если пустое поле только у одного абонента в разговоре -- да, "" -- уникально. Так же как уникально "вася" или "пыопрырц8процр".


            1. xReaper
              31.05.2024 10:38

              Конечно "Если" А Если нет ? Или мы будем спорить что уникальнее пустое поле или рандом ай ди ?



    1. mrgervant Автор
      31.05.2024 10:38
      +1

      Интересное замечание - не думал в таком ключе! К сожалению, информации о поведении АТС на стороне того абонента нет. Можно предполагать, что сам сервер по внутренней логике всё же ожидал получить текст CNAME, раз быстро вышло исправление его версии.


      1. datacompboy
        31.05.2024 10:38
        +3

        Я уверен, что это был баг на той стороне.

        Однако это не отменяет того факта, что поведение вашей стороны тоже не совсем корректно: тут либо реакция должна быть такой же как на отсутствие тега CNAME вообще, скорее всего -- отказ в установлении соединения -- либо принять, и использовать его как есть -- то есть пустое значение это всё же значение.

        Вы провели отличное глубокое расследование и нашли очень редкий случай, который обычно поймать можно только с помощью удачи (и/или фаззинга), теперь стоит сделать вывод и принять решение как реагировать на него с вашей стороны. :)

        Чего точно не стоит делать -- так это хоронить проблему и забить.


  1. 402d
    31.05.2024 10:38
    +1

    Ну и зачем, я читал этот RFC ? Я ведь не связан с RTP протоколами.

    Но даже беглого просмотра хватило, чтобы понять UUID в качестве CNAME тоже не айс.