SIP 483 Too Many Hops: причины ошибки, петли маршрутизации и Max-Forwards
При совершении вызова соединение мгновенно сбрасывается, а в SIP-сигнализации или логах софтсвича фиксируются следующие признаки:
- Клиентская сторона получает ответ
SIP/2.0 483 Too Many Hopsна отправленныйINVITE. - В телекоммуникационном дампе (sngrep, Wireshark) наблюдается бесконечное дублирование пакетов между двумя IP-адресами серверов или шлюзов.
- Значение заголовка
Max-Forwardsуменьшается на единицу при каждом прохождении узла и достигает0. - Высокая утилизация CPU на узлах SIP-прокси / SBC из-за шторма сигнальных пакетов при циклической маршрутизации.
1. Анализ сигнального трафика через sngrep / tcpdump
Для обнаружения узлов, между которыми возникла маршрутная петля, выполните захват сигнального трафика:
sngrep -d any sip
# либо прямой дамп через tcpdump:
tcpdump -nnvv -s 0 -i any port 5060 -w /tmp/sip_483_loop.pcapОткройте поток вызова и обратите внимание на стек заголовков Via. Присутствие одинаковых IP-адресов или доменов указывает на циклическую пересылку.
2. Проверка диалплана в Asterisk / FreePBX
Ошибки маршрутизации часто вызваны некорректным правилом переадресации, когда транк отправляет вызов обратно на прокси без изменения URI:
; Пример некорректного цикла в extensions.conf:
[from-internal]
exten => _X.,1,Dial(PJSIP/${EXTEN}@to_sbc)
; SBC возвращает вызов обратно в Asterisk, создавая бесконечный цикл:Убедитесь, что контекст входящего транка корректно направляет звонок во внутренний диалплан, а не возвращает его в исходящий маршрут:
[from-trunk-sbc]
exten => _X.,1,NoOp(Processing Inbound Call from SBC)
same => n,Dial(PJSIP/${EXTEN},30)
same => n,Hangup()3. Контроль начального значения Max-Forwards в PJSIP
В конфигурации pjsip.conf убедитесь, что значение max_forwards не занижено по умолчанию (стандарт — 70):
[global]
type=global
max_forwards=704. Настройка защиты от петель в Kamailio / OpenSIPS
При использовании Kamailio обязательно проверяйте совпадение исходящего IP с собственным адресом интерфейса перед маршрутизацией:
route[RELAY] {
if (src_ip == myself && dst_ip == myself) {
sl_send_reply("483", "Loop Detected");
exit;
}
if (!mf_process_maxfwd_header(10)) {
sl_send_reply("483", "Too Many Hops");
exit;
}
t_relay();
} Частые вопросы (FAQ)
Зачем нужен заголовок Max-Forwards в протоколе SIP?
Заголовок Max-Forwards работает аналогично полю TTL (Time To Live) в IP-пакетах. Он предотвращает вечное циркулирование запросов между ошибочно сконфигурированными прокси-серверами. Каждый промежуточный узел (Stateful/Stateless Proxy) уменьшает его значение на единицу.
Какое начальное значение Max-Forwards определено в стандарте RFC 3261?
Согласно разделу 8.1.1.8 RFC 3261, клиентский терминал (UAC) должен устанавливать значение заголовка Max-Forwards равным 70, если иное не определено специфическими требованиями архитектуры сети.
Может ли ошибка 483 возникать при корректной маршрутизации без петель?
Да, если в цепочке прохождения сложного Enterprise-вызова (несколько SBC, локальные прокси филиалов, шлюзы интеграции с CRM) исходное значение Max-Forwards было установлено слишком низким (например, 10 или 5).
Как в Asterisk полностью отключить вызов при получении 483?
В диалплане Asterisk можно обработать статус завершения вызова: same => n,GotoIf($["${HANGUPCAUSE}" = "483"]?handle_loop). Не пытайтесь выполнять failover на тот же маршрут, это лишь увеличит нагрузку на сеть.