Bond sockets in OpenSIPS 4.0

In real-life scenarios, the SIP routing is done across multiple IP interfaces (like public or private, different VPN’s, IPv4 versus IPv6 or different protocols). Usually this is handled in OpenSIPS by picking / setting an outbound OpenSIPS socket for the handled call. But there are cases where such simple approach simply does not work:

  • reaching a destination (let’s say a carrier) may be possible via multiple SIP sockets, like different ones for different protocols (UDP, TCP, TLS) or AF families (IPv4 / IPv6) – so picking up the matching SIP sockets is a painful selection based on the properties of the handled call (what protocol is required, for example) – this pollutes the script in a very ugly way
  • when sending the request out, you only have a FQDN host name in RURI, so you do not know the protocol and AF family resulting from the DNS query. So you cannot manually select a SIP socket from script.

Such issues may appear in:

  • SBC, for interconnect scenarios – here the routing is DNS driven in conjunction with multiple SIP sockets on both internal and external side of the SBC.
  • infrastructure routing, where you route calls between different internal components of your platform (SIP proxy, media servers, SBC’s) all being able to support multiple protocols.

To solve this kind of problems, OpenSIPS 4.0 comes with the concept of “bond sockets”, to provide auto selection for the outbound SIP socket, based on the properties of the destination.

Bond socket – the idea

Instead of picking/setting a specific outbound SIP socket for the call (prior knowing the protocol of AF to be used), you can set a group of sockets to be used.

For example, for an SBC, you may have a group of sockets to be used for the “external” communication and another one for the “internal” communication. Each group may contain multiple SIP sockets, for various protocols and AF families. When you want to send a call to the outer side of the SBC (as the call is for an “external” destination), you just have to set (for routing out) the group of “external” sockets – and OpenSIPS, based on the final protocol and AF of the destination, will be the matching socket.

Bond socket – how to use

The usage is quite simple. First, defining such a socket, as a list of real SIP sockets defined in OpenSIPS config.

# 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"}

Once defined, a bond socket may be used from script as any other SIP socket. Let’s say you want to route to an external destination. This destination is given by a FQDN , so subject the NAPTR / SRV and A DNS lookups – these lookup’s may provide the final information on what is the protocol and AF to be used for routing the call.

$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 – more stuff

In addition to the straight-forward usage, the bond sockets come with couple of more extensions.

There is support for inbound sockets too – if you want to check if the inbound socket (used to receive the request) is part of a certain bond, OpenSIPS core provides the socket_belongs_to_bond() function. This helps to identify the routing scenarios:

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;
}

Also the definition of the bond sockets do support sockets with interface naming. Such sockets (with network interface name) may expand to multiple real SIP sockets (if multiple IPs are configured on that network interface).

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

Translates into a bond socket with 4 actual SIP sockets:

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

Conclusions

The bond sockets intend not only to simplify, but also to make possible the proper selection of the outbound socket based on the last-minute discovered (DNS based) properties of the destination.

IF you want to learn more, join us to during OpenSIPS Summit 2026 in Bucharest!

Leave a comment