From c2c802ac24c19c12c5fcd5e96466ba553e319c18 Mon Sep 17 00:00:00 2001 From: Donat Zenichev Date: Mon, 22 Jul 2024 21:45:53 +0200 Subject: [PATCH] MT#60476 sdp_out_add_origin: add replacements support Add support of replacements flags: - replace-origin - replace-origin-username - replace-origin-full Additionally: fix websocket tests, because now the `-` symbol isn't considered as the one to be set always when using `replce-origin-full`. Instead it will use values of the very first parsed SDP. Change-Id: I7636f020cb92cb760fcd25b0b84509e6d5ba2a9f --- daemon/sdp.c | 70 ++++++++++++++++---------------- t/auto-daemon-tests-websocket.py | 28 ++++++------- 2 files changed, 48 insertions(+), 50 deletions(-) diff --git a/daemon/sdp.c b/daemon/sdp.c index cf7be7adc..95aeb4e41 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -3463,52 +3463,50 @@ static void sdp_out_add_origin(GString *out, struct call_monologue *monologue, struct packet_stream *first_ps, sdp_ng_flags *flags) { struct call_monologue *ml = monologue; + str a, a_type; /* for the offer/answer model or subscribe don't use the given monologues SDP, * but try the one of the subscription, because the given monologue itself * has likely no session attributes set yet */ struct media_subscription *ms = call_get_top_media_subscription(monologue); - if (ms && ms->monologue) { + if (ms && ms->monologue) ml = ms->monologue; - /* replace origin address only - * rest of the values are taken from the monologue (so parsed origin) */ - if (flags->replace_origin) { - g_string_append_printf(out, - "o="STR_FORMAT" "STR_FORMAT" %llu IN %s %s\r\n", - STR_FMT(&ml->session_sdp_orig->username), - STR_FMT(&ml->session_sdp_orig->session_id), - ml->session_sdp_orig->version_num, - first_ps->selected_sfd->local_intf->advertised_address.addr.family->rfc_name, - sockaddr_print_buf(&first_ps->selected_sfd->local_intf->advertised_address.addr)); - return; - } - /* values taken from the monologue (so parsed origin) */ - else if (!flags->replace_origin_full && ml->session_sdp_orig->parsed) { - g_string_append_printf(out, - "o="STR_FORMAT" "STR_FORMAT" %llu IN "STR_FORMAT" "STR_FORMAT"\r\n", - STR_FMT(&ml->session_sdp_orig->username), - STR_FMT(&ml->session_sdp_orig->session_id), - ml->session_sdp_orig->version_num, - STR_FMT(&ml->session_sdp_orig->address.address_type), - STR_FMT(&ml->session_sdp_orig->address.address)); - return; - } + /* orig username */ + str * orig_username = (ml->session_last_sdp_orig && + (flags->replace_username || flags->replace_origin_full)) ? + &ml->session_last_sdp_orig->username : &ml->session_sdp_orig->username; + + /* orig session id */ + str * orig_session_id = (ml->session_last_sdp_orig && flags->replace_origin_full) ? + &ml->session_last_sdp_orig->session_id : &ml->session_sdp_orig->session_id; + + /* orig session ver */ + /* TODO: add support of `sdp_version_check()` */ + unsigned long long orig_session_version = (ml->session_last_sdp_orig && flags->replace_origin_full) ? + ml->session_last_sdp_orig->version_num : ml->session_sdp_orig->version_num; + + /* orig IP family and address */ + str * orig_address_type; + str * orig_address; + if (!ms || flags->replace_origin || flags->replace_origin_full) { + /* replacing flags or PUBLISH */ + str_init(&a_type, (char *)first_ps->selected_sfd->local_intf->advertised_address.addr.family->rfc_name); + str_init(&a, sockaddr_print_buf(&first_ps->selected_sfd->local_intf->advertised_address.addr)); + orig_address_type = &a_type; + orig_address = &a; + } else { + orig_address_type = &ml->session_sdp_orig->address.address_type; + orig_address = &ml->session_sdp_orig->address.address; } - /* TODO: rework full replacement. - * By replacing everything, rtpengine should keep on always using same values - * towards particular endpoint. So, not just a straight-forward replacing with own values. - */ - - /* replace everything, default values for cases like: - * - publish - * - replace_origin_full flag */ - unsigned long long id = (unsigned long long) rtpe_now.tv_sec << 32 | rtpe_now.tv_usec; g_string_append_printf(out, - "o=- %llu %llu IN %s %s\r\n", id, id, - first_ps->selected_sfd->local_intf->advertised_address.addr.family->rfc_name, - sockaddr_print_buf(&first_ps->selected_sfd->local_intf->advertised_address.addr)); + "o="STR_FORMAT" "STR_FORMAT" %llu IN "STR_FORMAT" "STR_FORMAT"\r\n", + STR_FMT(orig_username), + STR_FMT(orig_session_id), + orig_session_version, + STR_FMT(orig_address_type), + STR_FMT(orig_address)); } static void sdp_out_add_session_name(GString *out, struct call_monologue *monologue, diff --git a/t/auto-daemon-tests-websocket.py b/t/auto-daemon-tests-websocket.py index afbb8f1c3..24b29ae3f 100644 --- a/t/auto-daemon-tests-websocket.py +++ b/t/auto-daemon-tests-websocket.py @@ -537,7 +537,7 @@ class TestVideoroom(unittest.TestCase): sdp, re.compile( "^v=0\r\n" - "o=- \d+ \d+ IN IP4 203.0.113.1\r\n" + "o=x \d+ \d+ IN IP4 203.0.113.1\r\n" "s=rtpengine.*?\r\n" "t=0 0\r\n" "m=audio \d+ RTP/AVP 8\r\n" @@ -613,7 +613,7 @@ class TestVideoroom(unittest.TestCase): sdp, re.compile( "^v=0\r\n" - "o=- \d+ \d+ IN IP4 203.0.113.1\r\n" + "o=x \d+ \d+ IN IP4 203.0.113.1\r\n" "s=foobar\r\n" "t=0 0\r\n" "m=audio \d+ UDP/TLS/RTP/SAVPF 8\r\n" @@ -822,7 +822,7 @@ class TestVideoroom(unittest.TestCase): sdp, re.compile( "^v=0\r\n" - "o=- \d+ \d+ IN IP4 203.0.113.1\r\n" + "o=x \d+ \d+ IN IP4 203.0.113.1\r\n" "s=rtpengine.*?\r\n" "t=0 0\r\n" "m=audio \d+ RTP/AVP 8\r\n" @@ -901,7 +901,7 @@ class TestVideoroom(unittest.TestCase): sdp, re.compile( "^v=0\r\n" - "o=- \d+ \d+ IN IP4 203.0.113.1\r\n" + "o=x \d+ \d+ IN IP4 203.0.113.1\r\n" "s=foobar\r\n" "t=0 0\r\n" "m=audio \d+ UDP/TLS/RTP/SAVPF 8\r\n" @@ -1088,7 +1088,7 @@ class TestVideoroom(unittest.TestCase): sdp, re.compile( "^v=0\r\n" - "o=- \d+ \d+ IN IP4 203.0.113.1\r\n" + "o=x \d+ \d+ IN IP4 203.0.113.1\r\n" "s=rtpengine.*?\r\n" "t=0 0\r\n" "m=audio \d+ RTP/SAVP 8\r\n" @@ -1187,7 +1187,7 @@ class TestVideoroom(unittest.TestCase): sdp, re.compile( "^v=0\r\n" - "o=- \d+ \d+ IN IP4 203.0.113.1\r\n" + "o=x \d+ \d+ IN IP4 203.0.113.1\r\n" "s=rtpengine.*?\r\n" "t=0 0\r\n" "m=audio \d+ RTP/SAVP 8\r\n" @@ -1283,7 +1283,7 @@ class TestVideoroom(unittest.TestCase): sdp, re.compile( "^v=0\r\n" - "o=- \d+ \d+ IN IP4 203.0.113.1\r\n" + "o=x \d+ \d+ IN IP4 203.0.113.1\r\n" "s=rtpengine.*?\r\n" "t=0 0\r\n" "m=audio \d+ UDP/TLS/RTP/SAVPF 8\r\n" @@ -1378,7 +1378,7 @@ class TestVideoroom(unittest.TestCase): self.assertIsInstance(sdp, str) match_re = re.compile( "^v=0\r\n" - "o=- \d+ \d+ IN IP4 203.0.113.1\r\n" + "o=x \d+ \d+ IN IP4 203.0.113.1\r\n" "s=rtpengine.*?\r\n" "t=0 0\r\n" "m=audio (\d+) RTP/AVP 8\r\n" @@ -1905,7 +1905,7 @@ class TestVideoroom(unittest.TestCase): sdp, re.compile( "^v=0\r\n" - "o=- \d+ \d+ IN IP4 203.0.113.1\r\n" + "o=x \d+ \d+ IN IP4 203.0.113.1\r\n" "s=rtpengine.*?\r\n" "t=0 0\r\n" "m=audio \d+ RTP/AVP 8\r\n" @@ -2019,7 +2019,7 @@ class TestVideoroom(unittest.TestCase): sdp, re.compile( "^v=0\r\n" - "o=- \d+ \d+ IN IP4 203.0.113.1\r\n" + "o=x \d+ \d+ IN IP4 203.0.113.1\r\n" "s=foobar\r\n" "t=0 0\r\n" "m=audio \d+ UDP/TLS/RTP/SAVPF 8\r\n" @@ -2629,7 +2629,7 @@ class TestVideoroom(unittest.TestCase): self.assertIsInstance(sdp, str) match_re = re.compile( "^v=0\r\n" - "o=- \d+ \d+ IN IP4 203.0.113.1\r\n" + "o=x \d+ \d+ IN IP4 203.0.113.1\r\n" "s=rtpengine.*?\r\n" "t=0 0\r\n" "m=audio (\d+) RTP/AVP 96\r\n" @@ -2753,7 +2753,7 @@ class TestVideoroom(unittest.TestCase): match_re = re.compile( "^v=0\r\n" - "o=- \d+ \d+ IN IP4 203.0.113.1\r\n" + "o=x \d+ \d+ IN IP4 203.0.113.1\r\n" "s=rtpengine.*?\r\n" "t=0 0\r\n" "m=audio (\d+) RTP/AVP 96\r\n" @@ -3002,7 +3002,7 @@ class TestVideoroom(unittest.TestCase): match_re = re.compile( "^v=0\r\n" - "o=- \d+ \d+ IN IP4 203.0.113.1\r\n" + "o=x \d+ \d+ IN IP4 203.0.113.1\r\n" "s=rtpengine.*?\r\n" "t=0 0\r\n" "m=audio (\d+) RTP/AVP 96\r\n" @@ -3151,7 +3151,7 @@ class TestVideoroom(unittest.TestCase): match_re = re.compile( "^v=0\r\n" - "o=- \d+ \d+ IN IP4 203.0.113.1\r\n" + "o=x \d+ \d+ IN IP4 203.0.113.1\r\n" "s=foobar\r\n" "t=0 0\r\n" "m=audio (\d+) RTP/AVP 96\r\n"