OpenSIPS故障转移时From/To Header出现语法错误求助
OpenSIPS故障转移场景下From/To Header异常问题分析
问题现象
呼叫第一台主机host1时一切正常,但触发故障转移重试host2时,From和To字段出现语法错误,日志输出:
From: <sip:1111111111@42.96.x.x><sip:2222222222@42.96.x.x>;;tag=XDDpmaS4Fr8vK To: <sip:3333333333@125.212.y.y><sip:3333333333@103.63.z.z>
相关脚本代码
REQUEST_ROUTE 片段
route [FROM_GATEWAY] { if ($fU=~"^999" && !$avp(new_caller)) { for ($var(v) in $(json(foo)[*])) $avp(new_caller) = $var(v); } if (!$avp(new_caller)) { $avp(new_caller) = $fU; } if (!do_routing($avp(new_caller),,,$avp(dst_rule_attrs),$avp(dst_gw_attrs), ,$avp(partition))) {...} $var(new_caller_domain) = ...; $var(uri) := "sip:" + $avp(new_caller) + "@" + $var(new_caller_domain); uac_replace_from("", "$var(uri)"); $var(new_callee) = ...; $var(uri) := "sip:" + $var(new_callee) + "@" + $(ru{uri.domain}); uac_replace_to("", "$var(uri)"); route(RELAY); }
FAILURE_ROUTE 片段
failure_route [MANAGE_FAILURE] { if (t_check_status("403")) { $avp(new_caller) = NULL; if ($avp(new_caller)) { $var(isFailOver) = 1; route(FROM_GATEWAY); } } ... }
问题原因
uac_replace_from/uac_replace_to的追加逻辑
这两个函数的特性是:当第一个参数(显示名)传空字符串时,不会完全覆盖原有Header,而是在原有值后追加新的URI。第一次呼叫host1时,Header正常生成;故障转移重试时,再次调用这两个函数,新URI被直接追加到已修改过的From/To Header后,导致出现重复的<sip:...>结构。重试时未重置Header状态
触发故障转移进入FAILURE_ROUTE后,当前请求的From/To Header已经是第一次处理后的结果,再次进入FROM_GATEWAY路由调用替换函数时,没有先清除原有Header内容,直接基于已修改的Header进行追加操作,最终形成语法错误的格式。FAILURE_ROUTE逻辑矛盾
代码中先执行$avp(new_caller) = NULL;,紧接着判断if ($avp(new_caller))——此时$avp(new_caller)为NULL,条件永远不成立。如果实际触发了重试,说明要么这段逻辑与运行的代码不符,要么有其他分支触发了重试流程,但核心的Header异常仍来自重复调用替换函数未重置的问题。
修复建议
- 使用
set_furi/set_turi替代uac_replace_from/uac_replace_to,这两个函数会直接覆盖整个URI部分,而非追加:// 替换uac_replace_from set_furi("$var(uri)"); // 替换uac_replace_to set_turi("$var(uri)"); - 若坚持使用
uac_replace_from/uac_replace_to,需在调用前清除原有Header内容,或确保每次调用都基于原始请求Header修改。 - 修正FAILURE_ROUTE中的逻辑错误:
$avp(new_caller) = NULL;后的判断永远为假,需调整逻辑(比如重新赋值有效new_caller或设置重试标记)后再触发重试。
内容的提问来源于stack exchange,提问作者vanminh
相关产品推荐
相关产品推荐

