Hi Ihor,

Attached is a patch for doublechecking the AF of the forced socket - if not matching, it will be discarded and a new socket will be selected based on proto and AF family. It is not ideal, but let's see.

For doing DNS at the script level, see the IP transformation (it is what you worked on previously):
https://www.opensips.org/Documentation/Script-Tran-3-6#ip.resolve

I agree, it might be useful to have it extended to (a) control the AF and (b) to return maybe a list with all the IPs.

On a much broader view, talking with Razvan on this topic, we were brainstorming on a more generic and flexible approach for this kind of problem (trying to force from script some kind of outbound socket, but without knowing (yet) all the details on the destination (like proto, port, IP). The idea here is to come up with a kind of phony socket definition (phony as it will not be used for listening on) to act as a routing table, to allow the selection of a real socket based on a later determined port, proto, etc.

Like (in a json format):

socket = my_socket { AF=4:udp:1.2.3.4:5060, AF=6: udp:[2001:db8::1:0]:5060}

or something more complex, with proto filtering too:

socket = my_socket { AF=4,proto=udp:udp:1.2.3.4:5060, AF=6,proto=tcp: tcp:[2001:db8::1:0]:5060}


The idea is to still have at the code level a `struct socket_info`, but to be interpreted in a more generic way.

Regards,

Bogdan-Andrei Iancu

OpenSIPS Founder and Developer
  https://www.opensips-solutions.com
  https://www.siphub.com

On 08.01.2026 18:33, Ihor Olkhovskyi wrote:

Bogdan,

Thanks for this, I'm for sure will be happy to test a patch.

For the DNS/socket/AF, as I've said, I'm using now explicit resolution of address with AF (resolve4 and resolve6) and acting accordingly.

Still, sort of solution I see here - https://www.kamailio.org/docs/modules/devel/modules/ipops.html#ipops.f.dns_query , it also allows to deal with multiple A and AAAA records.

Le 08/01/2026 à 16:55, Bogdan-Andrei Iancu a écrit :
Hi Ihor,

First, without the `dns_try_ipv6` options, the DNS lookup will never return an IPv6 address (as gethostbyname() will be used, which is AF_INET only).

Now, going back to the original report: having the `dns_try_ipv6` option on, you get back an IPv6 address (from the DNS resolver). Now, checking the code, if I'm not missing something obvious, I would say the code allows sending to an IPv6 destination via an IPv4 socket :-/ ...which seems broken, IMHO. The code verifies only the compatibility (between destination and sending socket) when comes to the protocol, but not AF. For this case, will you be willing to test a small patch? this will discard the forced socket if not compatible with the destination (this is also done for the proto mismatch) - and a new matching socket will be looked up.

Now, about the multi IPs from DNS - if the DNS based fallback is not turned off (as flag to t_relay), opensips will try to do dns based failover (if the sending fails). But this will not change whatever outbound socket was set...

Basically, to wrap this up, your dilemma is like this: you want to force a socket, but the DNS may give IPv4 or IPV6, so you have no idea which socket to force...

Regards,
Bogdan-Andrei Iancu

OpenSIPS Founder and Developer
   https://www.opensips-solutions.com
   https://www.siphub.com
On 02.01.2026 13:27, Ihor Olkhovskyi wrote:
Bohdan,

I've looked through code (resolve.c) and got an impression, that only first resolved address is used along the way. Means if destination address resolves to IPv6 with dns_try_ipv6=yes, it uses only IPv6 in packet processing (namely for $du) and you cannot force IPv4 outbound socket later, cause no info about IPv4 is present. I've made a small hack to have a possibility to choose, which address family I want to use (https://github.com/igorolhovskiy/opensips-v6/commit/527d8d3d010d3a5a1e4b68475df45cb4e9f44604) but I don't like the solution. Maybe I'm wrong, but my impression, that when DNS resolution is happens, only 1 address (which includes the family as well) is being used later with no possibility to change it. I can provide more logs soon (for relaying part), but not sure it's the case here.

Regards,
Ihor

Le lun. 29 déc. 2025 à 10:33, Bogdan-Andrei Iancu <[email protected]> a écrit :

    Hi Ihor,

    So, you say OpenSIPS picks the IPv6 address as destination
    (confirmed by the err log), but you are not sure what interface
    is to be used (even if you forced the ipv4 one, it may be
    discarded by the internal fwd logic).

    Could you provide debug level logs for the relaying part ?

    Regards,

    Bogdan-Andrei Iancu

    OpenSIPS Founder and Developer
       https://www.opensips-solutions.com
       https://www.siphub.com

    On 10.12.2025 17:58, Ihor Olkhovskyi wrote:
    Hello!

    I'm trying to build ipv4/ipv6 bridge with OpenSIPS 3.6.2.
    I've declared the sockets like this:

    # v4 addresses
    socket=tls:OPENSIPS_IPV4_ADDR:TLS_PORT
    socket=wss:OPENSIPS_IPV4_ADDR:WSS_PORT
    # v6 addresses
    socket=tls:[OPENSIPS_IPV6_ADDR]:TLS_PORT
    socket=wss:[OPENSIPS_IPV6_ADDR]:WSS_PORT
    dns_try_ipv6=yes
    # Always listen on localhost v4
    socket=tls:127.0.0.1:TLS_PORT

    Means explicit to start on v4 and v6 addresses for lately to
    change address family explicitly

    OpenSIPS starts without any issues, but when I try to do socket
    forcing with

    $socket_out = "wss:OPENSIPS_IPV4_ADDR:WSS_PORT";
    t_relay();

    I'm getting

    ERROR:proto_wss:ws_sync_connect: bind failed (22) Invalid argument
    ERROR:proto_wss:ws_connect: connect failed
    ERROR:proto_wss:proto_wss_send: connect failed
    tm:msg_send: send() to EXTERNAL_IPV6(sic!) for proto wss/6 failed
    tm:t_forward_nonack: sending request failed

    So OpenSIPS is trying to send over IPv6. I guess that is cause
    network address of RURI is v6 already, but DNS answers in
    dual-stack. If I remove `dns_try_ipv6` it works, but how than I
    should work with v6?

    What am I missing?

    Thanks in advance!

-- Best regards,
    Ihor (Igor)

    _______________________________________________
    Users mailing list
    [email protected]
    http://lists.opensips.org/cgi-bin/mailman/listinfo/users



--
Best regards,
Ihor (Igor)

--
Regards,
Ihor
diff --git a/forward.c b/forward.c
index c123cdf8c..2704cb6c6 100644
--- a/forward.c
+++ b/forward.c
@@ -154,11 +154,16 @@ const struct socket_info* get_send_socket(struct sip_msg *msg,
 			msg->force_send_socket=find_si(&(msg->force_send_socket->address),
 											msg->force_send_socket->port_no,
 											proto);
-		}
+		} else
+		if (msg->force_send_socket->address.af!=to->s.sa_family){
+			LM_DBG("force_send_socket of different AF (sock=%d, dst=%d)!\n",
+				msg->force_send_socket->address.af, to->s.sa_family);
+			msg->force_send_socket=NULL;
+		} else
 		if (msg->force_send_socket)
 			return msg->force_send_socket;
 		else
-			LM_WARN("protocol/port mismatch\n");
+			LM_WARN("protocol/port/af mismatch\n");
 	};
 
 	if (mhomed && proto==PROTO_UDP)
_______________________________________________
Users mailing list
[email protected]
http://lists.opensips.org/cgi-bin/mailman/listinfo/users

Reply via email to