OpenSIPS 4.0 中的绑定套接字(bond socket)

在实际场景中,SIP 路由是通过多个 IP 接口(例如公网或私网、不同的 VPN、IPv4 与 IPv6 或不同的协议)实现的。通常,OpenSIPS 会通过为待处理的呼叫选择/设置一个出站 OpenSIPS 套接字来处理这种情况。但有些情况下,这种简单的方法根本行不通

  • 到达目的地(例如运营商)可能通过多个 SIP 套接字实现,例如不同的协议(UDP、TCP、TLS)或 AF 系列(IPv4/IPv6)可以使用不同的套接字。因此,根据已处理呼叫的属性(例如所需的协议)选择匹配的 SIP 套接字是一项繁琐的工作,这会以非常糟糕的方式污染脚本。
  • 发送请求时,RURI 中只有 FQDN 主机名,因此您无法得知 DNS 查询结果对应的协议和 AF 族。所以您无法通过脚本手动选择 SIP 套接字。

此类问题可能出现在:

  • SBC,用于互连场景,这里的路由是由 DNS 驱动的,并且与 SBC 内部和外部的多个 SIP 套接字结合使用。
  • 基础设施路由,用于在平台的不同内部组件(SIP 代理、媒体服务器、SBC)之间路由呼叫,所有这些组件都能够支持多种协议。

为了解决这类问题,OpenSIPS 4.0 引入了“绑定套接字(bond socket)”的概念,可以根据目标的属性自动选择出站 SIP 套接字。

Bond socket 的核心理念

与其为呼叫选择/设置特定的出站 SIP 套接字(在知道要使用的 AF 协议之前),不如设置一组要使用的套接字。

例如,对于单板计算机 (SBC),你可以设置一组套接字用于“外部”通信,另一组用于“内部”通信。每组套接字可以包含多个 SIP 套接字,分别对应不同的协议和应用框架系列。当需要将呼叫发往SBC外部(即呼叫目标为“外部”)时,只需设置“外部”套接字组进行路由,OpenSIPS 将根据目标的最终协议和 AF 自动匹配对应套接字。

Bond socket 使用方法

使用方法非常简单。首先,定义这样一个套接字,即在 OpenSIPS 配置中定义的实际 SIP 套接字列表

# the internal interfaces
socket=udp:10.10.0.3:5060
socket=tcp:10.10.0.5:5060
# the external interfaces
socket=udp:1.2.3.4:5060
socket=tcp:1.2.3.9:5060
socket=tls:[2001:db8:1234:5678::1]:5061
# define the "external" bond socket, over all external sockets
socket=bond:extern {"udp:10.10.0.3:5060", "tcp:10.10.0.5:5060", "tls:[2001:db8:1234:5678::1]:5061"}
# and and "internal" bond socket
socket=bond:intern {"udp:10.10.0.3:5060", "tcp:10.10.0.5:5060"}

一旦定义完成,绑定套接字就可以像其他 SIP 套接字一样从脚本中使用。假设你想要路由到外部目标。该目标由 FQDN 指定,因此需要进行 NAPTR/SRV 和 A DNS 查询——这些查询可以提供最终信息,确定用于路由呼叫的协议和地址字段 (AF)。

$ru = "sip:carrier1.com" ;
$socket_out = "bond:external";
t_relay();
# t_relay, after doing all the DNS lookups, will pick the approiate socket
# from the "external" bond, to match the protocol and AF of the destination

Bond socket 其它的扩展功能

OpenSIPS 也支持入站套接字,如果你想检查入站套接字(用于接收请求)是否属于某个 Bond ,OpenSIPS 核心提供了`socket_belongs_to_bond ()` 函数。这有助于识别路由场景:

if (socket_belongs_to_bond( $si, "internal") {
  # came from internal, must go to external
  $socket_out = "bond:external";
} else
if (socket_belongs_to_bond( $si, "external") {
  # came from external, must go to internal
  $socket_out = "bond:internal";
} else {
   send_reply(403,"Forbidden");
   exit;
}

此外,Bond socket 的定义也支持带有接口名称的套接字。此类套接字(带有网络接口名称)可以扩展为多个实际的 SIP 套接字(如果在该网络接口上配置了多个 IP 地址)。

socket=udp:lo:5060
socket=tcp:lo:5060
socket=bond:extern {"udp:lo:5060", "tcp:lo:5060"}

转换为具有4 个实际 SIP 套接字的 Bond socket:

Listening on 
             udp: 127.0.0.1 [127.0.0.1]:5060
             udp: 0:0:0:0:0:0:0:1 [[0:0:0:0:0:0:0:1]]:5060
             tcp: 127.0.0.1 [127.0.0.1]:5060
             tcp: 0:0:0:0:0:0:0:1 [[0:0:0:0:0:0:0:1]]:5060

结论

Bond socket 不仅旨在简化操作,更要实现根据目标地址在最后时刻发现的(基于DNS的)属性来正确选择出站套接字。

原文:https://blog.opensips.org/2026/03/11/bond-sockets-in-opensips-4-0/

本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/65374.html

(0)

相关推荐