linphone-developers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Linphone-developers] lib oRTP problem with a RTP session without associ


From: Frédéric BOITEUX
Subject: [Linphone-developers] lib oRTP problem with a RTP session without associated RTCP
Date: Thu, 31 Oct 2024 15:21:18 +0000

        Hello Linphone developers !

  Using the lib oRTP since a long time (in 1.0.2 version with some local 
modifications), I recently found a problem with this lib, which seems to be 
also present in your upstream version. Using a RTP session without associated 
RTCP, we found that if we change the peer IP address during the session live, 
after some time [and some packets sent to the prior peer IP], using 
rtp_session_set_remote_addr_full() function, the library doesn’t change the 
peer IP, without error message, continuing to send RTP packets to the first 
peer IP !

Indeed, in the _rtp_session_set_remote_addr_full() function (called by 
rtp_session_set_remote_addr_full() and some other related functions), a lot of 
RTP session processing is enclosed in a test of RTCP activation :

Line 925 of rtpsession_inet.c :
        if ((rtcp_addr != NULL) && (rtcp_port > 0)) {
                res0 = bctbx_name_to_addrinfo((session->rtcp.gs.socket == -1) ? 
AF_UNSPEC : session->rtcp.gs.sockfamily,
                                              SOCK_DGRAM, rtcp_addr, rtcp_port);
        …
                < *RTP* and RTCP processing >
        …
        
                ortp_message("RtpSession [%p] sending to rtp %s rtcp %s %s", 
session, rtp_printable_addr, rtcp_printable_addr,
                             is_aux ? "as auxiliary destination" : "");
        } else {
                ortp_message("RtpSession [%p] sending to rtp %s %s", session, 
rtp_printable_addr,
                             is_aux ? "as auxiliary destination" : "");
        }

So when we don’t use RTCP, nothing is done apart from printing a message !

We use UDP connected mode, and for this case, RTP without RTCP, the connection 
isn’t done ☹.

Moreover, when actually using RTCP, when changing from a *connected* peer to 
another one, we should first disconnect from the former, and then connect to 
the new one, but this is not the case in the current code.

I’ve modified it with a patch like :

diff --git a/src/rtpsession_inet.c b/src/rtpsession_inet.c
index fdd15cad..34bce8df 100644
--- a/src/rtpsession_inet.c
+++ b/src/rtpsession_inet.c
@@ -961,31 +961,46 @@ static int _rtp_session_set_remote_addr_full(
                        ortp_warning("Could not set destination for RCTP socket 
to %s:%i.", rtcp_addr, rtcp_port);
                        goto end;
                }
+       }
 
-               if (can_connect(session)) {
-                       if (try_connect(session->rtp.gs.socket, (struct 
sockaddr *)&session->rtp.gs.rem_addr,
-                                       session->rtp.gs.rem_addrlen))
-                               session->flags |= RTP_SOCKET_CONNECTED;
-                       if (session->rtcp.gs.socket != (ortp_socket_t)-1) {
-                               if (try_connect(session->rtcp.gs.socket, 
(struct sockaddr *)&session->rtcp.gs.rem_addr,
-                                               session->rtcp.gs.rem_addrlen))
-                                       session->flags |= RTCP_SOCKET_CONNECTED;
-                       }
-               } else if (session->flags & RTP_SOCKET_CONNECTED) {
-                       /*must dissolve association done by connect().
-                       See connect(2) manpage*/
-                       struct sockaddr sa;
-                       sa.sa_family = AF_UNSPEC;
-                       if (connect(session->rtp.gs.socket, &sa, sizeof(sa)) < 
0) {
-                               ortp_error("Cannot dissolve connect() 
association for rtp socket: %s", getSocketError());
-                       }
+       if (session->flags & RTP_SOCKET_CONNECTED) {
+               /*must dissolve association done by connect().
+                 See connect(2) manpage*/
+               struct sockaddr sa;
+               sa.sa_family = AF_UNSPEC;
+               if (connect(session->rtp.gs.socket, &sa, sizeof(sa)) < 0) {
+                       ortp_error("Cannot dissolve connect() association for 
rtp socket: %s", getSocketError());
+               } else {
+                       ortp_message("Current RTP session disconnected from old 
peer");
+                       session->flags &= ~RTP_SOCKET_CONNECTED;
+               }
+               if ((rtcp_addr != NULL) && (rtcp_port > 0)) {
                        if (connect(session->rtcp.gs.socket, &sa, sizeof(sa)) < 
0) {
                                ortp_error("Cannot dissolve connect() 
association for rtcp socket: %s", getSocketError());
+                       } else {
+                               ortp_message("Current RTCP session disconnected 
from old peer");
+                               session->flags &= ~RTCP_SOCKET_CONNECTED;
                        }
-                       session->flags &= ~RTP_SOCKET_CONNECTED;
-                       session->flags &= ~RTCP_SOCKET_CONNECTED;
                }
+       }
 
+       if (can_connect(session)) {
+               if (try_connect(session->rtp.gs.socket, (struct sockaddr 
*)&session->rtp.gs.rem_addr,
+                               session->rtp.gs.rem_addrlen)) {
+                       session->flags |= RTP_SOCKET_CONNECTED;
+                       ortp_message("RTP session connected to %s", 
rtp_printable_addr);
+               }
+               if ((rtcp_addr != NULL) && (rtcp_port > 0) &&
+                   (session->rtcp.gs.socket != (ortp_socket_t)-1)) {
+                       if (try_connect(session->rtcp.gs.socket, (struct 
sockaddr *)&session->rtcp.gs.rem_addr,
+                                       session->rtcp.gs.rem_addrlen)) {
+                               session->flags |= RTCP_SOCKET_CONNECTED;
+                                ortp_message("RTCP session connected to %s", 
rtcp_printable_addr);
+                       }
+               }
+       }
+
+       if ((rtcp_addr != NULL) && (rtcp_port > 0)) {
                ortp_message("RtpSession [%p] sending to rtp %s rtcp %s %s", 
session, rtp_printable_addr, rtcp_printable_addr,
                             is_aux ? "as auxiliary destination" : "");
        } else {


I would like to have your point of view for this problem ; perhaps it’s an odd 
scenario for you, explaining why you didn’t encounter it yet ?

I would be pleased if you could integrate this fix (with your coding standards) 
in the upstream lib oRTP source.

        With regards,
                Frédéric Boiteux,  Odigo.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]